careermate 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/AGENTS.md +33 -0
  2. package/dist/doctor.mjs +1 -1
  3. package/dist/mcp.mjs +1 -1
  4. package/dist/web.mjs +1 -1
  5. package/docs/FAQ.md +101 -0
  6. package/docs/MCP_TOOLS.md +292 -0
  7. package/docs/START_WORKFLOW.md +137 -0
  8. package/docs/SUPPORTED_AI_APPS.md +112 -0
  9. package/docs/WORKFLOWS.md +202 -0
  10. package/docs/career-os/README.md +76 -0
  11. package/docs/career-os/eop/cover-letter.md +46 -0
  12. package/docs/career-os/eop/fit-analysis.md +48 -0
  13. package/docs/career-os/eop/interview-prep.md +39 -0
  14. package/docs/career-os/eop/job-analysis.md +42 -0
  15. package/docs/career-os/eop/profile-extraction.md +37 -0
  16. package/docs/career-os/knowledge/ats.md +131 -0
  17. package/docs/career-os/knowledge/company-research.md +137 -0
  18. package/docs/career-os/knowledge/cover-letter.md +135 -0
  19. package/docs/career-os/knowledge/fit-matching.md +121 -0
  20. package/docs/career-os/knowledge/human-writing.md +118 -0
  21. package/docs/career-os/knowledge/interview-behavioral.md +132 -0
  22. package/docs/career-os/knowledge/interview-technical.md +126 -0
  23. package/docs/career-os/knowledge/linkedin-profile.md +152 -0
  24. package/docs/career-os/knowledge/networking-referrals.md +166 -0
  25. package/docs/career-os/knowledge/offer-evaluation-decision.md +121 -0
  26. package/docs/career-os/knowledge/onboarding-first-90-days.md +126 -0
  27. package/docs/career-os/knowledge/portfolio.md +121 -0
  28. package/docs/career-os/knowledge/recruiter-screen.md +105 -0
  29. package/docs/career-os/knowledge/rejection-triage-iteration.md +115 -0
  30. package/docs/career-os/knowledge/resume.md +123 -0
  31. package/docs/career-os/knowledge/salary-negotiation.md +123 -0
  32. package/docs/career-os/knowledge/verifiers/ats-compat.md +64 -0
  33. package/docs/career-os/knowledge/verifiers/consistency.md +61 -0
  34. package/docs/career-os/knowledge/verifiers/human-voice.md +82 -0
  35. package/docs/career-os/knowledge/verifiers/recency-staleness.md +72 -0
  36. package/docs/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
  37. package/docs/career-os/knowledge/verifiers/truthfulness.md +67 -0
  38. package/package.json +11 -2
@@ -0,0 +1,37 @@
1
+ # EOP — 기본정보/경력 추출 (Profile Extraction)
2
+
3
+ > 외부 LLM 실행 지침. 이 절차를 따르면 환각 없이 **이력 구조화 전문가**처럼 사용자 문서에서 사실만 정확히 뽑는다.
4
+ > **지식 출처(deep reference, 먼저 읽어라):** [`../knowledge/resume.md`](../knowledge/resume.md) · 검증기 [`../knowledge/verifiers/truthfulness.md`](../knowledge/verifiers/truthfulness.md)·[`consistency.md`](../knowledge/verifiers/consistency.md). 이 EOP는 그 플레이북을 *실행 절차*로 압축한 얇은 층이다 — 추출 시 함께 적용한다.
5
+ > 근거(보강 리서치): [`../validation/research/job-analysis-and-profile.md`](../validation/research/job-analysis-and-profile.md) (B). 검증 대상(L2). 먼저 [README](../README.md) §0·§3 적용.
6
+
7
+ ## 0. 전문가 프레임
8
+ - **추출은 span 식별이지 생성이 아니다.** 핵심 필드를 원문에서 못 찾는 항목은 **환각으로 폐기**. 성과·날짜·고용주·숫자·스킬을 **절대 발명하지 않는다**.
9
+ - **책임 vs 성과 구분:** "~을 담당했습니다"=책임(duty); "X→Y 정량 변화"=성과(achievement). **지표를 발명해 duty를 성과로 격상 금지.**
10
+ - 정량 임팩트는 **명시될 때만** (metric, value, delta)로 구조화; 없으면 비우거나 역량 키워드(추론 금지).
11
+ - **모호하면 추측하지 말고 사용자에게 질문**(옵션 제시).
12
+
13
+ ## 1. 입력 수집
14
+ 사용자 문서(이력서/경력기술서) → `read_document`. 스캔 PDF·이미지로 텍스트 레이어가 없으면 본문을 텍스트로 붙여넣어 달라고 안내. 기존 `get_profile`로 중복 확인.
15
+
16
+ ## 2. 추출 절차
17
+ 1. **원문 인덱싱**(verbatim span 근거 유지).
18
+ 2. **스키마 추출**(JSON Resume: basics/work/education/skills/projects), 각 필드 = 원문 span.
19
+ 3. **volatile 필드만 정규화:** 날짜 → ISO 8601(현재 역할 endDate null), 조직명 접미("(주)"/"Inc.") 노이즈 제거; 직함은 통제 매핑 요청 없으면 원형 유지.
20
+ 4. **근무항목별 각 불릿을 responsibility | achievement 2분류로 태깅.** achievement는 원문에 **명시적 outcome**(완료된 결과·지표·전후 변화·수상/선정/달성)이 있을 때만(예: "처리 시간 2시간→20분 단축", "신규 거래처 전환 완료", "전사 평가 1위 선정"); 수치·결과 없이 수행/담당/참여/진행/개선만 서술된 불릿(예: "고객 응대 프로세스 개선 작업 진행")은 **responsibility**. 정량 임팩트는 명시될 때만 (metric, value, delta). <!-- applied: profile-duty / 2026-06-18 / reconfirm 4/4 (codex·opus·sonnet·haiku) -->
21
+ 5. **모호성 → 질문**(날짜 충돌/중복·직함 과장·공백기·숫자 단위·기준 미상·FT vs 프리랜스·숙련도 미제공): 옵션 제시, 사실로 자동 해소 금지.
22
+ 6. **스킬 택소노미:** dedupe + 그룹(level은 명시될 때만); NCS/플랫폼 통제 어휘에 매핑하되 **원 토큰 유지**.
23
+ 7. **충실도 노트:** 폐기/불확실 항목을 명시 나열.
24
+
25
+ ## 3. 한국 특수
26
+ 경력기술서(실행·성과)와 자소서(동기·배움)를 **분리** 추출. 정량 불가 역할은 *날조 대신* 역량 키워드. "면접에서 설명 가능한 수치만". 날짜/직함 변이(재직중·음/양력 혼재)는 ISO 정규화하되 원형 보존.
27
+
28
+ ## 4. 출력 계약 (사용자 대면)
29
+ - **구조화 결과**(스키마 형태, 사람이 읽기 쉬운 요약 동반)
30
+ - **책임 vs 성과 태깅** · **모호성 질문 목록**(확인 필요)
31
+ - **충실도 노트**(무엇을 폐기/확인했는지) · **신뢰도**
32
+ - **발명 0 보장** 명시 — 사용자 확인 후 저장(`add_resume`/프로필 갱신).
33
+ 숨길 것: 내부 도구명·EOP.
34
+
35
+ ## 5. 자가검증 루브릭 (research §B 루브릭)
36
+ **PASS:** 추출된 모든 사실(고용주·직함·날짜·지표·스킬)이 verbatim span에 추적 가능 · **발명 0** / 책임 vs 성과 정확 태깅 / 날짜 ISO 정규화 + 현재 역할 처리 / 모호성을 사실 해소 대신 질문으로 / 스키마 준수 / 정량 임팩트는 명시될 때만.
37
+ **FAIL:** 고용주·날짜·숫자·스킬 환각 / duty를 가짜 성과로 격상 / 날짜 오정규화·발명 / 모호성을 미검증 사실로 붕괴 / 원문 항목 누락·왜곡 / 구조·스키마 오류.
@@ -0,0 +1,131 @@
1
+ # ATS — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ 이 플레이북은 연결된 AI가 후보자의 이력서를 **기계가 안정적으로 읽고 검색해 낼 수 있게(parseable & findable)** 만들도록 돕는다. 두 가지 진실이 모든 것을 떠받친다. (1) **파싱은 실재하고 결과를 좌우한다** — 다수 ATS 파서는 텍스트를 선형(좌→우, 위→아래)으로 읽으며 표·다단·텍스트박스·헤더/푸터·그래픽을 "word salad"로 뭉개, 연락처·스킬·날짜가 검색 인덱스와 자동완성에서 조용히 사라진다. (2) **"ATS가 점수로 자동 탈락시킨다"는 서사는 상당 부분 신화**지만 **완전한 신화는 아니다** — 사람이 거르는 단계가 핵심이되, 지원서 양식의 **knockout/사전 스크리닝 문항**(취업 자격·학위·근무지·연봉 하한)은 진짜 자동 탈락 스위치이며, 대량 채용에서는 AI 어시스트 랭킹/자동 숏리스트가 사실상의 자동 필터로 작동하기도 한다. CareerMate에는 LLM이 없으므로, 아래 루브릭은 연결된 AI가 `save_fit_analysis`·`save_cover_letter_version` 저장 전에 자가검증할 수 있는 **셀 수 있는/체크 가능한 신호**로 설계했다. 단, "무엇이 JD 핵심 용어인가"·"이 약어가 모호한가"·"이 직함이 진실한가" 같은 **판단은 외부 AI의 몫**이고, CareerMate는 결정론적 **측정**만 한다.
8
+
9
+ **적용 범위(중요):** 이 플레이북은 **영어권 ATS**(Workday/Greenhouse/Lever/Taleo/iCIMS/Workable 등 자유양식 이력서 파싱) 기준이다. 한국 주력 플랫폼(사람인·잡코리아·원티드·그리팅·각사 자체 채용시스템)의 **문항 기반 지원서**는 자유양식 이력서 ATS와 완전히 다른 게임이며(§2 한국 트랙), 일부 루브릭(날짜 형식·표준 헤더·약어)은 로케일 분기 또는 면제가 필요하다.
10
+
11
+ ## 2. 플레이북
12
+
13
+ ### 원칙
14
+
15
+ - **단일 컬럼(single-column)만 출력하라.** 이력서 본문을 표·다단 그리드·텍스트박스·좌우 병렬 블록에 넣지 말고, 스킬 묶음은 쉼표·세로바(|)·불릿(•)으로 한 줄에 표현하라. — 주류 파서는 선형으로 읽으며 표/다단을 "페이지 전체를 가로로 슬라이스"해 텍스트 레이어를 뒤섞어 스킬·연락처·섹션을 통째로 누락시킨다. 디자인 중심 이력서가 work-experience 블록만 파싱된 사례가 보고됐다. _(출처: Jobscan — Tables and Columns Break Resume Parsing)_
16
+ - **연락처(이름·전화·이메일·지역)와 핵심 키워드는 본문(BODY)에 둬라. 페이지 헤더/푸터나 이미지에 넣지 마라.** — **일부(주로 구형) 파서**는 헤더/푸터/텍스트박스 텍스트를 건너뛴다. 2026년 현재 다수 최신 엔진(Sovren/Textkernel/HireAbility/Affinda 계열)은 헤더/푸터를 읽지만, 실패가 여전히 존재하므로 본문에 두는 것이 무비용 안전책이다. _(출처: Jobscan — 5 ATS Formatting Mistakes; UMN Duluth Career Center)_
17
+ - **표준·직역 섹션 헤더를 그대로 써라**: 'Work Experience'(또는 'Experience'), 'Education', 'Skills', 'Certifications', 'Summary'. 'What I've Done', 'My Journey' 같은 창의적 라벨을 피하라. — 파서는 표준 헤딩 문자열을 인식해 내용을 분류한다. 비표준 헤딩은 엉뚱한 필드로 분류되거나 누락돼 구조화 검색에 안 잡힌다. _(출처: Indeed — How To Write an ATS Resume; 다수 대학 커리어센터)_
18
+ - **JD의 정확한 용어를 미러링하되, 시맨틱 등가물도 커버하라.** boolean exact-match가 여전히 흔하므로 JD 표현을 그대로 쓰되, Workday·Eightfold·HiredScore 계열은 **stemming·동의어·임베딩 시맨틱 매칭**을 돌리므로 의미적 등가물('Node.js'↔'NodeJS', 'CI/CD'↔'CICD', 'manage'↔'managed')도 함께 다뤄라. — 후보자가 가졌지만 JD와 다르게 표현한 스킬은 exact 검색에서 누락될 수 있으나, 시맨틱 레이어에서는 등가물이 잡히기도 한다. 두 모델을 모두 가정하라. _(출처: Teal — Resume Keywords; Scale.jobs — Match Keywords; Eightfold/HiredScore 시맨틱 매칭 동향)_
19
+ - **약어 확장(expansion)은 좁게 적용하라.** JD가 두 형태를 모두 쓰거나 **진짜로 모호한 약어**에만 'long form (ACRONYM)'을 한 번씩 넣는다. AWS/SQL/API/REST/SaaS/GCP/CPA 같은 **업계 표준·널리 알려진 약어는 면제** — 'Amazon Web Services (AWS)'나 'Certified Public Accountant (CPA)'를 매번 풀어쓰면 오히려 junior하게 읽히고 리크루터는 'AWS'·'CPA'로 검색한다. _(출처: Teal — Resume Keywords; 시니어 리크루터 리뷰)_
20
+ - **지원서 양식 knockout/사전 스크리닝 문항을 키워드보다 상위·우선 게이트로 다뤄라.** 취업 자격/비자 스폰서십, 필수 학위/자격증, 근무지/이주, 연봉 하한, 최소 경력연수 — 지원 전에 후보 프로필의 사실과 대조해 mismatch를 사용자에게 알려라. — Workday/Greenhouse/Taleo/iCIMS에서 필수 knockout 문항에 부적격 답을 하면 사람 검토 전에 자동 탈락한다. "어떤 키워드 최적화도 자동 부적격을 이기지 못한다." _(출처: The Interview Guys — ATS Resume Hack; Huntr — How ATS Work 2026)_
21
+ - **키워드 스터핑·숨김 텍스트 금지. 사실·수치·고유명사·날짜는 원문 그대로 보존하라.** — 파싱된 이력서는 결국 사람이 스캔한다(실제로 거르는 단계). 스터핑·허위 키워드는 스팸으로 읽혀 그 단계에서 탈락한다. _(출처: The Tech Resume — ATS Myths Busted; Teal)_
22
+ - **헤드라인/타깃 직함과 최근 직함을 JD 직함과 정렬하되, 진실한 범위에서만.** (예: PM 업무를 'Program Lead'로 했다면 'Product Manager'를 진실하게 추가) — 직함은 1차 boolean 필터이자 사람의 첫인상 신호다. 단 '진실성'은 본질적으로 AI/사람 판단이라 결정론 루브릭으로 강제 불가하며, 한국식 직급(사원/대리/과장/팀장)과 영문(Manager/Lead) 충돌도 사람 판단이 필요하다. _(출처: Jobscan — Top Resume Keywords; The Interview Guys)_
23
+ - **지원 URL로 ATS 플랫폼을 식별해 파일형식·전략을 조정하라.** apply URL이 `greenhouse.io`·`lever.co`·`*.myworkdayjobs.com`·`icims.com`을 포함하면 무료·결정론적 신호다. Greenhouse/Lever는 PDF 텍스트 레이어를 잘 파싱하고, 일부 구형 Taleo/iCIMS는 어려워한다. Workday는 후보가 대부분 필드를 **재입력(re-key)** 하므로 파싱 품질보다 **knockout 문항·프로필 필드**가 더 중요하다 — 우선순위는 **플랫폼 조건부**다. _(출처: Huntr — How ATS Work 2026; 시니어 리크루터 리뷰)_
24
+
25
+ ### 한국 트랙 (영어권 ATS와 다른 게임)
26
+
27
+ - 사람인/잡코리아/원티드/그리팅 등은 **문항 기반 자기소개서 지원서**가 핵심이다. 자유양식 이력서 파싱 루브릭(단일 컬럼·표준 헤더·MMM YYYY 날짜)은 부분적으로만 적용되며, 날짜('2023.01 ~ 현재', '재직중')·직급 체계는 로케일 분기가 필요하다.
28
+ - 한국 지원서에서는 **각 문항에 대한 답변 품질**과 **자격 요건 충족**이 ATS 포맷보다 우선한다. 이 경우 §3 루브릭 중 R1/R2/R7(포맷·헤더·텍스트레이어)만 적용하고 R6(날짜)·R5(약어)는 면제하라.
29
+
30
+ ### Do
31
+
32
+ - 이력서를 한 컬럼·위→아래·역연대순(최근 우선)으로 배치한다.
33
+ - 직역 표준 헤더를 쓴다: Summary, Skills, Work Experience, Education, Certifications.
34
+ - 이름·전화·이메일·도시/지역을 맨 위 본문에 **plain text 줄**로 넣는다.
35
+ - `get_application_context`로 JD의 필수·반복 용어를 먼저 추출하되, **무엇이 must-have/nice-to-have인지의 선정은 외부 AI가** 하고(이 판단은 CareerMate가 못 한다), 증거가 있는 곳에만 정확한 문자열을 녹인다.
36
+ - 시맨틱 등가물도 함께 커버한다(예: 'Node.js' 본문에 두면 'NodeJS' 검색도 의식).
37
+ - 지원 URL로 ATS를 식별해 파일형식·우선순위를 조정한다(§원칙 마지막).
38
+ - 날짜를 'MMM YYYY – MMM YYYY'(예: 'Jan 2023 – Present')로 직함과 같은 줄에 일관 표기한다. **한국어 이력서는 '2023.01 ~ 현재' 로케일 형식을 허용한다.**
39
+ - **테뉴어 타임라인 무결성**을 확인한다: 날짜 존재뿐 아니라 순서 일관성, 파서가 재직기간을 계산 가능한지, 겹침/공백이 사람 스크리닝을 유발하지 않는지.
40
+ - 약어는 **모호한 경우에만** 확장형을 한 번 쓴다(업계 표준 약어는 그대로).
41
+ - plain 불릿(• 또는 -)과 표준 폰트(Arial, Calibri, Times New Roman, 10–12pt)를 쓴다.
42
+ - .docx 또는 진짜 텍스트레이어 PDF로 저장·전달하고, 텍스트가 선택/복사되는지 확인한다.
43
+ - knockout 문항(비자/스폰서십·학위/자격·근무지·연봉·경력연수)을 **후보 프로필의 사실과 대조한 3-state(매치/미스매치/불명) 프리플라이트**로 사용자에게 제시한다.
44
+ - **LinkedIn/프로필 패리티**를 맞춘다: 직함 정렬·키워드 미러링을 LinkedIn 헤드라인·스킬에도 적용한다(소싱 상당수가 ATS가 아니라 LinkedIn 검색에서 일어난다).
45
+ - 한 회사 다중 역할은 회사를 한 번 적고 역할을 들여쓰기로 묶는다(umbrella method).
46
+
47
+ ### Don't
48
+
49
+ - 이력서 본문에 표·다단/좌우 병렬·텍스트박스를 쓰지 마라.
50
+ - 연락처·스킬·키워드를 헤더/푸터나 이미지/그래픽 안에 넣지 마라.
51
+ - 표준 헤더 대신 창의적 섹션명('What I've Done', 'My Story')을 쓰지 마라.
52
+ - 선택 가능한 텍스트 레이어가 없는 스캔/이미지 PDF를 제출하지 마라.
53
+ - 키워드 스터핑·부자연스러운 반복·흰색/투명/1pt 숨김 텍스트로 점수를 조작하지 마라.
54
+ - 후보가 뒷받침 못 하는 스킬/키워드를 발명·과장하지 마라(사람이 파싱 텍스트를 읽고 거른다).
55
+ - 그래픽·아이콘·평점 바·스킬 퍼센트 차트로 정보를 전달하지 마라.
56
+ - 높은 'match score'가 면접을 보장한다고, 또는 ATS가 점수로 자동 탈락시킨다고 가정하지 마라 — 진짜 게이트는 knockout 문항·사람 검토·(대량채용의) AI 랭킹이다.
57
+ - 고정된 'PDF=자동거부' 신화를 믿지 마라 — 플랫폼 조건부다.
58
+ - 모든 약어를 기계적으로 풀어쓰지 마라(AWS/SQL/CPA 등 표준 약어는 그대로).
59
+ - 날짜를 문단 안에 묻거나 생략하지 마라 — 파서가 타임라인을 만들 수 없다.
60
+
61
+ ### 워크드 예시 (Before → After)
62
+
63
+ 1. **Before:** SKILLS 섹션을 3열 표로 작성
64
+ `| Languages | Frameworks | Tools |` / `| Python | Django | Docker |` / `| Go | React | AWS |`
65
+ **After:**
66
+ `Skills`
67
+ `Languages: Python, Go`
68
+ `Frameworks: Django, React`
69
+ `Tools: Docker, AWS`
70
+ **왜 더 나은가:** 파서가 표를 가로로 읽어 'Languages Frameworks Tools Python Django Docker...'처럼 뒤섞으면 그룹핑이 깨진다. 단일 컬럼 쉼표 목록은 각 용어를 깨끗한 줄에 둬 'Python'·'React'·'AWS'가 각각 인덱싱되고 검색에 노출된다.
71
+
72
+ 2. **Before:** 페이지 헤더 영역(.docx page-header)에 'Jane Park — jane@email.com — 010-1234-5678', 본문은 'PROFILE'로 시작.
73
+ **After:** 본문 1행 'Jane Park', 2행 'Seoul, South Korea | jane@email.com | 010-1234-5678', 3행 헤딩 'Summary'.
74
+ **왜 더 나은가:** 헤더 영역 연락처는 **일부 파서**가 건너뛰어 리크루터가 연락 수단 없는 이력서를 받고 자동완성이 비는 실패가 실재한다. 본문 plain text로 옮기면 어느 파서에서도 추출이 보장된다. 'PROFILE'도 표준 'Summary'로 정규화했다.
75
+
76
+ 3. **Before:** Experience 불릿 'Led cross-functional initiatives to improve discoverability of our content.' (JD는 'SEO'·'Google Analytics' 요구)
77
+ **After:** 'Led Search Engine Optimization (SEO) initiatives using Google Analytics, lifting organic traffic 38% in 6 months.'
78
+ **왜 더 나은가:** 원문엔 JD 정확 문자열 'SEO'·'Google Analytics'가 없어 boolean 검색에서 자격 있는 후보가 누락된다. 재작성은 정확 용어(모호한 SEO는 확장형 동반)와 구체 수치를 동시에 넣어 파서/검색과 사람 독자를 모두 만족시키되, 실제 한 일이라 날조가 아니다. **이 불릿이 최근 역할에 있을수록 가중치가 높다**(§R4 recency 신호 참조).
79
+
80
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
81
+
82
+ > **책임 경계:** CareerMate는 **결정론적 측정**(개수·존재여부·패턴·비율)만 한다. **무엇이 JD 핵심 용어인가, 약어가 모호한가, 직함이 진실한가, JD가 어떤 hard requirement를 명시하는가**의 **판단은 외부 AI**가 jd_terms·knockouts 등으로 미리 제공해야 한다. 아래 임계값(0.70, ≤4회 등)은 **발명된 magic number가 아니라 권장 출발점**이며, AI가 JD/문서 길이/역할 수에 맞게 조정한다. 일부 체크는 **자문(advisory)** 이지 하드 게이트가 아니다.
83
+
84
+ | ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) |
85
+ |----|-----------|-----------|--------------------------------|
86
+ | R1 | 단일 컬럼 | 표/텍스트박스 구조 0개 | **.docx 원본에서만 신뢰**: `w:tbl`·`w:txbxContent` XML 요소 카운트 == 0. **PDF는 컬럼 검출 불가** — x-좌표 위치 정보 없이는 신뢰 불가하므로 '검출 불가, 사용자 경고'로 정직히 강등. 텍스트 공백-갭 휴리스틱은 약한 보조 신호로만(거짓양성: 우측 정렬 날짜줄). |
87
+ | R2 | 표준 헤더 | {Summary/Profile, Skills, Experience, Education, Certifications} 중 ≥3 존재, 그 자리에 비표준 헤딩 0 | 추출 텍스트를 표준 헤딩 화이트리스트와 대소문자 무시 substring 매칭, 카운트(≥3)하고 화이트리스트 밖 헤딩 줄 플래그. 순수 문자열 매칭. |
88
+ | R3 | 본문 연락처 | 이메일·전화 정규식이 본문에서 각각 ≥1 | 본문 추출 텍스트에 이메일 `[\w.+-]+@[\w-]+\.[\w.-]+` ≥1, 전화 숫자 패턴 ≥1. **.docx는 헤더/푸터 XML에 *only* 존재하는 경우(중복 아님)를 직접 겨냥해 플래그**; PDF는 헤더/본문 구분 불가라 본문 매치만 확인. |
89
+ | R4 | JD 키워드 커버리지 + recency | must-have 용어 커버리지 비율 ≥ 0.70(권장 출발점, AI 조정). **+ 최근 역할 배치 가중** | jd_terms[]는 **외부 AI가 추출·정규화**(lowercase, 구두점 제거, '.js'/'js' fold, 단·복수 dedupe, 동의어 묶음)해 제공. CareerMate는 정규화된 용어를 substring이 아니라 **토큰 경계 매칭**으로 카운트(raw substring은 'Java'⊂'JavaScript', 'lead'⊂'leadership' 거짓양성 유발 → 금지). 추가로 **각 용어가 최근(상단) 역할에 있는지** 위치 플래그를 반환해 AI가 recency 가중. |
90
+ | R5 | 약어 확장 (**advisory**) | 모호한 약어만: 확장형 동반 권장. 업계 표준 약어 화이트리스트(AWS/SQL/API/REST/SaaS/GCP/CPA/PhD/CEO/USA 등) **면제**. 월 약어·고유명사 면제 | 대문자 토큰 정규식 추출 후 **표준 약어 화이트리스트·월 약어를 먼저 제외**, 남은 모호 후보만 'long form (ABC)' 페어링 존재 확인. **하드 게이트 아님 — 자문**. (AI가 모호성 판단) |
91
+ | R6 | 날짜·테뉴어 무결성 | 모든 역할 항목에 파싱 가능한 날짜 범위 + 순서 일관 + 겹침/공백 없음 | 영문 `(Jan|...|\d{4})\s*[–-]\s*(Present|\d{4})` **또는 한국어 `\d{4}\.\d{2}\s*[~–-]\s*(현재|재직중|\d{4})`** 로 로케일 분기. 역할 헤딩 수 대비 비율 1.0. 추가로 날짜를 정렬해 **겹침/공백 구간을 카운트**(>0이면 사람 스크리닝 유발 가능 플래그). |
92
+ | R7 | 파일 텍스트 레이어 | 추출 텍스트 길이 > 300자, 형식 .docx 또는 text-PDF(이미지-PDF 아님) | `read_document`로 추출 후 글자수 측정. PDF인데 near-zero면 이미지-only → fail. 카운트 체크. |
93
+ | R8 | 스터핑·숨김 텍스트 | 핵심 용어 반복이 **문서 길이/역할 수 정규화** 상한 이내, 숨김 텍스트 런 0 | 용어별 occurrence 카운트를 **역할 수·페이지 수로 정규화**(2페이지 시니어 이력서는 핵심 언어 6–8회가 정상 → 고정 4회 상한 금지). 숨김 검출은 `w:color val='FFFFFF'`뿐 아니라 **폰트색==배경색·≤1pt 폰트·텍스트=배경이미지** 케이스까지 스캔(FFFFFF만 보면 회피 쉬움). 커버리지 한계는 정직히 고지. |
94
+ | R9 | knockout 프리플라이트 (3-state) | JD 명시 hard requirement **각각 × 후보 프로필 사실 = 매치/미스매치/불명** 매트릭스 존재. 빈 헤더만으로는 불합격 | JD hard requirement 추출(visa/degree/location/years/salary)은 **외부 AI 판단**(자기기만 방지: 존재≠정확). knockout 답은 **CareerMate 프로필 데이터**의 사실(시민권/비자/학위)에서 와야 함. CareerMate는 각 항목이 (a) JD에 명시됐고 (b) 프로필 사실과 대조됐고 (c) 3-state 중 하나로 라벨됐는지 **구조 존재**를 카운트. **LLM 의존 단계임을 명시**. |
95
+ | R10 | 직함 정렬 (**advisory**) | JD 핵심 직함 구(또는 진실한 동의어)가 헤드라인/최근 역할줄에 등장 | JD 직함 토큰을 상단 헤드라인/첫 역할줄에 substring 매칭. **단 '진실성'은 검증 불가 — AI/사람 판단**. 한국식 직급↔영문 충돌도 AI 판단. 하드 게이트 아님. |
96
+
97
+ **주요 실패 모드:**
98
+ - **substring 거짓양성/거짓음성:** raw substring 매칭은 'Java'⊂'JavaScript', 'lead'⊂'leadership'를 오매칭한다. 토큰 경계 + 외부 AI 정규화·동의어 묶음으로만 막을 수 있다(R4).
99
+ - **PDF 컬럼 검출 환상:** 텍스트 추출이 컬럼을 단일 스트림으로 reflow하면 진짜 문제가 숨는다. PDF는 '검출 불가, 경고'로 정직히 강등한다(R1).
100
+ - **약어 오탐 폭탄:** 모든 대문자 토큰에 확장형을 요구하면 AWS/SQL/CEO/월약어가 전부 fail한다 → 화이트리스트 면제 + advisory(R5).
101
+ - **knockout 자기기만:** 빈 헤더만 써넣어도 '존재'로 통과 + JD 텍스트만으로는 mismatch 판정 불가 → 프로필 사실 대조 3-state 강제(R9).
102
+ - **로케일 미대응:** 영문 'MMM YYYY'·'Present'·'FFFFFF 흰배경' 가정은 한국어 이력서·색배경 디자인을 100% 오판한다 → 로케일 분기(R6)·다중 숨김 케이스(R8).
103
+ - **magic number 과신:** 0.70·≤4회는 출발점이지 법칙이 아니다. AI가 JD/문서 길이로 조정한다.
104
+ - **루브릭 자체의 정밀도 미검증:** 이 결정론 루브릭이 깨끗한 이력서를 오탈락시키지 않는지 보장하려면 **소규모 라벨드 픽스처 세트**(예: 손으로 채점한 known-good 이력서 10건)로 회귀 검증이 필요하다 — Phase B 과제로 명시.
105
+ - **결과 오인:** 루브릭 만점은 **파싱가능성·검색노출의 필요조건 점검**일 뿐 합격/면접 예측이 아니다. 추천·다이렉트소싱·소규모 기업은 ATS와 무관하게 진행되며, 만점이어도 knockout·사람·AI 랭킹에서 떨어질 수 있다.
106
+
107
+ ## 4. 출처 (Provenance)
108
+
109
+ > **증거 한계 고지:** 핵심 파싱 주장은 Jobscan(ATS 최적화 도구를 파는 벤더 — 파싱 취약성 과장 인센티브)과 대학 커리어센터(상호 인용·수년 지연)에 기댄다. 일화 1건('디자인 이력서가 work-experience만 파싱')과 가이드 다수가 근거이며, '헤더/푸터를 실제로 무시하는 ATS 비율'·'단일 vs 멀티컬럼 파싱 실패율' 같은 **정량 효과(effect size)는 미검증**이다. 1차 파서 벤더(Sovren/Textkernel/HireAbility/Affinda) 또는 각 ATS 자체 help docs가 파싱 동작의 권위 있는 출처이나 본 플레이북에는 미반영 — **규칙 영향도는 ATS 벤더·버전별로 다르며 정량 효과는 미검증**임을 전제로 적용하라.
110
+
111
+ - **Jobscan — Why ATS Tables and Columns Break Your Resume Parsing (2026)** — 선형 파싱, 표/다단 word-salad 실패, 세로바/쉼표/불릿 대안, umbrella method · https://www.jobscan.co/blog/resume-tables-columns-ats/ _(벤더, 상업적 편향 가능)_
112
+ - **Jobscan — 5 Critical ATS Resume Formatting Mistakes (2026)** — 헤더/푸터·텍스트박스 누락(일부·구형 한정으로 해석), 본문 연락처, 단일컬럼/폰트/마진 기본값 · https://www.jobscan.co/blog/ats-formatting-mistakes/ _(벤더)_
113
+ - **UVA / Santa Clara / U. Maryland / U. Utah / UMN Duluth Career Center ATS guides** — 표준 헤딩, 역연대순, .docx/PDF 수용, plain 불릿, 10–12pt 폰트(다수 대학 교차 확인) · https://www.scu.edu/careercenter/toolkit/job-scan-common-ats-resume-formatting-mistakes/ _(상호 인용 가능, 지연 가능)_
114
+ - **Indeed Career Advice — How To Write an ATS Resume** — 보편 표준 섹션(Work Experience/Education/Skills/Certifications)과 템플릿 구조 · https://www.indeed.com/career-advice/resumes-cover-letters/ats-resume-template
115
+ - **Teal — Resume Keywords / Scale.jobs — Match Keywords** — exact-match 우선, JD 미러링, 약어+확장(좁게), 자연스러운 배치, 스터핑 회피 · https://www.tealhq.com/post/keywords-for-resume
116
+ - **The Interview Guys — ATS Resume Hack & What ATS Looks For** — knockout/사전 스크리닝이 진짜 자동 부적격기, 직함 정렬 · https://blog.theinterviewguys.com/ats-resume-hack/
117
+ - **Huntr — How Applicant Tracking Systems Actually Work (2026)** — 플랫폼별 knockout 동작(Workday/Greenhouse/Taleo/iCIMS/Workable), URL로 ATS 식별, Workday 재입력 현실 · https://huntr.co/blog/how-applicant-tracking-systems-work
118
+ - **The Tech Resume — ATS Myths Busted** — 'PDF 거부'·'점수 자동탈락' 신화 반박(단, 대량채용 AI 랭킹은 별개), 파싱→boolean/자동완성·사람이 거름(Amazon/Google/Microsoft 리크루터 인용) · https://thetechresume.com/samples/ats-myths-busted.html _(단일 강주장 출처 — 과의존 주의)_
119
+ - **시맨틱/임베딩 매칭 동향 (Eightfold / HiredScore / Workday Skills Cloud, 2026)** — 일부 최신 ATS가 stemming·동의어·임베딩 시맨틱 매칭·AI 랭킹/숏리스트를 실제 운용 → exact-match 단독 가정 보정 _(2차 동향, 정량 미검증)_
120
+ - **Wikipedia — Applicant Tracking System** — ATS의 일반 정의·생태계 프레이밍(운영 디테일은 근거하지 않음) · https://en.wikipedia.org/wiki/Applicant_tracking_system
121
+
122
+ ## 5. Phase B 힌트 (아키텍처로 연결)
123
+
124
+ - **MCP 도구 아이디어:**
125
+ - `get_ats_checklist` — principles·do/don't·countable rubricChecks를 구조화 JSON으로 반환(AI가 작성 중 적용).
126
+ - `analyze_ats_fit({ resume_id, job_id })` — **LLM 없이 계산 가능한 raw 결정론 신호**만 반환: 추출 텍스트, 탐지 헤더, .docx의 `w:tbl`/`w:txbxContent` 카운트, 텍스트레이어 길이, 본문 연락처 매치, 로케일 분기 날짜·겹침/공백, jd_terms 커버리지 맵, 숨김 텍스트 후보. **jd_terms 추출·정규화·동의어 묶음과 knockout hard-requirement 추출은 호출하는 AI가 입력으로 제공**(CareerMate는 카운팅만). 결과를 `save_fit_analysis`에 연결.
127
+ - (Phase B 과제) **fixture 회귀 세트** — known-good 이력서 ~10건을 손 채점해 루브릭이 깨끗한 이력서를 오탈락시키지 않는지 정밀도/재현율 측정.
128
+ - **데이터 형태 힌트:**
129
+ - `ats_checklist: { principles:[{rule,rationale,source}], rubricChecks:[{id,check,passBar,measure,advisory:bool,llm_dependent:bool}] }`
130
+ - `ats_signals: { file_type:'docx'|'pdf_text'|'pdf_image', locale:'en'|'ko', text_len:int, table_count:int, textbox_count:int, columns_detectable:bool, headers_found:string[], contact:{email:bool,phone:bool,in_body:bool,header_only:bool}, dates_ok_ratio:float, tenure_overlaps:int, tenure_gaps:int, jd_terms:[{term,normalized,required:bool,found:bool,in_recent_role:bool}], coverage_ratio:float, acronyms:[{token,expansion_found:bool,whitelisted:bool}], hidden_text_runs:int, knockouts:[{type:'visa'|'degree'|'location'|'salary'|'years', jd_value:string|null, profile_value:string|null, state:'match'|'mismatch'|'unknown'}], ats_platform:'greenhouse'|'workday'|'lever'|'taleo'|'icims'|'unknown' }`
131
+ - 각 rubric 체크가 ats_signals 필드와 1:1 매핑돼 AI가 결정론 pass/fail 표를 렌더(R5/R10은 advisory, R9는 llm_dependent 라벨). CareerMate=측정, AI=판단의 책임 분리를 구조로 강제.
@@ -0,0 +1,137 @@
1
+ # 회사 리서치 / Company Research — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ CareerMate 사용자를 대신해 지원 대상 회사·산업·보상을 리서치하고, 그 리서치를 **맞춤 면접 답변·고가치 질문·적합도 판정(go/no-go)** 으로 변환한다. 사고(synthesis)는 연결된 AI(Claude/GPT/Gemini)가 하고, CareerMate는 공고·프로필·적합도 분석·면접 자료를 MCP로 저장·제공한다. 핵심 규율은 다섯 가지다 — (1) 7개 캐논 앵커(미션/전략, 제품, 최근뉴스, 문화·인재상, 직무·레벨, **경쟁사·시장 포지션**, 보상)를 덮는다, (2) 출처 우선순위(1차/공식 > 2차/언론 > 3차/리뷰)를 지키고 교차검증·날짜를 붙인다, (3) 모든 사실을 STAR 훅·질문·적합도 플래그 중 하나로 **변환**한다(원시 사실은 미완성), (4) 모든 주장을 **이름·날짜가 붙은 출처**에 귀속시킨다, (5) **출처를 실제로 가져올 수 없으면 지어내지 말고 미검증으로 선언**한다.
8
+
9
+ **중요(정직한 한계):** 아래 루브릭은 LLM 없이 셀 수 있는 **완성도·형식 게이트**다. 출처가 **진짜인지·주장을 실제로 뒷받침하는지·정말 변환됐는지** 같은 품질·진위는 패턴/카운트로 검증할 수 없다 — 그 최종 품질 판단은 연결된 AI 본인의 책임이다. 루브릭은 "얇거나 출처 없는 리서치"를 사전에 걸러낼 뿐, 진실성을 보증하지 않는다.
10
+
11
+ ## 2. 플레이북
12
+
13
+ ### 원칙
14
+
15
+ - **7개 캐논 앵커를 덮어라: 미션/전략, 제품/비즈니스모델, 최근뉴스(≤6개월), 문화·인재상, 직무·레벨, 경쟁사·시장 포지션, 보상(협상 단계에 한함).** — 대학 커리어센터는 회사+산업+직무의 다축 커버리지로 수렴하며, 단일 축("About 페이지만 읽음")은 면접관이 즉시 할인한다. 경쟁사 축은 "왜 X가 아니라 우리냐"라는 최강 적합도 신호를 만든다. _(출처: UF Career Connections Center "Four Steps"; Ohio State ECS; Letscareer DART 경쟁사 비교)_
16
+ - **출처를 등급화하라: 회사 1차 자료(공식 사이트·블로그·채용공고·공시 DART 사업보고서)=Tier-1, 평판 있는 2차/언론=Tier-2, 자기선택 리뷰 플랫폼=Tier-3 신호.** — 리뷰 사이트 별점은 작고 비무작위인 자기선택 표본으로, 극단(매우 만족/매우 불만) 응답자에 치우친다. Tier-3 단독 근거로 결론을 내리지 마라. _(출처: BGSU ScholarWorks "Construct Validity of Glassdoor Ratings"; PubMed "Incentives can reduce bias")_
17
+ - **단, 잡플래닛의 면접 후기(질문 유형·전형 절차)는 별점과 구분해 취급하라.** — 한국 맥락에서 잡플래닛 **면접 후기**는 회사별 실제 질문·분위기를 담은, 별점보다 훨씬 actionable한 거의-1차에 가까운 제보다. 별점은 Tier-3로 두되, 면접 후기는 "회사별 제보(교차검증 권장)"로 가중치를 높여라. _(출처: 잡플래닛 면접후기)_
18
+ - **모든 비자명 주장은 ≥2개 독립 출처로 교차검증하라. 출처가 하나면 '미검증'으로 라벨링하라('단일 Glassdoor 리뷰에 따르면…').** — 어떤 단일 크라우드소스 데이터 1건은 사실이 아니라 가설이다. _(출처: UF "Four Steps" 링크드인 동문 교차확인; Ohio State ECS)_
19
+ - **최근성 타임스탬프: 모든 '최근 뉴스' 항목에 날짜를 붙이고 ~6개월 이내를 선호하라. 6개월 초과는 '최근'으로 부르지 말고, 12~18개월 초과는 스테일로 표시하라.** — 구체적·최근 동향 언급은 면접에서 가장 강한 신뢰 신호이며, 낡은 '최근'은 정반대로 준비 부족을 드러낸다. _(출처: UF "Four Steps"; Ohio State ECS)_
20
+ - **출처를 실제로 가져올 수 없으면(웹/도구 접근 없음, 학습 컷오프 이후) 날짜를 지어내지 말고 해당 앵커를 '미검증/라이브 출처 없음'으로 선언하라.** — 이것이 최대 날조 리스크다. YYYY-MM 정규식은 날짜가 **실재하는지** 검증하지 못한다 — 가짜 날짜로 게이트를 통과시키지 마라. _(출처: 본 플레이북 안티-날조 원칙; AGENTS.md 추측 금지)_
21
+ - **각 리서치 사실을 세 산출물 중 하나로 변환하라: (a) 사용자 강점↔회사 니즈를 잇는 STAR/답변 훅, (b) 면접관 질문, (c) 적합도 플래그(pro/con).** — 리서치의 목적은 답변 맞춤·적합도 판정·고가치 질문이다. 변환되지 않은 사실은 길이만 늘리는 미완성 출력이다. _(출처: Hays "How to research an employer"; Randstad RiseSmart STAR)_
22
+ - **면접관 질문 3~5개를 '공개 웹사이트만으로는 답할 수 없는' 특정 사실 기반 개방형(how/what)으로 만들고, 각 질문이 어느 앵커 사실에서 파생됐는지 기록하라(based_on_anchor).** — 홈페이지 너머를 읽었음을 증명하는 질문이 진정성·시니어리티를 신호한다. _(출처: Ohio State ECS; Indeed "27 Smart Questions"; UndercoverRecruiter)_
23
+ - **가능하면 면접관·팀 레이어까지 리서치하라: 패널의 역할/재직기간/최근 글, 직무가 속한 팀의 미션·제품영역·최근 팀 블로그.** — '웹사이트로 답 안 되는' 질문은 회사 전체가 아니라 **그 팀**에서 나온다. (라이브 출처 없으면 미검증으로 표시.) _(출처: UF "Four Steps" 링크드인 현직자; Ohio State ECS)_
24
+ - **적합도는 판정으로 끝내라: pro/con 플래그를 모두 만들고, 명시적 go/no-go 한 줄과 함께 ≥1개의 con(또는 disqualifier 검토)을 반드시 포함하라.** — con 없는 all-pro는 사용자가 듣고 싶은 말만 하는 확증편향이다. _(출처: 본 플레이북 적합도 판정 원칙)_
25
+ - **공고에 앵커링하라: 공고 상위 키워드/요건을 추출하고, '공고 키워드 → 사용자 강점 → 회사 니즈'를 잇는 매핑 레코드(triple)를 만들어라.** — 키워드를 단순 반복(echo)하는 게 아니라 강점·니즈와 묶는 것이 변환이다. _(출처: Letscareer DART 분석; Hays 강점-공고 정렬)_
26
+ - **보상은 협상 단계에 한해 다루고, 시장에 맞게 분해하라.** 글로벌 빅테크는 levels.fyi로 레벨 매핑 후 base/bonus/equity 분해. **한국·비테크·SME·공공은 equity가 거의 없고 포괄임금·상여(13th·성과급)·직급(사원/대리/과장)이 1급 구조다 — equity를 강요하지 마라.** DART 직원 평균 급여는 **전사 평균**이지 직급/직무 밴드가 아니다 — 밴드 앵커로 쓰지 마라. _(출처: levels.fyi 협상 가이드; MIT CAPD; DART 사업보고서 주의)_
27
+
28
+ ### Do
29
+
30
+ - 연결 직후 `get_application_context`로 대상 공고·프로필·강조 포인트를 먼저 확보하고 그 위에 외부 리서치를 얹어라.
31
+ - 7개 앵커를 체크리스트로 돌며 각 항목에 최소 1개의 출처(이름+날짜)를 붙여라. 못 채운 앵커는 침묵하지 말고 '미확인/해당없음(사유)'으로 명시하라.
32
+ - 리뷰 사이트 항목은 '제보 기반 신호'로 라벨링하고, 같은 결론을 받치는 2차 출처를 1개 더 찾아 교차검증하라. (잡플래닛 면접후기는 별점보다 가중치를 높이되 여전히 교차확인.)
33
+ - 최근 6개월 내 뉴스(출시·투자·조직개편·리더십)를 ≥1개 찾아 면접 오프닝/질문에 구체적으로 인용하라. **라이브로 못 찾으면 '미검증'으로 표시**하라.
34
+ - 경쟁사 ≥2곳과 그 대비 '우리의 차별점' 1줄을 확보해 "왜 X가 아니라 여기냐"에 답할 수 있게 하라.
35
+ - 모든 사실을 STAR 훅·질문·적합도 플래그 중 하나로 변환하고, 변환 안 된 원시 사실은 `gaps`로 보류하라.
36
+ - 면접관 질문 3~5개를 특정 사실 기반 개방형으로 만들고 각 질문에 `based_on_anchor`를 기록하라.
37
+ - 적합도 판정에 명시적 go/no-go 한 줄과 ≥1개의 con을 포함하라.
38
+ - 공고 키워드를 '키워드→강점→니즈' triple로 매핑해 저장하라(단순 반복 금지).
39
+ - 보상은 **협상 단계에서만** 다루고, 한국이면 직급·상여·포괄임금 구조로, 글로벌 테크면 base/bonus/equity+levels.fyi로 분해하라.
40
+ - 공개 자료가 희박한 회사(SME·스텔스 스타트업)는 솔직히 '공개 발자국 희소'로 보고하고, 빈 앵커를 면접 질문으로 전환하는 계획을 제시하라.
41
+ - 최종 산출은 `save_fit_analysis`·`save_interview_prep`로 저장하고 대시보드 링크(`http://127.0.0.1:4319`)를 안내하라.
42
+
43
+ ### Don't
44
+
45
+ - 리뷰 단일 별점·험담을 검증 없이 사실로 단정하지 마라(작고 비무작위인 자기선택 표본).
46
+ - '좋은 문화', '성장하는 회사' 같은 출처 없는 일반론으로 리서치를 채우지 마라.
47
+ - 회사 About 페이지만 읽고 리서치를 끝냈다고 하지 마라(단일 축·단일 출처 결론 금지).
48
+ - 라이브 출처를 못 가져오는데 날짜·뉴스를 **지어내지** 마라 — 미검증으로 선언하라.
49
+ - 12~18개월 지난 뉴스를 '최근'이라 부르지 마라. 6개월 초과면 '최근' 라벨을 떼라.
50
+ - 공개 웹사이트만으로 답 나오는 질문('주력 제품이 뭔가요?', '앞으로 어떻게 성장하나요?')을 면접 질문으로 내지 마라.
51
+ - 보상을 단일 숫자로 인용하지 마라. **DART 전사 평균을 직급 밴드처럼 쓰지 마라.** equity 없는 한국 직무에 equity를 억지로 끼워 fail-flag 하지 마라.
52
+ - 면접 전 단계에서 보상 협상을 무리하게 끌어올리지 마라(보상은 오퍼/협상 단계 게이팅).
53
+ - 공고·강점과 연결하지 않은 채 회사 사실만 나열하지 마라(에코 ≠ 변환).
54
+ - all-pro 플래그만 내고 '판정'이라 부르지 마라(확증편향).
55
+ - 사용자 데이터를 외부로 보내거나, 미검증 추정을 사실로 단정해 지어내지 마라(불확실하면 사용자에게 확인).
56
+
57
+ ### 워크드 예시 (Before → After)
58
+
59
+ 1. **Before:** "이 회사는 좋은 기업 문화로 유명하고 성장하고 있어서 지원했습니다. 제품도 훌륭하고 비전이 멋집니다."
60
+ **After:** "공식 블로그(2026-03)에 따르면 귀사는 동남아 결제 인프라로 확장 중이고, 업계 보도 2곳에서 교차확인된 시리즈C(2026-02)를 마쳤습니다. 경쟁사 A·B 대비 차별점은 다국가 정산 정합성 자동화로 보입니다. 저는 핀테크 정산 시스템을 다국가로 확장한 경험(처리량 3배↑)이 있어, 공고의 '글로벌 결제 트래픽 처리' 요건(키워드)→제 강점→귀사의 확장 니즈로 직접 연결됩니다. — 면접 질문(based_on: 최근뉴스): '동남아 확장에서 reconciliation을 어느 단계까지 자동화하셨고, 다음 분기 병목은 어디라고 보시나요?'"
61
+ **왜 더 나은가:** 출처+날짜, 교차검증된 최근뉴스, 경쟁사 차별점, 그리고 키워드→강점→니즈 triple과 앵커 기반 개방형 질문으로 변환됐다. Before는 출처 없는 일반론이라 어느 회사에나 붙는다.
62
+
63
+ 2. **Before:** "Glassdoor 별점이 2.9이고 '워라밸이 나쁘다'는 리뷰가 있어 이 회사는 워라밸이 안 좋습니다."
64
+ **After:** "Glassdoor·잡플래닛(제보 기반 신호, 자기선택 표본이라 편향 가능) 일부 리뷰에 '성수기 야근' 언급이 있습니다 — 단정하지 않습니다. 교차확인: 채용공고에 '온콜 로테이션' 문구, 링크드인 현직자 1명이 '분기 마감 주간만 집중'이라 확인 → 결론은 '상시 야근'이 아니라 '특정 주기 피크'. 적합도 con 플래그로 기록하고, 면접에서 '온콜/마감 주기의 빈도와 보상 방식'을 직접 물어 확인할 것."
65
+ **왜 더 나은가:** Tier-3를 신호로만 라벨링하고 2차 출처로 교차검증해 과장된 결론을 보정했으며, 미확인 항목을 con 플래그+면접 질문으로 전환했다. Before는 단일 출처를 사실로 단정한 안티패턴이다.
66
+
67
+ 3. **Before:** "이 직무 연봉은 약 6천만 원 정도로 알고 있습니다."
68
+ **After:** "(협상 단계에서) **한국 법인**이라면: 잡플래닛 연봉 제보(N건, 직급=대리 기준)와 DART 사업보고서의 **전사** 평균 급여를 *참고치로만* 교차확인하고, 포괄임금 여부·상여/성과급 구조·직급(사원/대리/과장)을 분해해 묻습니다 — DART 평균은 직급 밴드가 아니므로 밴드로 쓰지 않습니다. **글로벌 테크**라면: levels.fyi에서 해당 회사 레벨(공고의 'Senior'에 *근사* 매핑, 회사별로 다를 수 있음)의 base/bonus/equity 중앙값(데이터 N건, 갱신 2026-Q2)으로 분해합니다. 어느 쪽이든 단일 숫자가 아니라 밴드+구조로 협상 앵커를 잡습니다."
69
+ **왜 더 나은가:** 시장별로 구조를 분리(한국=직급·상여·포괄임금, 글로벌=base/bonus/equity)하고, DART 평균을 밴드로 오용하지 않으며, 레벨 매핑이 근사임을 명시했다. 보상을 협상 단계로 게이팅했다. Before는 출처·구조·레벨이 없는 단일 숫자라 협상에 쓸 수 없다.
70
+
71
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
72
+
73
+ > **설계 원칙:** 루브릭은 **연결된 AI가 EMIT하는 구조화 필드**(아래 §5 data shape의 `anchors[]`, `questions[]`, `fit_flags[]`, `mappings[]` 등) 위에서 **존재여부·non-null·개수**를 센다 — 산문에 정규식을 돌리지 않는다. 이는 측정을 게임하기 어렵게 만들고 LLM 없이 결정적으로 통과/실패를 낸다. 단, 이 게이트들은 **완성도·형식**만 본다 — 진위·출처 유효성·진짜 변환 여부는 검증하지 못한다(연결된 AI 책임).
74
+
75
+ | ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) |
76
+ |----|-----------|-----------|--------------------------------|
77
+ | R1 | 7개 캐논 앵커 커버리지 | `anchors[].key`가 7종 중 ≥6종 존재 AND 각 앵커의 `facts[]`가 비어있지 않거나 `status`가 `unverified`/`n/a(사유)`로 명시 | `anchors` 배열에서 distinct `key` 수와, 빈 `facts[]`의 `status` non-null 여부를 카운트 |
78
+ | R2 | 사실당 출처 귀속 | `anchors[].facts[]`의 각 fact가 `source_name` non-null AND `source_tier∈{1,2,3}` 보유 비율 ≥90% | fact 객체에서 `source_name!=null && source_tier!=null` 개수 ÷ 전체 fact 수 (구조 필드 카운트) |
79
+ | R3 | 최근뉴스 날짜 + 스테일 FAIL | `recent_news` 앵커에 `dated`(YYYY-MM) 있는 fact ≥1 AND **'최근'으로 라벨된 fact의 `dated`가 6개월 이내**; 6개월 초과를 '최근'으로 표기하면 FAIL | `dated` 필드 파싱 후 기준일과의 개월차 계산; `label=='recent' && months_diff>6`이면 실패 카운트>0 |
80
+ | R4 | 라이브 출처 없음 정직 선언 | 라이브 검색 불가 시 해당 fact는 `retrieved=false` AND `status='unverified'`; `retrieved=false`인데 `dated`만 채워진 fact 0건 | `retrieved==false && dated!=null && status!='unverified'` 위반 건수=0 |
81
+ | R5 | Tier-3 단독 결론 없음 | `source_tier==3`만으로 도출된 결론 fact는 `cross_verified==true`(독립 2차 출처 `source_name` 동반) 또는 `signal_only==true` 라벨 | tier3 fact 중 `cross_verified==false && signal_only==false` 건수=0 (구조 플래그 카운트) |
82
+ | R6 | 질문 사양 + 앵커 출처 | `questions[]` 개수 3~5 AND 각 question이 `based_on_anchor` non-null AND `open_ended==true` (AI가 EMIT한 플래그) | `questions` 길이 ∈[3,5]; `based_on_anchor!=null && open_ended==true` 비율=100% |
83
+ | R7 | 공고 매핑 triple | `mappings[]`에 `{keyword, user_strength, company_need}` 3필드 모두 non-null인 완전 triple ≥3개 | triple 객체에서 세 필드 동시 non-null 개수 카운트 ≥3 (에코가 아니라 매핑) |
84
+ | R8 | 적합도 판정(con 강제) | `fit_flags[]`에 `type=='con'` ≥1 AND `verdict` 필드(go/no-go) non-null | `fit_flags` 중 `type=='con'` 개수≥1 그리고 `verdict!=null` |
85
+ | R9 | 보상 시장별 분해(조건부) | `comp`가 존재하고 `phase=='negotiation'`일 때만 평가: `market=='kr'`이면 `{직급, 상여/성과급, 포괄임금여부}` 중 ≥2 + DART는 `band==false`; `market=='global'`이면 `{base, bonus, equity?}` 중 ≥2 + `level_map_approximate==true` | `comp.phase`로 게이팅; 시장별 요구 필드 non-null 개수 카운트, equity는 kr에서 optional |
86
+
87
+ **주요 실패 모드:**
88
+ - **형식 통과 = 품질 통과로 착각.** R1~R9는 모두 표면 형식(필드 존재·개수)만 본다. 가짜 출처명·boilerplate `cross_verified=true`·진짜 매핑이 아닌 triple은 잡지 못한다 — 진위·변환 품질은 연결된 AI가 책임진다.
89
+ - **날짜 날조.** 라이브 출처 없이 그럴듯한 YYYY-MM을 채워 R3을 통과시키는 것. R4가 `retrieved` 플래그로 1차 방어하지만, AI가 정직하게 EMIT해야만 작동한다.
90
+ - **에코 ≠ 변환.** 공고 명사를 답변에 복붙해 키워드만 늘리는 것(구 bag-of-words 함정). R7은 완전 triple만 세서 단순 반복을 거른다.
91
+ - **확증편향(all-pro).** con 없는 판정. R8이 `type=='con'` ≥1을 강제한다.
92
+ - **US-테크 편향.** equity·levels.fyi·L\d 레벨을 한국·비테크 직무에 강요해 정상 리서치를 fail-flag. R9가 시장별로 분기하고 equity를 kr에서 optional로 둔다.
93
+ - **얇은 데이터 회사를 날조로 메움.** SME·스텔스의 빈 앵커를 지어내 채우는 것. R1이 `status='unverified'`/`n/a(사유)`를 허용해 정직한 공백을 합격으로 인정한다.
94
+
95
+ ## 4. 출처 (Provenance)
96
+
97
+ - **UF Career Connections Center — Four Steps for Researching an Employer** — 캐논 앵커(미션/문화/제품/뉴스), 다출처 교차검증, 링크드인 현직자 확인, 최근 게시물 언급 전략 · https://career.ufl.edu/four-steps-for-researching-an-employer/
98
+ - **Ohio State Engineering Career Services — How to Research a Company for an Interview** — 여러 소스 결합(Handshake/Glassdoor/LinkedIn/Google), 리서치 기반 3~5개 질문 준비 · https://www.ecs.osu.edu/news/2025/02/how-research-company-interview
99
+ - **BGSU ScholarWorks — Examining the Construct Validity of Glassdoor.com Ratings** — 리뷰 사이트 자기선택·비무작위 표본 편향을 Tier-3 신호로만 다루는 근거(정성적 방향성; 단일 보편 상수로 인용 금지) · https://scholarworks.bgsu.edu/cgi/viewcontent.cgi?article=1099&context=pad
100
+ - **PubMed — Incentives can reduce bias in online employer reviews** — 자원/자기선택 리뷰가 더 극단적이라는 실증 → 단일 리뷰 단정 금지 · https://pubmed.ncbi.nlm.nih.gov/33764122/
101
+ - **levels.fyi — Ultimate Negotiation Guide & leveling methodology** — (글로벌 테크 한정) 레벨 *근사* 매핑, total comp의 base+bonus+equity 분해, 협상 앵커링. 한국·비테크·SME 커버리지는 희소함에 유의 · https://www.levels.fyi/blog/ultimate-negotiation-guide.html
102
+ - **MIT CAPD — How to negotiate your tech salary ft. levels.fyi** — 보상 데이터를 레벨에 매핑해 협상 앵커로 쓰는 교육 자료 · https://capd.mit.edu/resources/how-to-negotiate-your-tech-salary-ft-levels-fyi-video/
103
+ - **Hays — How to research an employer before an interview** — 리서치를 STAR 답변·맞춤 질문으로 변환, 강점을 공고/회사 목표에 정렬 · https://www.hays.co.uk/career-advice/article/interview-prep-employer-research
104
+ - **Indeed — 27 Smart Questions to Ask in an Interview** — 리서치 기반 개방형 질문 설계 기준 · https://www.indeed.com/career-advice/interviewing/smart-questions-to-ask-in-an-interview
105
+ - **Letscareer — DART 사업보고서 분석 방법** — 한국 맥락: '사업의 내용'·'경영진 의견' 분석을 지원 동기/면접 차별화로 연결, **경쟁사 비교**. 단 직원 평균 급여는 전사 평균이지 직급 밴드가 아님에 유의 · https://www.letscareer.co.kr/blog/65/
106
+ - **잡플래닛 (JobPlanet)** — 한국 맥락 소스. 별점=Tier-3 신호이나 **면접 후기(질문 유형·전형)는 거의-1차에 가까운 actionable 제보**로 가중치 상향(교차검증 전제) · https://www.jobplanet.co.kr/
107
+
108
+ ## 5. Phase B 힌트 (아키텍처로 연결)
109
+
110
+ - **MCP 도구 아이디어:**
111
+ - `get_company_research_brief(job_id)` — 대상 공고에 묶인 7개 캐논 앵커 슬롯(미션/전략, 제품, 최근뉴스, 문화·인재상, 직무·레벨, **경쟁사·시장**, 보상) 작업판을 반환. 각 앵커에 '사실+출처명+날짜+신뢰등급(Tier1/2/3)+retrieved/cross_verified 플래그' 배열, 공고 상위 키워드, 사용자 강점 목록, 빈/미검증/스테일 앵커를 표시하는 `gaps`.
112
+ - `save_company_research(job_id, anchors[], mappings[], questions[], fit_flags[], comp?)` — 결과를 구조화 필드로 저장.
113
+ - `validate_company_research(payload)` — §3 R1~R9를 **LLM 없이 구조 필드 카운트/존재여부**로 돌려 `{check_id, passed, measured_value}` 배열 반환. 정규식-온-프로즈가 아니라 EMIT된 struct 위에서만 측정.
114
+ - **데이터 형태 힌트:**
115
+ ```
116
+ {
117
+ job_id,
118
+ posting_keywords: string[],
119
+ user_strengths: string[],
120
+ anchors: { key: 'mission'|'product'|'recent_news'|'culture'|'level'|'competitor'|'comp',
121
+ status: 'filled'|'unverified'|'n/a',
122
+ facts: [{ text, source_name, source_tier: 1|2|3, dated: 'YYYY-MM'|null,
123
+ retrieved: boolean, cross_verified: boolean, signal_only: boolean,
124
+ label?: 'recent' }] }[],
125
+ mappings: [{ keyword, user_strength, company_need }], // 완전 triple만 카운트
126
+ comp?: { phase: 'research'|'negotiation', market: 'kr'|'global',
127
+ // kr: { 직급?, 상여?, 성과급?, 포괄임금여부?, dart_band: false }
128
+ // global: { base?, bonus?, equity?, level_map_approximate: true } },
129
+ generated: {
130
+ questions: [{ text, based_on_anchor, open_ended: boolean }], // 3~5개
131
+ fit_flags: [{ type: 'pro'|'con', text, source_name }], // con ≥1
132
+ verdict: 'go'|'no-go'|'conditional' // non-null 강제
133
+ },
134
+ gaps: string[],
135
+ validation: [{ check_id, passed: boolean, measured_value }]
136
+ }
137
+ ```
@@ -0,0 +1,135 @@
1
+ # 자기소개서 / Cover Letter — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ 자기소개서/커버레터는 이력서를 산문으로 다시 쓴 글이 아니라, **특정 회사·직무를 겨냥한 설득 문서**다. 검증된 뼈대는 hook → fit(왜 나, 증거) → why-this-company → close이며, 각 주장은 형용사가 아니라 행동+정량 결과(STAR-lite) 한 단락으로 증명한다. 가장 흔한 실패는 **회사명을 바꿔도 말이 되는 제너릭 편지**(빈 형용사, 회사 고유 근거 없음, 이력서 불릿 복붙)다. CareerMate는 LLM이 없으므로, 검증 루브릭을 **두 종류로 정직하게 분리**한다 — (A) 순수 정규식·카운트로 저장 전 자동 검사 가능한 항목, (B) 연결 AI의 의미 판단이 필요한 항목. 또한 한국 자소서(문항형·글자수·인재상)와 영문 커버레터(단일 레터·ATS)는 **로케일별로 다른 루브릭**을 적용한다.
8
+
9
+ ## 2. 플레이북
10
+
11
+ ### 원칙
12
+
13
+ - **구조를 hook → fit(증거) → why-this-company → close 4역할로 고정하되, locale='ko' 문항형 자소서는 문항당 별도 글로 다룬다.** 영문 단일 레터는 4역할이 각각 한 문단 이상 존재해야 한다. 한국 자소서는 보통 3~5개 문항('지원동기/성장과정/직무역량/입사후포부')이 각각 별개 글이고 글자수 제한도 다르므로, 4역할 단일 레터를 강제하지 말고 **문항별 두괄식(결론→증명→직무·인재상 연결)** 로 매핑한다. _(출처: Georgetown Cawley Career Center; Princeton Cover Letter Guide; 한국 대기업 공채 자소서 문항 관행)_
14
+ - **형용사로 자신을 묘사하지 말고, 그 형용사가 참임을 증명하는 구체적 사례로 대체하라.** '소통을 잘한다' 대신 '야간 피킹 라인을 3개월 주도해 오배송률 4.1%→1.2%'처럼 행동+전후 델타를 쓴다. 빈 형용사뿐 아니라 '~라고 생각합니다', '많은 것을 배웠습니다', '~을 통해 성장했습니다', '~에 기여하고 싶습니다' 같은 **증거 없는 자기서술 종결구문**도 슬롭이다. _(출처: LiveCareer/CareerAddict Cover Letter Mistakes; Linkareer 두괄식 작성법)_
15
+ - **각 핵심 주장은 STAR-lite로 증명하되, 한 통/한 문항에 1~2개의 대표 경험만 깊게 다뤄라.** 결과(R)는 **'규모'가 아니라 '본인 행동으로 인한 변화량'** 이다. '100억 규모 프로젝트 담당'은 임팩트가 아니다 — '전환율 60→210(+250%)'이 임팩트다. S/T 압축은 글자수 빠듯한 문항의 기본값이되, 경험 서술형 문항은 평가자가 맥락을 요구하므로 **문항 유형에 따라 S/T 분량을 조절**한다. _(출처: Harvard FAS Mignone Center; 매거진한경 KKK-STAR)_
16
+ - **이력서를 줄단위로 반복하지 마라.** 커버레터는 이력서가 못 담는 '왜·어떻게·맥락'을 더한다. 다만 한국어는 교착어라 표면형이 달라도 의미가 같을 수 있으니, 중복 판정은 단순 n-gram이 아니라 의미 기준으로 본다. _(출처: 4 Corner Resources; LiveCareer)_
17
+ - **'왜 이 회사인가'를 회사 고유 근거(미션·제품·최근 활동·인재상/핵심가치)로 1~3문장 명시하라.** 회사명을 placeholder로 바꿔도 말이 되는 문장은 실패다. _(출처: University of Maryland Cover Letter Resources; Catch 합격 자소서)_
18
+ - **본문의 모든 수치·고유명사는 저장된 사용자 데이터(get_resumes·경력·프로젝트)에 출처가 있어야 한다.** 정량화를 강조하되 **없는 수치를 발명하도록 압박하지 마라** — 면접에서 즉시 무너진다. 근거가 없으면 약한 주장을 빼되 숫자를 지어내지 않는다. _(출처: CareerMate AGENTS.md 사실 보존 원칙; get_writing_style_guide)_
19
+ - **공고 핵심 요구사항을 본인 증거와 1:1 매핑하되 키워드 스터핑을 피하라.** 단, `get_application_context`의 `job.requirements`/`job.keywords`는 **선택적 자유텍스트 배열**이라 '상위 N개 랭킹'이 보장되지 않는다. 비어 있으면 이 매핑 체크는 **skip(N/A)** 처리한다. _(출처: Yale HR/Career Development; Scale.jobs Keyword Mistakes)_
20
+ - **분량/글자수는 로케일별로 다르다.** 영문 학생 커버레터는 3/4~1페이지(≈250~400단어). 한국 자소서는 문항당 500~1000자가 흔하고 **상한뿐 아니라 하한**(예: 최소 500자)도 평가에 들어가며, 글자수 기준이 **공백 포함/제외/byte** 로 공고마다 갈린다(가장 흔한 실격 사유). _(출처: University of Cincinnati Guide; 한국 자소서 글자수 관행)_
21
+ - **수신자 실명·직무명 지정은 로케일 의존이다.** 영문/외국계 다이렉트 지원은 'To whom it may concern' 대신 채용담당자 실명을 쓴다. 한국 공채/플랫폼은 시스템 폼 입력이라 수신자 특정이 불가능하므로 실명 지정을 강제하지 않는다. _(출처: Harvard via CNBC; 한국 공채 지원 폼 현실)_
22
+ - **블라인드 채용 가드레일을 지켜라.** 한국 NCS/공정채용 기조상 나이·성별·사진·가족관계·출신지 등 직무무관 개인정보는 자소서에 넣지 않는다. _(출처: NCS 블라인드 채용 가이드 기조)_
23
+ - **직무 유형·지원자 경로별로 기준을 차등하라.** 경력직(임팩트·리더십·P&L), 신입/인턴(잠재력·학습속도·전이가능 스킬), 기술직(설계 디테일) vs 영업/마케팅(정량 KPI)은 평가축이 다르다. 신입·경력단절·직무전환자는 정량 실적이 빈약하므로 **'숫자 ≥2'를 강요하지 말고** 프로젝트·학습 사례로 fit을 증명하게 한다. _(출처: Harvard 직무 직결 경험 권고; 채용 실무 차등)_
24
+
25
+ ### Do
26
+
27
+ - 영문 도입 첫 문장에 (직무명 + 가장 관련 있는 경험 한 가지 + 회사에 대한 구체적 한 줄)을 넣어라. 한국 문항은 결론(직무 강점/지원동기)을 첫 문장에 두는 두괄식으로 시작하라.
28
+ - 각 강점 주장 뒤에 STAR-lite 한 단락(행동 → **전후 델타형 정량 결과**)을 붙여 증명하라.
29
+ - '왜 이 회사'를 회사 고유 사실(제품·미션·최근 뉴스·인재상)로 못박아라.
30
+ - 성과를 **전/후 비교(X→Y), 증감률(+N%), 금액·기간**으로 정량화하되, 그 수치가 저장된 이력서·경력 데이터에 근거가 있는지 확인하라.
31
+ - 약점·실패·갈등 문항은 정량 성과가 아니라 **성찰·개선 행동**으로 답하라(이 문항에 'quantified ≥2'를 강요하지 마라).
32
+ - 글자수 제한을 적용할 때 **count_mode(공백포함/공백제외/byte)** 를 먼저 확인하라.
33
+ - 클로징에 명확한 다음 단계(면접 요청/연락 가능 시점)를 한 문장으로 넣어라(로케일상 가능할 때).
34
+ - 저장 전 lint(루브릭 자동 검사)를 통과시킨 뒤 save_cover_letter_version으로 보관하라.
35
+ - 초안은 get_writing_style_guide의 문체를 적용해 사람이 쓴 듯 자연스럽게 다듬어라.
36
+
37
+ ### Don't
38
+
39
+ - 'I am writing to apply for…' / 'I have always been passionate about' / 'As a recent graduate' / '저는 ~에 지원합니다' / '어릴 적부터', '~을 보며 자랐습니다', '저는 ~한 사람입니다', '평소 ~에 관심이 많아' 같은 상투적·성장기 도입으로 시작하지 마라.
40
+ - '성실한·책임감·열정·소통을 잘하는 / 꼼꼼한·끈기있는·헌신적인·주도적인 / hard-working·team player·detail-oriented·motivated·proactive·dedicated·diligent·people person' 같은 **증거 없는 평가형 형용사**나 그 동의어로 자신을 묘사하지 마라.
41
+ - '~라고 생각합니다', '많은 것을 배웠습니다', '~을 통해 성장했습니다', '귀사' 같은 증거 없는 자기서술 종결구문을 남발하지 마라.
42
+ - 이력서 불릿을 문장으로 바꿔 그대로 반복하지 마라.
43
+ - 회사명을 바꿔도 말이 되는 제너릭 지원동기를 쓰지 마라.
44
+ - 한 통/한 문항에 5~6개 경험을 얕게 나열하지 마라(1~2개 깊게).
45
+ - '규모'(담당 규모·팀 인원·연도)를 '성과'로 위장하지 마라 — 본인 행동의 변화량이 결과다.
46
+ - 없는 성과·수치·고유명사를 지어내거나 과장하지 마라.
47
+ - 공고 키워드를 맥락 없이 나열(keyword stuffing)하지 마라.
48
+ - 나이·성별·사진·가족관계 등 직무무관 개인정보를 넣지 마라.
49
+ - 한 페이지(또는 지정 글자수 상한/하한)를 벗어나거나 빽빽한 텍스트 벽을 만들지 마라.
50
+ - MCP·job_id 같은 기술 용어를 편지 본문/사용자 설명에 노출하지 마라.
51
+
52
+ ### 워크드 예시 (Before → After)
53
+
54
+ 1. **Before:** 저는 책임감이 강하고 성실하며 팀워크가 뛰어난 지원자입니다. 어떤 일이든 열정을 가지고 최선을 다합니다. 귀사에 입사하여 열심히 일하고 싶습니다.
55
+ **After:** [직무 강점] 물류 인턴 시절, 출고 지연이 잦던 야간 피킹 라인을 맡아 동선 재배치와 체크리스트 도입을 주도했고(행동) 3개월간 오배송률을 4.1%→1.2%로 줄였습니다(결과). 같은 '병목을 데이터로 찾아 표준화하는' 방식이 OOO의 풀필먼트 자동화 로드맵에 바로 기여할 수 있다고 봅니다.
56
+ **왜 더 나은가:** 빈 형용사 3개를 STAR-lite 한 단락(행동+전후 델타 4.1→1.2%)으로 교체했고, 두괄식으로 결론을 앞세웠다. 마지막 문장이 회사 고유 맥락(풀필먼트 자동화)과 본인 강점을 연결해 '왜 나·왜 이 회사'를 동시에 충족한다. 회사명을 바꾸면 어색해진다 = 제너릭이 아니다.
57
+
58
+ 2. **Before:** I am writing to apply for the Marketing Coordinator position. I am a hard-working, detail-oriented team player with a passion for marketing and excellent communication skills.
59
+ **After:** When our student org's event registrations stalled at 60 signups, I rebuilt the email funnel and A/B-tested subject lines, lifting registrations to 210 (+250%) in three weeks. That same test-measure-iterate habit is what drew me to Acme's growth team, whose public "experiment weekly" culture matches how I already work.
60
+ **왜 더 나은가:** 상투적 도입과 4개 빈 형용사를 제거하고, **전후 델타(60→210, +250%, 3주)** 가 있는 단일 STAR 사례로 'detail-oriented/communication' 주장을 증명한다. 마지막 절이 회사 고유 근거('experiment weekly' 문화)로 why-this-company를 못박는다.
61
+
62
+ 3. **Before:** 저는 5개 프로젝트를 주도했고 매출 100억 규모 사업을 담당했습니다. 신규 고객을 발굴하고 보고서를 작성했습니다.
63
+ **After:** [직무 강점] 저는 '이탈 직전 고객을 데이터로 식별해 되살리는' 영업입니다. OO기업에서 해지 예고 고객을 결제주기·CS티켓으로 스코어링하는 시트를 만들어 상위 위험군에 선제 제안을 돌렸고(행동) 분기 이탈률을 9%→5%로 낮춰 유지매출 약 1.3억을 방어했습니다(결과). 데이터로 리텐션을 설계하는 이 방식이 OOO의 구독 비즈니스 핵심과 직결된다고 봅니다.
64
+ **왜 더 나은가:** Before는 '5개·100억'이라는 **규모 수치**일 뿐 본인 기여 결과가 0이고 이력서 재진술이다. After는 두괄식 + 이력서가 못 담는 '어떻게(스코어링 시트)' + **본인 행동의 변화량(9→5%, 1.3억)** 을 더하며 회사의 구독 비즈니스와 연결한다. 규모(scale)와 임팩트(impact)의 차이를 보여준다.
65
+
66
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
67
+
68
+ 각 항목의 `measure.type`을 정직하게 표기한다 — **`regex`/`count`/`ratio`** 는 LLM 없이 lint로 자동 검사 가능, **`ai-judge`** 는 연결 AI의 의미 판단이 필요(정규식 불가). lint_cover_letter는 `regex`/`count`/`ratio` 항목만 자동 채점하고, `ai-judge` 항목은 연결 AI에게 위임 표시한다.
69
+
70
+ | ID | 검사 항목 | 합격 기준 | 측정 방법(type · LLM 없이 셀 수 있게) |
71
+ |----|-----------|-----------|--------------------------------|
72
+ | R1 | 구조 역할 존재 | 영문: 4역할 present / 한국 문항형: 각 문항 두괄식 + 문항-역량 매핑 present | `ai-judge` — 문단 역할 분류는 의미 판단이라 정규식 불가. 연결 AI가 역할 태그를 달고 누락 0 확인. **lint 자동검사 불가(위임)** |
73
+ | R2 | 제너릭 도입 차단 | 금지 도입 패턴 매치 0건 | `regex` — 첫 문장에 `/(i am writing to apply\|i have always been passionate\|as a recent graduate\|지원하게 되었습니다\|지원합니다\|어릴 적부터\|보며 자랐습니다\|저는 .{0,8}한 사람입니다\|평소 .{0,12}관심이 많아\|to whom it may concern)/i` 히트 = 0 |
74
+ | R3 | 빈 형용사·자기서술 슬롭 | 평가형 형용사/종결구문 사전 매치 0건; 매치 시 동일 문단에 정량 증거 동반 | `regex+ratio` — 사전(성실\|책임감\|열정\|소통을 잘\|꼼꼼\|끈기\|헌신적\|주도적인\|커뮤니케이션이 원활\|라고 생각합니다\|많은 것을 배웠\|통해 성장\|기여하고 싶\|team player\|hard-?working\|detail-?oriented\|motivated\|proactive\|dedicated\|diligent\|people person) 매치=0 권장. **사전은 불완전 — 동의어 우회 가능하므로 R8(형용사+증거 비율)과 함께 본다** |
75
+ | R4 | 정량 **성과**(규모 아님) | 전후 비교/델타 패턴 ≥1 | `regex` — `/\d[\d,\.]*\s?%?\s?(→|->|~|에서)\s?\d[\d,\.]*\s?%?|[+\-]\s?\d+\s?%|(감소|증가|줄였|늘렸|개선|달성)[^.]{0,20}\d/` 매치 ≥1. **연도(20\d\d~20\d\d)·문항번호·전화·날짜는 negative lookahead로 제외** — 단순 숫자 카운트 금지 |
76
+ | R5 | 수치 출처 검증 | 본문 수치 토큰이 저장된 이력서/경력 데이터에 존재 | `count` — 본문 숫자 토큰을 추출해 get_resumes·experiences·projects 텍스트에서 동일/근접 토큰 매칭. 미발견 수치 수 = 0 권장(허위 수치 탐지) |
77
+ | R6 | 회사 고유성 | 회사명/제품/미션 고유명사 ≥2회 + 비종속 검사 | `count`(부분 자동) + `ai-judge`(완전 판정) — 토큰 등장 횟수 ≥2는 카운트 가능. '회사명 placeholder 치환 시 어색해지는 문장 ≥1'은 **연결 AI 판정(위임)** |
78
+ | R7 | 이력서 비반복 | locale별 임계 이하 | `ratio` — 영문: 단어 5-gram 중복 ≤20%. **한국어: 어절 n-gram은 교착어 특성상 부정확 → 임계 신뢰 낮음, 의미 중복은 `ai-judge` 보조 필요(한계 명시)** |
79
+ | R8 | STAR 행동+성과 동반 | 행동동사 단락 중 결과 절 동반 ≥1, 단 '규모≠성과' | `regex`(약) + `ai-judge` — 행동동사+결과신호 동시출현은 카운트되나 '우연 동시출현·규모 수치'를 구분하려면 연결 AI가 'R이 본인 행동의 변화량인가' 판정 |
80
+ | R9 | 분량/글자수 | locale·count_mode별 상·하한 이내 | `count` — 영문 word_count ≤400. 한국: char_count가 지정 limit 이내 **그리고 하한 이상**. **count_mode(with_space\|no_space\|byte) 입력 필수**(미지정 시 fail-safe로 가장 빡빡한 기준 사용) |
81
+ | R10 | 공고 요구 매핑 | 공고 키워드 ≥3개가 증거와 함께 등장 | `count`+`ai-judge` — 토큰 매치 카운트는 가능하나 '증거 동반' 판정은 의미 판단. **`job.requirements`/`keywords`가 비면 skip(N/A)** — 데이터 부재 시 통과/실패 강제 금지 |
82
+ | R11 | 블라인드 가드레일 | 직무무관 개인정보 패턴 0건 | `regex` — `/(\d{2,3}\s?세|남자|여자|아버지|어머니|출신|본적|사진 첨부)/` 등 NCS 금지정보 매치 = 0(locale='ko') |
83
+ | R12 | 1인칭 과다 | '저는/I'로 시작하는 문장 비율 ≤40% | `ratio` — 문장 분리 후 시작 토큰이 (저는\|제가\|^I\b)인 비율 계산 ≤0.40 |
84
+
85
+ **점수·게이팅:** overallPass는 단순 AND가 아니라 **가중 게이팅**이다. **치명(반드시 통과)** = R2·R3·R4·R5·R6(제너릭·증거 없음·허위 수치는 즉시 탈락 사유). **중요** = R1·R8·R10·R11. **경미** = R7·R9·R12(분량 5% 초과 등은 감점만). 치명 항목 중 하나라도 fail이면 overallPass=false. score는 치명 60% + 중요 30% + 경미 10% 가중합. lint는 `regex/count/ratio` 항목만 자동 채점하고 `ai-judge` 항목은 'AI 위임' 상태로 반환한다.
86
+
87
+ **주요 실패 모드:**
88
+ 1. **제너릭·교체 가능**(회사명 바꿔도 말이 됨) — R2·R6로 1차 차단, 비종속 판정은 AI 위임.
89
+ 2. **증거 없는 자기서술**(빈 형용사·종결구문 슬롭, 동의어 우회) — R3 사전 + R8 비율로 이중 방어, 사전 불완전성 명시.
90
+ 3. **규모를 성과로 위장**('100억 담당') — R4·R8이 전후 델타를 요구해 단순 숫자·규모를 거른다.
91
+ 4. **허위 수치 발명**(정량화 압박의 부작용) — R5가 저장 데이터 교차검증.
92
+ 5. **로케일 오적용**(영문 4역할·400단어 규범을 한국 문항형에 강제) — R1·R9가 locale 분기.
93
+ 6. **신입/약점 문항을 일괄 fail** — R4를 약점 문항·신입 경로에서 면제.
94
+
95
+ ## 4. 출처 (Provenance)
96
+
97
+ 신뢰도 등급: **[1차] 대학 커리어센터·공식 기관 / [2차] 커리어 매체·전문 블로그 / [참고] 커뮤니티·기업 블로그(일화적, 인과 주장 약함)**.
98
+
99
+ - **[1차] Harvard FAS — Mignone Center for Career Success** — 직무 직결 1~2개 경험 집중, 특정 수신자 지정, 공고 핵심 요구 연결 · https://careerservices.fas.harvard.edu/resources/harvard-college-guide-to-resumes-cover-letters/
100
+ - **[1차] Georgetown Cawley Career Education Center** — 4문단 구조(훅/자격/회사적합/클로징)와 적합성 1~3문장 · https://careercenter.georgetown.edu/major-career-guides/resumes-cover-letters/cover-letters/
101
+ - **[1차] Princeton Center for Career Development (2019 PDF)** — 문단별 역할 분리, 구체적 사례 vs 일반 진술 · https://careerdevelopment.princeton.edu/sites/g/files/toruqf1041/files/documents/cover_letter_guide_2019.pdf
102
+ - **[1차] University of Cincinnati — Standout Cover Letter Guide (2024)** — 제너릭 도입 금지, 훅 구성, 영문 분량 3/4~1페이지 · https://www.uc.edu/news/articles/2024/11/standout-cover-letter-guide.html
103
+ - **[1차] University of Maryland — Cover Letter Resources** — 회사 미션·가치 리서치 후 본인 경험과 정렬 · https://careers.umd.edu/find-jobs-internships/resumes-cover-letters/cover-letter-resources
104
+ - **[1차] Yale Office of Career Strategy — Cover Letter Guidance** — 공고 정독, 채용담당자 니즈 대응, 전이 가능 스킬(공식 OCS 자료로 인용 권장; studocu 비공식본 대체) · https://ocs.yale.edu/
105
+ - **[1차/기조] NCS 국가직무능력표준 — 블라인드/공정채용 가이드** — 직무무관 개인정보(나이·성별·사진·가족) 배제 기조 (R11 근거) · https://www.ncs.go.kr/
106
+ - **[2차] LiveCareer / CareerAddict / 4 Corner Resources — Cover Letter Mistakes** — 빈 형용사·클리셰 금지, 정량화, 이력서 반복 금지, 분량 · https://www.livecareer.com/resources/cover-letters/basics/cover-letter-mistakes
107
+ - **[2차] Harvard career experts via CNBC** — 'To whom it may concern' 금지·실명 지정(영문 한정) · https://www.cnbc.com/2019/07/23/example-of-the-perfect-cover-letter-according-to-harvard-career-experts.html
108
+ - **[2차] Scale.jobs — Keyword Mistakes in Cover Letters** — 키워드 스터핑 역효과, 키워드는 증거 문장 안에 · https://scale.jobs/blog/common-mistakes-when-using-keywords-in-cover-letters
109
+ - **[참고] Linkareer 두괄식 / 매거진한경 KKK-STAR / 대웅 STAR** — 한국 자소서 두괄식·STAR·정량 지표(일반론으로 유효하나 '합격 패턴' 인과 주장은 일화적) · https://community.linkareer.com/employment_data/4896233
110
+ - **[데이터 사실] CareerMate 코드** — `get_application_context`의 `job.requirements`/`job.keywords`는 optional 자유텍스트 배열(랭킹 없음) · packages/shared/src/schemas.ts:282-283, packages/core/src/context.ts:32-60 (R10 skip 규칙 근거)
111
+
112
+ ## 5. Phase B 힌트 (아키텍처로 연결)
113
+
114
+ - **MCP 도구 아이디어:**
115
+ - `get_cover_letter_playbook(locale?, mode='draft'|'review', question_type?)` — 연결 AI에게 (1) locale별 구조 템플릿(영문 4역할 / ko 문항형), (2) doList/dontList, (3) 금지 형용사·종결구문·도입 사전(ko/en), (4) 루브릭을 머신체크 가능한 형태로 serve. `question_type`(지원동기/성장과정/약점·실패/협업 등)에 따라 약점 문항은 R4 면제 등 **문항별 루브릭 변형**을 반환.
116
+ - `lint_cover_letter(text, job_id?, locale, count_mode?)` — 저장 없이 루브릭을 실제 카운트하는 **LLM-free 정적 검사기**. `regex/count/ratio` 항목만 자동 채점하고 `ai-judge` 항목은 'AI 위임' 상태로 표시. resume/job 컨텍스트는 서버가 get_resumes·get_application_context에서 조회(R5 수치 교차검증, R10 키워드 부재 시 N/A). 통과 후 기존 `save_cover_letter_version`에 저장.
117
+ - **데이터 형태 힌트:**
118
+ ```
119
+ playbook: {
120
+ locale: 'ko'|'en',
121
+ structure: [{ role|questionType, purpose, openingPatternBan:[regex], lengthBudget:{min,max,countMode}, example }],
122
+ bannedAdjectives: { ko:[], en:[] },
123
+ bannedClosers: { ko:[] }, // 종결구문 슬롭
124
+ genericOpenerPatterns: [regex],
125
+ blindGuardrails: [regex], // R11
126
+ rubric: [{ id, check, passBar, severity:'critical'|'major'|'minor',
127
+ measure:{ type:'regex'|'count'|'ratio'|'ai-judge', pattern?, threshold?, llmFree:boolean } }]
128
+ }
129
+ lint 입력: { text, jobId?, locale, countMode:'with_space'|'no_space'|'byte' }
130
+ lint 출력: {
131
+ checks:[{ id, type, llmFree, value, passBar, pass:boolean|'delegated', hits:[{span,snippet}] }],
132
+ score, overallPass, criticalFailures:[id], delegatedToAI:[id] // ai-judge 항목
133
+ }
134
+ ```
135
+ 핵심: 모든 `regex/count/ratio` 측정은 숫자/존재/비율이라 LLM 없이 계산 가능하고, `ai-judge` 항목(R1·R6 비종속판정·R8·R10 증거동반)은 **'LLM-free'라고 광고하지 않고** 연결 AI에 명시적으로 위임한다 — summary의 'even a regex-level check can verify' 과장을 제거한 정직한 분리.