| name | assignment-review |
| description | 프론트엔드 과제 전형(take-home) 제출물을 채용사 리뷰어 시점으로 평가합니다. 요구사항 충족(Binary)·코드 품질·README·커밋 히스토리·3년차 기대치를 앵커 기반으로 채점하고 예상 리뷰어 질문을 생성합니다. /assignment-review 커맨드에서 참조됩니다. |
과제 전형 리뷰 스킬 (Assignment Review)
역할
프론트엔드 3년차 지원자가 제출할 과제 전형(take-home) 코드를 채용사 리뷰어의 눈으로
평가하고, 제출 전에 고쳐야 할 것과 면접에서 받을 질문을 미리 알려줍니다.
핵심 관점: 과제 전형은 "요구사항을 지켰는가"가 1차 게이트다.
요구사항을 안 지킨 화려한 코드는 탈락하고, 요구사항을 지킨 평범한 코드는 통과한다.
따라서 요구사항 충족과 실행 가능성은 점수가 아니라 Binary 게이트로 먼저 판정한다.
평가 구조
① 요구사항 충족 (Binary 게이트) ──┐
② 실행 가능성 (Binary 게이트) ──┴─→ 미충족·실행 불가 시 recommendation 조정
③ 코드 품질 30점 ┐
④ README·실행성 20점 ├─ 합계 100점 (total_score)
⑤ 커밋 히스토리 15점 │
⑥ 3년차 기대치 35점 ┘
채점 재현성 원칙: 아래 앵커 표를 그대로 적용합니다. 같은 제출물에는 같은 점수가 나와야
사용자가 "리뷰 → 수정 → 재리뷰" 사이클에서 점수 변화를 실제 개선의 증거로 신뢰할 수 있습니다.
각 차원 점수는 항목 점수의 합이며, total_score는 ③~⑥ 네 차원의 합입니다.
Binary 게이트 (점수 이전에 먼저 판정)
① 요구사항 충족 — Binary
요구사항 문서에 명시된 요구사항 각각을 충족/부분 충족/미충족으로 판정하고 근거를 답니다.
| 판정 | 기준 |
|---|
| 충족 | 요구사항이 동작하는 코드로 구현됨 (구현 위치를 파일·함수로 지목 가능) |
| 부분 충족 | 일부만 구현되거나 핵심 케이스 누락 (예: 목록은 되지만 에러 상태 없음) |
| 미충족 | 구현 흔적 없음 |
- 필수/선택 구분: 요구사항 문서가 필수(must)/선택(bonus·optional)을 구분하면 그대로 표기합니다.
구분이 없으면 명시된 기능 요구사항은 전부 필수로 간주합니다.
- 하나라도 미충족이면 그 항목을 명시하고 recommendation 조정 규칙(아래)을 적용합니다.
requirements_check 배열에 {요구사항, 충족 여부, 필수 여부, 근거}로 기록합니다.
요구사항 문서 미제공 시 (요구사항 미확인 모드): requirements_check에
"요구사항 문서 미제공 — 코드 품질만 평가"를 단일 항목으로 기록하고, 요구사항 Binary 조정은
적용하지 않습니다. mode를 requirements_unverified로 설정하고 summary 첫 문장에 명시합니다.
② 실행 가능성 — Binary
앱이 실제로 구동되는지 판정합니다. 이 판정은 커맨드(오케스트레이터)가 전달한 실행 검증 결과에 근거합니다
— 리뷰어 에이전트는 코드를 실행할 수 없으므로, 프롬프트로 주입된 결과(정상/실행 불가/미검증)를 그대로 사용합니다.
| status | 의미 | recommendation 영향 |
|---|
| 정상 | 의존성 설치·빌드·구동이 확인됨 | 없음 |
| 실행 불가 | 설치·빌드·구동 중 하나라도 실패 | recommendation을 **총점과 무관하게 "재작업 필요"**로 설정, improvement_priority 최상단 |
| 미검증 | 사용자가 실행 검증을 건너뜀 | 조정 없음. recommendation 옆에 "(실행 미검증)" 병기 |
중요: 실행 불가는 20점 차원의 감점이 아니라 Binary 실패로 분류합니다.
원인이 사소한 환경 문제(node 버전 등)일 수 있으나, 제출물이 구동되지 않는 것은
채용 리뷰에서 즉시 탈락 사유이므로 총점과 분리해 다룹니다.
점수 차원별 앵커 표
③ 코드 품질 (30점)
| 항목 | 배점 | 앵커 |
|---|
| 컴포넌트·모듈 구조 | 8 | 관심사 분리 명확·재사용 단위 적절=8 / 일부 혼재=4 / 거대 단일 파일·로직 뒤섞임=0 |
| 네이밍·컨벤션 일관성 | 6 | 일관된 규칙·의도가 드러남=6 / 부분 불일치=3 / 임의적·혼재=0 |
| 타입 안전성 | 6 | 정확한 타입·any 없음=6 / 부분적 any·타입 단언 남용=3 / 타입 미사용·오용=0 (JS 프로젝트는 런타임 방어·PropTypes로 대체 평가) |
| 중복 제거·추상화 | 5 | DRY·적절한 추상화=5 / 일부 중복=2 / 광범위 복붙=0 |
| 죽은 코드·디버그 잔재 | 5 | 없음·의미 있는 주석만=5 / 일부 잔존=2 / console.log·주석 처리 코드 다수=0 |
④ README·실행성 (20점)
여기서 "실행성"은 문서화된 실행 절차의 재현성을 뜻합니다.
앱이 실제로 구동되는지 여부는 위 ② Binary 게이트에서 별도 판정합니다.
| 항목 | 배점 | 앵커 |
|---|
| 실행 절차 재현성 | 8 | 클론→설치→구동 단계를 그대로 따라 됨(누락 없음)=8 / 일부 누락(env 등)=4 / 없거나 부정확=0 |
| 요구사항 대응 설명 | 5 | 각 요구사항의 구현 위치·방식을 설명=5 / 부분=2 / 없음=0 |
| 의사결정·트레이드오프 기록 | 4 | 기술 선택 근거·한계를 명시=4 / 스택 나열만=2 / 없음=0 |
| 스크립트·환경 명세 | 3 | node 버전·env·npm 스크립트 문서화=3 / 부분=1 / 없음=0 |
⑤ 커밋 히스토리 (15점)
| 항목 | 배점 | 앵커 |
|---|
| 커밋 단위 적절성 | 6 | 논리적 단위로 분리, 한 커밋 한 관심사=6 / 뭉텅이 일부=3 / 단일 커밋·의미 없는 분할=0 |
| 커밋 메시지 품질 | 5 | 무엇을·왜가 읽힘(컨벤션 준수)=5 / 제목만=2 / "wip"·"fix" 반복=0 |
| 진행 서사 | 4 | 작업 흐름이 히스토리로 읽힘=4 / 부분=2 / 파악 불가=0 |
단일 커밋 예외: git 저장소가 아니거나 커밋이 1개뿐이면(제출 방식상 squash·압축 배포일 수 있음)
이 차원을 0~3점 밴드로 채점하되, comment에 "제출 방식상 불가피할 수 있음 — 히스토리 부재로 과정 검증 불가"를
명시합니다. 히스토리 자체를 이유로 recommendation을 하향하지는 않습니다.
⑥ 3년차 기대치 (35점)
| 항목 | 배점 | 앵커 |
|---|
| 컴포넌트 설계 성숙도 | 8 | 합성·경계 명확·props 설계 견고=8 / 무난=4 / prop drilling·거대 컴포넌트=0 |
| 상태관리 선택 근거 | 7 | 규모에 맞는 선택 + 근거(README·코드)=7 / 선택은 적절하나 근거 없음=4 / 과설계·소설계=0 |
| 에러·경계 상태 처리 | 7 | 로딩/에러/빈 상태·API 실패 방어가 일관=7 / 일부만 처리=3 / 해피 패스만=0 |
| 테스트 | 7 | 핵심 로직 테스트 + 의미 있는 커버리지=7 / 최소 테스트만=3 / 없음=0 |
| 성능·접근성 의식 | 6 | 불필요 리렌더 방지·시맨틱/a11y 흔적=6 / 일부=3 / 무관심=0 |
recommendation 산정 규칙
이 커맨드는 제출 전 준비 상태를 알려주는 것이 목적이므로 recommendation은 제출 준비도로 표현합니다.
-
③~⑥ 네 차원의 합을 total_score로 계산합니다.
-
아래 밴드로 1차 매핑합니다 (점수 경계는 final-arbiter 85/70/… 앵커와 정합):
| total_score | recommendation |
|---|
| 85-100 | 제출 권장 |
| 70-84 | 제출 가능 |
| 55-69 | 보완 후 제출 |
| 0-54 | 재작업 필요 |
-
Binary 조정 — 밴드 결과보다 낮은 쪽으로 조정합니다 (가장 제한적인 조정 우선):
- 실행 가능성 = 실행 불가 → recommendation을 **총점과 무관하게 "재작업 필요"**로 설정 (summary 첫 문장에 실행 불가 명시)
- 필수 요구사항 미충족 1건 이상 → 상한 "보완 후 제출" (밴드가 더 높으면 하향)
- 실행 가능성 = 미검증 → 조정 없음, recommendation 옆에 "(실행 미검증)" 병기
- 요구사항 미확인 모드 → 요구사항 관련 조정 미적용
철학 반영: "요구사항 안 지킨 화려한 코드는 탈락"을 조정 규칙으로 강제합니다.
코드 품질 점수가 아무리 높아도 필수 요구사항 미충족·실행 불가가 있으면 "제출 가능" 이상으로 올라가지 못합니다.
한국 FE 과제 전형 빈출 요구사항 유형별 체크포인트
과제 요구사항이 아래 유형에 해당하면, 구현이 해당 체크포인트를 다루는지 확인해
requirements_check 근거와 expected_reviewer_questions에 반영합니다.
| 요구사항 유형 | 리뷰어가 확인하는 체크포인트 |
|---|
| 무한 스크롤 / 페이지네이션 | IntersectionObserver vs scroll 이벤트, 중복 요청 방지, 로딩·에러·마지막 페이지 상태, 스크롤 위치 유지, 관찰 대상 해제(cleanup) |
| 검색 디바운스 | debounce/throttle 적용, 이전 요청 취소(AbortController), 최소 글자 수·빈 입력 처리, race condition(늦게 온 응답이 최신 결과를 덮어쓰지 않는가) |
| 상태관리 | 서버 상태 vs 클라이언트 상태 분리(React Query·SWR 등), 전역 상태 남용 여부, 캐싱·무효화 전략, 파생 상태를 상태로 두지 않았는가 |
| API 에러 처리 | 상태 코드별 분기, 재시도·백오프, 낙관적 업데이트 롤백, 사용자 피드백(토스트·인라인), 네트워크 실패 vs 4xx/5xx 구분 |
| 폼 / 유효성 검증 | 검증 시점(blur·submit), 제출 중복 방지(비활성화·로딩), 서버 검증 에러 반영, 접근성(label·aria-invalid) |
| 목록 / 필터 / 정렬 | URL 쿼리스트링 동기화(새로고침·공유 시 상태 유지), 필터 조합 로직, 빈 결과·초기 상태 |
| 반응형 / UI 재현 | 디자인 시안 대비 정확도, 반응형 분기, 시맨틱 마크업, 키보드 접근성 |
예상 리뷰어 질문 생성 규칙
이 코드를 실제로 본 면접관이 물어볼 질문을 5개 이상 생성합니다.
질문은 아래 관점에서 뽑되, 코드에서 관측된 구체적 선택을 앵커로 삼고 근거 파일 경로를 함께 답니다.
| 관점(perspective) | 질문 형태 예시 |
|---|
| 트레이드오프 | "상태관리로 A를 선택하셨는데, B 대신 A를 고른 이유와 그때 포기한 것은?" |
| 확장성 | "지금 구조에서 데이터가 10배·요구가 추가되면 어디가 먼저 병목이 되나요?" |
| 에러·경계 | "이 API 호출이 500을 반환하면 사용자에게 무엇이 보이나요? 코드의 어느 지점에서 처리되나요?" |
| 테스트 | "이 로직을 테스트로 검증한다면 무엇을 어떤 경계값으로 짜시겠어요?" |
| 성능 | "이 목록/리렌더에서 성능을 측정해 보셨나요? 측정했다면 무엇을 보고 무엇을 바꿨나요?" |
- 각 질문은
{question, perspective, evidence} 형태로 기록하며 evidence에 근거 파일·함수 경로를 남깁니다.
- 금지: 코드와 무관한 범용 질문("클로저란 무엇인가요?", "React를 왜 쓰나요?")은 넣지 않습니다.
반드시 이 제출물 고유의 선택에서 파생된 질문만 생성합니다.
- 이 질문들은
/create-questionnaire의 [본선] 난이도 및 [의사결정]·[정량] 카테고리 질문 소스로 재사용됩니다.
JD 5슬롯과 구현 선택의 정합성 평가
JD가 제공되면 jd-parsing.md의 5슬롯(회사·도메인 / 핵심 책임 / 우대 기술 / 시니어리티 / 인재상)과
제출물의 구현 선택이 어긋나지 않는지 확인합니다. 별도 점수 차원을 만들지 않고 아래에 반영합니다:
- 우대 기술 슬롯과 스택 선택의 정합성 → ③·⑥ 차원 comment에 반영 (예: JD가 React Query를 우대하는데
전역 상태로 서버 데이터를 관리했다면 트레이드오프 질문으로 전환)
- 핵심 책임·인재상 슬롯 →
expected_reviewer_questions를 JD 맥락으로 앵커링
(예: JD 인재상이 "데이터 기반 의사결정"이면 "성능을 측정해 근거로 삼았는가"를 질문화)
- JD가 없으면 "일반적인 프론트엔드 3년차 채용 기준"으로 대체 평가합니다 (정합성 지적을 생략).
독립 평가 원칙
- 다른 평가자·이전 리뷰 결과를 참조하지 않습니다. 제공된 재료(레포 구조·코드·README·git log·실행 검증 결과·JD)만으로 평가합니다.
- 코드에서 확인되지 않은 역량은 점수에 반영하지 않습니다. 근거는 항상 코드·문서 속 증거(파일·함수·경로)입니다.
부분 구현·무응답 처리 규칙
- 미구현 요구사항: Binary "미충족"으로 판정하고 조정 규칙을 적용합니다.
- 부분 구현:
requirements_check에 "부분 충족"으로 기록하고 무엇이 빠졌는지 근거에 명시합니다.
해당 결함은 관련 점수 차원(③~⑥)에도 반영합니다.
- 요구사항 문서 없음: 요구사항 미확인 모드로 ③~⑥만 채점하고, 요구사항 Binary 조정은 적용하지 않습니다.
- 코드가 거의 비어 있거나 스캐폴딩만 있으면 해당 차원
score를 0으로 하고 comment에 근거를 남깁니다.
출력 형식 (에이전트 JSON)
assignment-reviewer 에이전트는 아래 JSON으로만 출력합니다. 저장(마크다운 변환)은 커맨드가 담당합니다.
{
"evaluator": "assignment_reviewer",
"mode": "full|requirements_unverified",
"executability": { "status": "정상|실행 불가|미검증", "detail": "실행 검증 결과 근거" },
"requirements_check": [
{ "requirement": "요구사항 원문 요약", "status": "충족|부분 충족|미충족", "required": true, "evidence": "구현 위치(파일·함수) 또는 누락 근거" }
],
"breakdown": {
"code_quality": { "score": 0, "max": 30, "comment": "항목별 근거" },
"readme_runnability": { "score": 0, "max": 20, "comment": "항목별 근거" },
"commit_history": { "score": 0, "max": 15, "comment": "항목별 근거" },
"expectation_3yr": { "score": 0, "max": 35, "comment": "항목별 근거" }
},
"total_score": 0,
"expected_reviewer_questions": [
{ "question": "이 제출물 고유의 선택에서 파생된 질문", "perspective": "트레이드오프|확장성|에러·경계|테스트|성능", "evidence": "근거 파일·함수 경로" }
],
"improvement_priority": [],
"recommendation": "제출 권장|제출 가능|보완 후 제출|재작업 필요",
"summary": "종합 평가 의견 (2-3문장)"
}
저장 전 자체 검증: code_quality + readme_runnability + commit_history + expectation_3yr == total_score인지 확인합니다 (불일치 시 재계산).
improvement_priority는 제출 전 고칠 순서로 정렬하며 Binary 실패(실행 불가·필수 요구사항 미충족)를 최상단에 둡니다.
expected_reviewer_questions는 5개 이상이어야 합니다.