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

목차 › 8. 테스트

테스트

사람 승인 게이트를 없앤 대신 CI 를 안전망으로 세웠다 — 자동 5잡 · 백엔드 pytest 1,165건 · QA 시나리오 34개 · 최종 갱신 2026. 09. 22.

CI 잡 5push · PR 마다
백엔드 pytest 1,165건 통과 · a650123
앱 위젯 시험 373건 · 파일 30개
AI 면접 서버 110건 / 50초
QA 시나리오 34필수 27 + 실패 7

1. 테스트 계획

이 프로젝트에는 사람 리뷰 게이트가 없다. 2026. 08. 28. 개정으로 사전 확인을 없앴고, 09. 04.부터는 브랜치 → PR → 자체 머지다 — 승인자가 없고 자기 PR 을 자기가 머지한다. 그리고 main 머지 = 2분 후 프로덕션 배포(서버 systemd timer 자동 CD)다. 사람이 빠진 자리에 무엇을 놓을지가 이 장의 전제였고, 답은 CI 초록 하나였다. 규약에 그대로 적혀 있다 — "CI 빨간불인 PR 은 머지하지 않는다. main 이 빨간불이면 다른 작업보다 우선 수정."

계기는 사고다. 2026. 09. 01. 하루에 깨진 main 을 두 번 발견했고 둘 다 우연이었다 (d7fdd10 · d96749e). 그래서 CI 를 넣을 때의 목적을 "게이트"가 아니라 "깨졌다는 사실만 즉시 보이게"로 잡았다 — 우정 B 가 09. 02. 게이트(09. 04.)를 앞두고 먼저 올렸고, 파일 소유는 인프라 도메인이라 사후 공지로 처리했다.

규칙 1 — 검증 없는 push 없음

코드를 바꿨으면 해당 파트의 실행/테스트를 돌리고, 결과를 커밋 메시지에 한 줄 남긴다. 리뷰어가 없으므로 이력이 곧 기록이다.

규칙 2 — 우회 금지

테스트를 통과시키려고 주석 처리하거나 우회하지 않는다. 실패하면 실패한 대로 커밋 메시지와 팀 채널에 적는다. 초록을 만드는 것이 목적이 아니라 상태를 아는 것이 목적이기 때문이다.

규칙 3 — 깨진 main 은 묻지 않고 처리

발견한 사람이 고치거나(fix-forward) revert 한다. 2분 뒤 배포되므로 합의를 기다리는 시간이 곧 장애 시간이다.

층위 — 무엇을 어느 시점에 재는가

층위 대상 도구 시점 실측
백엔드 린트 미정의 이름 · 미사용 import ruff check --select F push · PR 배포 후 500 의 주원인을 1초에 잡는다
백엔드 단위 · API 실제 PostgreSQL + pgvector 에 alembic 이행 후 실행 pytest + pytest-timeout(60초) push · PR 1,165건 통과
프론트 타입 · 린트 · 빌드 oxlint + tsc -b + vite build push · PR 테스트가 없어 빌드가 회귀 그물
앱 위젯 · API 클라이언트 flutter analyze + flutter test push · PR 파일 30개 · 373건
AI 면접 서버 실시간 전사 · 판정 중계 · 화자 매칭 pytest (Python 3.13) push · PR 110건 / 50초
에이전트 회귀 하네스 실서버 /agent/chat 시나리오 — 정답 · 속도 · 창작 여부 자체 하네스 (-m regression) 모델 · 프롬프트 변경 시 55건 (10 + 30 + 15)
계약 대조 배포본 OpenAPI ↔ main 경로 · 스키마 · 인증 check_public_contract.py 배포 후 09. 02. 경로 55/55 · 스키마 75/75
스키마 대조 alembic 이행 결과 ↔ 모델 check_schema_drift.py pytest 직전 (CI) 이행 누락 2건을 잡아낸 뒤 상설화
모델 채점 동일 케이스 23건을 같은 자로 — 도구 이름 · no-tool 위반 · 확인 문구 · 인자 · 응답 judge.py 모델 · 어댑터 비교 시 학습 전 Qwen 26.1% · Claude Haiku 69.6% · Qwen v9 73.9%
E2E · QA 필수 27기능 시나리오 (전제 → 절차 → 기대) qa-scenarios 문서 게이트 판정 09. 04. 1차 게이트 4항목 충족 · 09. 30. 2차 예정

안 한 것도 적는다. 프론트엔드에는 테스트 코드가 없다 — tsc -b 가 사실상의 회귀 그물이고, 그 이상은 남은 기간에 넣지 않기로 했다. AI 면접 서버에도 린트를 아직 붙이지 않았다: 기존 오류 5건(analyze_file · app · deception_vit · interview_ws · test_interview_ws)이 남아 있어 지금 붙이면 아무도 안 보는 빨간 CI 가 되기 때문이다. 다음 ai/ 변경 때 정리한 뒤 붙인다.

2. 단위 및 통합 테스트

CI(.github/workflows/ci.yml)는 잡 5개다. 같은 브랜치에 연달아 push 하면 앞의 실행을 취소한다(concurrency + cancel-in-progress) — 무료 러너 분을 아끼기 위해서다. 아래 표의 칩은 그 잡을 실제로 올린 사람이다 — 파일 자체는 인프라 도메인이라, 남이 올린 경우는 사후 공지로 처리했다.

잡하는 일들어온 계기추가
lint
수택 E
uvx ruff@0.16.7 check --select F app tests 헥사고날 이동 뒤 NameError 2건이 프로덕션까지 갔다 — schedules.py 의 timedelta 미import, assignments.py 의 함수 밖 PgTalentRepository. 둘 다 그 줄을 타는 테스트가 없어 pytest 초록, 배포 뒤 500 09. 12.
backend
우정 B
uv sync --frozen → pgvector 확장 → alembic upgrade head → 모델↔이행 비교 → pytest -q 깨진 main 을 하루 두 번 우연히 발견 09. 02.
frontend
우정 B
npm ci → oxlint → tsc -b + vite build (Node 22) 같음 — 백엔드 잡과 같은 커밋으로 첫 CI 에 함께 들어왔다 09. 02.
ai
수택 E
apt 5개(opencv · mediapipe · soundfile) 후 pytest 3파일 실시간 면접 서버 시험 110개가 CI 밖에 있었다. 09. 01. 이후 51번 바뀌었는데 매번 각자 로컬 컨테이너로만 확인했다 — 깨졌는지가 머지한 사람의 기억에 달려 있었다. 우정 B 가 로컬에서 110 passed / 50초를 실측한 뒤 요청했다 09. 17.
mobile
수택 E
Flutter 3.44.8 — flutter analyze + flutter test 09. 15. 앱 시험 15건이 깨진 채 며칠 지나갔다 — 아무도 몰랐다. Issue #254 — 민아 C 원안 09. 17.

백엔드 — 목 DB 를 안 쓴다

테스트 DB 를 흉내로 대체하지 않았다. CI 는 pgvector/pgvector:pg16 서비스 컨테이너를 띄운다 — 순정 postgres 를 쓰면 vector 확장이 없어 conftest 가 application_embeddings 를 건너뛰고, 그러면 임베딩 경로가 CI 에서 통째로 안 돈다. 로컬 docker-compose 와 같은 이미지를 쓰는 이유가 그것이다. 격리는 트랜잭션으로 한다 — db fixture 가 각 테스트를 트랜잭션으로 감싸고 끝나면 롤백해서 DB 에 흔적이 남지 않는다.

파일 52개에 def test_ 가 1,084개이고, parametrize 확장까지 포함해 1,165건이 통과한다(커밋 a650123 — 같은 실행에서 55건은 skip, 그 로컬에 pgvector 가 없어서다). 09. 02. 실측 기준으로는 486건에 CI 14.5초 · 로컬 88.6초였다 — 로컬이 느린 것은 WSL 이 /mnt/c 를 읽는 속도 탓이지 테스트 탓이 아니다. 백엔드 로드맵의 W5 완료 기준("uv run pytest 30초 내")은 러너에서는 이미 만족한다.

CI 가 잡은 것 — pytest 만으로는 안 보이던 두 종류

이행 누락 — check_schema_drift.py (09. 17.)

alembic upgrade head 스텝만 있으면 초록이 거짓이 된다. pytest 의 conftest 가 create_all 로 이행에 빠진 표를 채워 넣기 때문이다. 실제로 두 번 그랬다 — 09. 16. email_logs.stage 의 password_setup 을 모델에만 넣어 운영에서 메일 행 INSERT 가 거부됐고, 09. 17. 이행 번호 0023 중복(#282)으로 운영 DB 에 file_blobs 가 안 생길 뻔했다. 그래서 이행 직후 · pytest 전에 표 · 컬럼 · NULL 허용 · CHECK 허용값 · UNIQUE · 인덱스 이름 다섯 가지를 비교하고, 다르면 종료 코드 1 이다. 번호 중복 자체는 별도로 tests/test_alembic_revisions.py 가 막는다 — DB 없이 파일만 읽고, 번호를 짓는 사람이 둘 이상이면 언제든 다시 나기 때문이다.

로컬 초록 · CI 빨강 — conftest.py 의 스위치 선점

개발자 .env 에만 있는 키가 판정을 갈랐다. ANTHROPIC_API_KEY 가 있으면 백엔드가 "사용 가능"으로 보이지만 CI 에는 없어 503 으로 갈린다 — 이 갈림으로 실제 사고가 났고 d4580e2 로 사후 복구했다. 그래서 conftest 가 알려진 스위치 12개를 빈 값으로 선점하고 COMPANY_NAME 은 CI 의 실효값 "Arda" 로 못 박는다. 지우는 것으로는 안 된다 — app/main.py 의 load_dotenv() 가 없는 키에는 .env 값을 넣기 때문에, 미리 값을 잡아두는 것이 유일하게 확실한 방법이다.

멈춤 — pytest-timeout 60초

09. 04. 로컬에서 Docker Desktop 이 죽어 DB connect 대기로 pytest 가 24분간 조용히 멈췄다. 침묵을 실패로 바꿨다 — 타임아웃이 걸리면 어떤 테스트가 어디서 기다렸는지 스택과 함께 드러난다.

회귀 하네스 — 기본 스위트 밖에 둔 이유

소연 D 도메인의 에이전트는 "되냐"가 아니라 "얼마나 잘 되냐"를 재야 한다. 그래서 backend/tests/prompt_regression/ 는 실 백엔드 (localhost:8000)에 실호출하고, @pytest.mark.regression 이 붙어 기본 pytest -q 에서 자동으로 제외된다 — 시나리오 하나당 5~40초라 CI 기본 스위트에 끼면 매 PR 이 몇 분씩 밀린다. -m regression 을 명시해야만 돈다.

세트건수재는 것기준
test_step0 10 인사 · 자기소개 · 목록 · 이름 검색 · 역량 검색 · 단계 변경 요청 등 정형 문장 Ollama qwen3:4b · Guard 도입 후 10/10 · 평균 15초가 회귀 기준선
test_intent_variations 30 존칭(씨 · 님) · 오타 · 존댓말 · 조사 변형 — 정형 10개는 regex 가 잡게 만든 것이라 진짜 정확도는 변형에서 드러난다 의도 정확도 wrong ≤ 5% · p50 ≤ 4s
test_faq 15 지원자용 공개 챗 — 공고 정보 · 본인 상태 응답, 차단 주제(연봉 · 합격 가능성 · 다른 지원자) 거절, 프롬프트 주입 방어 거절 문구로 답하고 주입에 넘어가지 않을 것

하네스의 assert 는 최소한만 건다. 대신 구조적 기준 두 가지는 깨지면 채택 불가로 못 박았다 — ① 렌더된 답변에 시드 밖 이름이 없어야 한다(도구 결과 창작 차단) ② change_stage 확인 카드는 기대한 지원자를 가리켜야 한다 (다른 레코드 차단). 성공률 · 응답 시간은 results/*.jsonl 에 append 로 쌓여, 프롬프트를 고친 뒤 다시 돌리면 같은 파일의 diff 로 개선이 보인다. 쓰기 의도는 확인 카드까지만 만들고 실행하지 않으므로 하네스가 DB 를 바꾸지 않는다.

계약과 구조도 스크립트로 잰다

check_public_contract.py 는 배포본 /openapi.json 에서 GET 을 전부 뽑아 토큰 없이 한 번씩 때려 본다. 경로 목록을 코드에 박지 않은 이유는 명시적이다 — 박아두면 새로 생긴 엔드포인트가 대조에서 빠져 무의미해진다. 경로 변수에는 존재하지 않는 값을 넣어 실지원자 데이터에 닿지 않고, 읽기만 한다. 실측은 08. 31. 경로 35/35 · 스키마 62/62, 09. 02. 경로 55/55 · 스키마 75/75 · 필드 불일치 0 이다.

check_architecture.py 는 ADR-0035 헥사고날 적용 상태를 AST 로 센다. 이유를 스크립트가 직접 적고 있다 — "포트 · 어댑터로 바꿨다"는 말은 폴더를 만든 것만으로도 참이 되어 버린다. 2026. 09. 12. 실측값을 기준선으로 박아 --strict 는 원시 DB 접근이 늘면 실패한다. 그때 판정은 "구조는 갖췄지만 실질은 절반"이었고, 그 숫자를 남겨 뒀다.

3. 사용자 인수 테스트

인수 기준은 docs/00_overview/qa-scenarios.md 한 곳이다. 2026. 08. 24. 작성했고, 그 시점에 화면이 아직 없어서 05-design 의 화면 지도를 기준으로 썼다 — 확정되지 않은 UI 디테일은 "(화면 확정 후 갱신)" 으로 표시해 둔다. 각 시나리오는 전제 → 절차 → 기대 결과 세 줄이다: 어떤 상태에서, 누가 무엇을 클릭 · 입력하고, 무엇이 보이면 성공인가.

군건수담는 것
A. 인증 · 권한3 JWT 가입 · 로그인, 역할 2종(관리자 · 멤버), 조작 제어
B. 채용 공고3 생성 · 수정 · 삭제, 상태 3종, 공고별 지원자 수 집계
C. 지원 (로그인 없음)3 공개 링크 지원서 제출, 이력서 업로드, 개인정보 수집 동의
D. 지원자 관리6 테이블 · 칸반 · 드래그 단계 이동 · 상세 · 단계 이력 · 담당자 직접 등록
E. 평가2 점수(1~5) + 코멘트 작성, 목록 조회와 평균 점수
F. 파일2 presigned URL 로 브라우저 → S3 직행 업로드, 다운로드
G. 알림 · 메일3 단계 변경 메일, 비동기 처리(200ms 내 응답), 실패 시 재시도
H. 검색 · 필터2 이름 · 이메일 검색, 단계별 필터
J. 시스템 · 운영3 Docker 구성, AWS 배포, Swagger /docs
실패 케이스7 중복 지원(409) · 허용 안 되는 형식 · 용량 초과 · 권한 없는 접근(403) · 마감 공고 지원 · 로그인 실패 · 필수 항목 미입력

시나리오는 결정이 바뀌면 같이 고친다. A3 "면접관은 배정된 지원자만 조회"는 08. 31. ADR-0017(등급 이분화)로 폐지됐고, 확인할 것이 "무엇이 열렸는가 · 무엇이 남았는가"로 바뀌어 세 갈래로 쪼갰다 — A3-1 조회는 전원 열려 있다(미배정 10명 포함 12명 전원이 보인다), A3-2 멤버는 배정된 건만 평가를 쓴다(그 외 403), A3-3 면접관 배정 · 남의 가용 시간은 관리자만(단 본인 가용 시간은 멤버도 가능). 시나리오가 낡은 채 남아 있으면 인수 기준이 아니라 오해의 근거가 된다.

1차 게이트 (09. 04.) — 09. 02. 수직 슬라이스 실측

게이트 판정은 문장이 아니라 실데이터 한 번 관통으로 했다. 공개 지원 폼 제출 → DB 저장 → 담당자 확인까지다. 게이트 4항목 중 마지막까지 미충족이던 것이 이 수직 슬라이스였고, 판정일(09. 04.)보다 이틀 앞선 09. 02.에 관통해 닫았다 — 코드 변경 없이 브라우저로 실제 경로를 한 번 통과한 것이다. 기존 공고를 쓰지 않고 검증용 공고(id 3)를 새로 만들어 관통한 뒤 closed 로 내렸다: C6 의 UNIQUE(job_posting_id, email) 에 걸릴 수 있고, 공개 링크 발급이 재발급이라 그 공고의 기존 토큰을 즉시 무효화하기 때문이다.

단계결과
공개 링크로 공고 조회 (로그인 없음) 통과 GET /public/postings/by-token/{token}
이력서 PDF 첨부 → 브라우저에서 S3 직행 PUT 통과
제출 통과 지원자 id 24 · source=form · files 1행
담당자 화면 표시 통과 목록 · 상세 모두
접수 확인 메일 sent 기존 15건이 failed 인 것과 달리 성공
단계 이력 (없음) → applied
담당자의 첨부 열람 통과 실측 시점엔 받아보는 쪽 화면이 없었고, 프론트 오너에게 넘겨 같은 날 f4d7a1b 로 닫혔다 — 826 B PDF 원문이 그대로 렌더

검증 방법 자체를 기록으로 남겼다. 첨부를 눌러도 브라우저에서 아무 일이 없어 보일 수 있는데, 그것이 기능 실패인지 환경 탓인지 구분하려면 같은 URL 을 iframe 으로 불러 렌더되는지 본다(iframe 로드는 CORS 검사를 안 받는다). 오류 표시와 콘솔이 비어 있는데 화면만 안 바뀌면 환경 쪽이다. 실제로 버킷 CORS 의 AllowedMethods 가 PUT 뿐이라 브라우저 fetch GET 은 막히고, 이 판별법 없이는 서버가 멀쩡하고 로그에도 안 남는 함정에 다시 빠진다.

2차 게이트 (09. 30.) — 아직 안 돌았다

조건은 필수 27개 기능 전부 프로덕션 동작 · 에이전트와 앱도 데모 가능 · QA 시나리오 전 항목 통합 리허설 2회 · 09. 28.~30. 전 도메인 공통 버퍼(코드 프리즈와 잔여 버그)다. 통합 리허설은 W5(09. 21.~25.)에 프로덕션 URL 과 실기기에서 도는 일정이고, 09. 22. 현재 아직 수행 전이다 예정.

외부 인수 — 멘토링이 실질적인 수용 심사였다

내부 QA 와 별개로 IBM 강사 멘토링이 사실상의 인수 창구였다. 09. 10. 멘토가 21개 항목을 짚었고(서류 · AI 요약 6 · 면접 7 · 지원자 쪽 4 · 화면 · 앱 · 학습 4), 팀이 항목마다 현황과 대조해 "이미 동작 / 결정 필요 / 실측 필요"로 갈랐다. 09. 11. 숙제는 "지원자 · 관리자 입장에서 각각 시연 가능하도록 준비"였다 — 두 역할로 갈라 시연한다는 인수 기준이 여기서 나왔다. 09. 18. 피드백의 "모델 비교를 정량적으로"는 09. 22. 같은 채점기 기반 정량 보고서로 반영됐다 — 같은 날짜의 나머지 세 항목은 트래커에서 아직 doing 이다.

4. 결함 추적 및 조치

추적 창구는 셋이다. 하나는 GitHub 이슈 · PR, 하나는 피드백 트래커, 하나는 사람이 아니라 기계다.

① GitHub 이슈 · PR — PR 이 곧 기록

리뷰 게이트가 없으므로 브랜치 · 커밋 메시지 · PR 본문이 전부 사후 참고 대상이다. 09. 22. 기준 main 의 커밋 1,095개 · 머지된 PR 236건(번호는 #354 까지). 커밋 제목에는 기능 번호(D3 · G1 · J7)나 도메인 접두어를 붙이고, type 은 feat fix docs test chore refactor 다.

② 피드백 트래커 — _data/feedback/<GitHub 아이디>.yml

멘토링 · 강의 피드백은 반영 담당자가 자기 파일에 적는다 — 칸반과 같은 원칙(한 사람 = 파일 하나)이라 git 충돌이 없다. 접수 시점에는 received · from · content · status: todo 만 채우고, 반영이 끝나면 같은 항목에 fixed · fix 를 채워 done 으로 바꾼다 — 접수와 반영이 한 줄에서 추적된다.

③ 외부 헬스체크 — 기계가 이슈를 연다

서버 안의 지표는 "서버가 살아 있다"까지만 안다. DNS · TLS · Caddy · 보안그룹이 죽어 밖에서만 안 되는 경우는 못 잡는다. 그래서 GitHub 러너가 15분마다 공개 주소를 사용자와 같은 경로로 부르고, 실패하면 이슈를 열거나 열린 이슈에 코멘트, 복구되면 "복구됨"을 달고 닫는다. 열린 이슈는 항상 최대 하나다. 공개 저장소라 비용 0.

도메인 밖 결함은 고치지 않고 넘긴다

다른 도메인에서 문제를 발견하면 직접 고치지 않고 이슈로 오너에게 넘긴다. 실례 — 백엔드가 앱 쪽 프레임 전송 문제를 09. 16.에 이슈 #260 으로 넘기면서 PR #154 를 닫고 살아 있는 항목 둘만 추렸다. 같은 건에서 "얼굴 114/114 no_face" 추적은 앱이 안 보내는 것과 서버가 못 찾는 것을 가르려면 양쪽을 같이 봐야 해서 서버 로그 대조를 백엔드가 맡기로 나눴다. 경계를 넘는 수정보다 경계를 넘는 정보 교환이 싸다.

사고 하나에 장치 하나 — 재발 방지 규칙으로 승격된 것

사고

깨진 main 을 하루 두 번, 둘 다 우연히 발견

장치 — CI 도입. 이후 09. 04. 브랜치 → PR → 자체 머지로 main 에 닿는 경로를 하나로 좁혔다. 지금 5개 잡이 push · PR 마다 돈다.

사고

미정의 이름 2건이 프로덕션 500

장치 — CI ruff --select F. 스타일 규칙까지 켜지 않은 것이 핵심이다 — 기존 파일 수백 줄이 빨개지면 아무도 안 보는 빨간 CI 가 된다. 잡는 것은 실제로 터지는 것뿐.

사고

Docker 가 죽어 pytest 가 24분간 침묵

장치 — pytest-timeout 60초. 멈춤을 침묵이 아니라 실패로 바꿨다.

사고

디스크 고갈로 배포가 죽음

장치 — 컨테이너 로그 상한 20MB×3 · 배포 때 이미지 · 캐시 prune · EBS 29 → 50GB(09. 10.). 이 건과 위 두 장치(멈춤 · 미정의 이름)를 묶어 세 부류 모두 재발 0 이다.

사고

n8n 이 웹훅은 받고 죽어 메일이 queued 로 잔류

장치 — API 가 스스로 5분마다 밀린 메일을 SMTP 로 재발송(최대 3회, 초과는 failed 로 접어 사람이 확인). 합격 · 불합격 통보가 통째로 멎던 단일 장애점을 없앴다.

사고

.env 를 고쳤는데 반영이 안 됨

장치 — docker compose restart 는 env_file 을 다시 읽지 않는다. up -d --force-recreate 를 규칙으로 문서화했다.

대조가 잡아낸 결함, 실측이 뒤집은 판정

결함어떻게 드러났나조치
#59 면접관이 공고 수정 가능
#97 draft 공고 무인증 노출
무인증 GET 대조 — 지금까지 나온 권한 결함이 전부 이 대조에서 나왔다 대조를 스크립트로 굳혀(check_public_contract.py) 엔드포인트가 늘 때마다 자동으로 대상이 되게 했다
#282 이행 번호 0023 중복
#283 file_blobs 누락
운영에만 표가 없는데 CI 는 초록 — create_all 이 가렸다 모델↔이행 비교를 CI 상설 스텝으로. 09. 22. DB 권한 분리 이후에는 누락이 곧 기동 실패라 더 중요해졌다
요건 우수 지원자가 우대 부족만으로 탈락 fit-check 지원자 24명 3축 점수 실측 — 인수인계의 "자동 불합격 3명"이 실제로는 8명이었다 PR #182 — 가중치 요건 50→60 · 우대 20→10 · 문화 30 유지 + 요건 ≥70 이면 문화 하한 50
자료가 없는 지원자를 채점하려 함 자소서 1줄 · 전부 미기재인 지원자가 판정 없이 남거나 사유 불명 「불합격」으로 보였다 PR #349 · #351 — 요약 insufficient=true 면 「서류 탈락」 라벨로. false 인 지원자는 안 건드려 대량 탈락 방지
AI 추정값이 신고값처럼 보임 폼에 경력을 안 적으면 AI 가 이력서에서 연차를 추출하는데 표식이 없어 구별 불가 (공정성) career_years_source="ai" 표식 → 프론트 「AI 추정」 배지. 재생성 시 표식이 사라지는 문제는 PR #311 로 후속 — 09. 22. 현재 미머지
인터뷰방 답변 저장 실패 · 서류 대조 · CONFLICT 409 09. 10. 멘토링 21항목 점검 + 시연 리허설 중 실측 (Q9 시도 후 Q1 로 되돌아감) PR #174 · #175 · #178 로 해결, PR #183 으로 Qwen 학습 파이프라인 착수

닫지 못한 것

안 된 것은 안 됐다고 적는다. 09. 15. 세션 75 에서 CPU 전사가 180초 상한을 넘겨 답변이 [전사 지연] 자리표시자로 저장됐다. 전사 속도 자체는 OpenAI API 전환으로 풀렸지만 이미 자리표시자로 남은 답변을 되살리는 경로는 없다 미해결 — 기능 미비가 아니라 지원자 데이터 손실이라 백엔드 큐 23번으로 남은 기간 맨 위에 뒀다. AI 면접 서버 린트 5건도 아직 CI 에 안 붙어 있다 대기. 이 둘은 초록을 만들어 가리지 않고 빨간 채로 문서에 남긴다 — 그것이 "테스트를 통과시키려고 우회하지 않는다"는 규칙의 실제 모습이다.

← 목차로