careermate 0.0.1
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.
- package/AGENTS.md +33 -0
- package/INSTALL.md +230 -0
- package/LICENSE +21 -0
- package/README.md +532 -0
- package/THIRD_PARTY_NOTICES.md +57 -0
- package/bin/careermate.mjs +77 -0
- package/dist/career-os/README.md +78 -0
- package/dist/career-os/eop/cover-letter.md +46 -0
- package/dist/career-os/eop/fit-analysis.md +48 -0
- package/dist/career-os/eop/interview-prep.md +39 -0
- package/dist/career-os/eop/job-analysis.md +42 -0
- package/dist/career-os/eop/profile-extraction.md +37 -0
- package/dist/career-os/knowledge/ats.md +131 -0
- package/dist/career-os/knowledge/company-research.md +137 -0
- package/dist/career-os/knowledge/cover-letter.md +135 -0
- package/dist/career-os/knowledge/fit-matching.md +121 -0
- package/dist/career-os/knowledge/human-writing.md +118 -0
- package/dist/career-os/knowledge/interview-behavioral.md +132 -0
- package/dist/career-os/knowledge/interview-technical.md +126 -0
- package/dist/career-os/knowledge/linkedin-profile.md +152 -0
- package/dist/career-os/knowledge/networking-referrals.md +166 -0
- package/dist/career-os/knowledge/offer-evaluation-decision.md +121 -0
- package/dist/career-os/knowledge/onboarding-first-90-days.md +126 -0
- package/dist/career-os/knowledge/portfolio.md +121 -0
- package/dist/career-os/knowledge/recruiter-screen.md +105 -0
- package/dist/career-os/knowledge/rejection-triage-iteration.md +115 -0
- package/dist/career-os/knowledge/resume.md +123 -0
- package/dist/career-os/knowledge/salary-negotiation.md +123 -0
- package/dist/career-os/knowledge/verifiers/ats-compat.md +64 -0
- package/dist/career-os/knowledge/verifiers/consistency.md +61 -0
- package/dist/career-os/knowledge/verifiers/human-voice.md +82 -0
- package/dist/career-os/knowledge/verifiers/recency-staleness.md +72 -0
- package/dist/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
- package/dist/career-os/knowledge/verifiers/truthfulness.md +67 -0
- package/dist/doctor.mjs +79094 -0
- package/dist/mcp.mjs +96108 -0
- package/dist/migrate.mjs +4735 -0
- package/dist/pdf.worker.min.mjs +28 -0
- package/dist/public/app.js +150 -0
- package/dist/public/fonts/PretendardVariable.woff2 +0 -0
- package/dist/public/icon-180.png +0 -0
- package/dist/public/index.html +52 -0
- package/dist/public/lib.js +394 -0
- package/dist/public/pages/applications.js +107 -0
- package/dist/public/pages/documents.js +467 -0
- package/dist/public/pages/home.js +261 -0
- package/dist/public/pages/interview.js +227 -0
- package/dist/public/pages/jobs.js +493 -0
- package/dist/public/pages/profile.js +556 -0
- package/dist/public/pages/settings.js +240 -0
- package/dist/public/styles.css +498 -0
- package/dist/site/analytics.js +97 -0
- package/dist/site/favicon.svg +1 -0
- package/dist/site/fonts/PretendardVariable.woff2 +0 -0
- package/dist/site/icon-180.png +0 -0
- package/dist/site/icon-512.png +0 -0
- package/dist/site/index.html +598 -0
- package/dist/site/landing.js +54 -0
- package/dist/site/llms-install.txt +217 -0
- package/dist/site/robots.txt +4 -0
- package/dist/site/sitemap.xml +21 -0
- package/dist/site/start.html +326 -0
- package/dist/site/style.css +550 -0
- package/dist/site/vercel.json +20 -0
- package/dist/web.mjs +46852 -0
- package/docs/FAQ.md +101 -0
- package/docs/MCP_TOOLS.md +311 -0
- package/docs/README.md +28 -0
- package/docs/START_WORKFLOW.md +137 -0
- package/docs/SUPPORTED_AI_APPS.md +112 -0
- package/docs/WORKFLOWS.md +202 -0
- package/docs/career-os/README.md +78 -0
- package/docs/career-os/eop/cover-letter.md +46 -0
- package/docs/career-os/eop/fit-analysis.md +48 -0
- package/docs/career-os/eop/interview-prep.md +39 -0
- package/docs/career-os/eop/job-analysis.md +42 -0
- package/docs/career-os/eop/profile-extraction.md +37 -0
- package/docs/career-os/knowledge/ats.md +131 -0
- package/docs/career-os/knowledge/company-research.md +137 -0
- package/docs/career-os/knowledge/cover-letter.md +135 -0
- package/docs/career-os/knowledge/fit-matching.md +121 -0
- package/docs/career-os/knowledge/human-writing.md +118 -0
- package/docs/career-os/knowledge/interview-behavioral.md +132 -0
- package/docs/career-os/knowledge/interview-technical.md +126 -0
- package/docs/career-os/knowledge/linkedin-profile.md +152 -0
- package/docs/career-os/knowledge/networking-referrals.md +166 -0
- package/docs/career-os/knowledge/offer-evaluation-decision.md +121 -0
- package/docs/career-os/knowledge/onboarding-first-90-days.md +126 -0
- package/docs/career-os/knowledge/portfolio.md +121 -0
- package/docs/career-os/knowledge/recruiter-screen.md +105 -0
- package/docs/career-os/knowledge/rejection-triage-iteration.md +115 -0
- package/docs/career-os/knowledge/resume.md +123 -0
- package/docs/career-os/knowledge/salary-negotiation.md +123 -0
- package/docs/career-os/knowledge/verifiers/ats-compat.md +64 -0
- package/docs/career-os/knowledge/verifiers/consistency.md +61 -0
- package/docs/career-os/knowledge/verifiers/human-voice.md +82 -0
- package/docs/career-os/knowledge/verifiers/recency-staleness.md +72 -0
- package/docs/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
- package/docs/career-os/knowledge/verifiers/truthfulness.md +67 -0
- package/package.json +89 -0
- package/packages/core/src/context.ts +74 -0
- package/packages/core/src/index.ts +8 -0
- package/packages/core/src/onboarding.ts +81 -0
- package/packages/core/src/services.ts +187 -0
- package/packages/core/src/summary.ts +104 -0
- package/packages/db/src/connection.ts +76 -0
- package/packages/db/src/index.ts +23 -0
- package/packages/db/src/paths.ts +52 -0
- package/packages/db/src/repositories.ts +891 -0
- package/packages/db/src/runtime.ts +58 -0
- package/packages/db/src/schema.ts +307 -0
- package/packages/exporters/src/html.ts +110 -0
- package/packages/exporters/src/index.ts +364 -0
- package/packages/exporters/src/markdown.ts +178 -0
- package/packages/knowledge/src/index.ts +168 -0
- package/packages/mcp-tools/src/bridge.ts +106 -0
- package/packages/mcp-tools/src/index.ts +17 -0
- package/packages/mcp-tools/src/result.ts +49 -0
- package/packages/mcp-tools/src/tools.ts +747 -0
- package/packages/mcp-tools/src/update.ts +330 -0
- package/packages/parsers/src/documents.ts +533 -0
- package/packages/parsers/src/html.ts +86 -0
- package/packages/parsers/src/index.ts +231 -0
- package/packages/parsers/src/keywords.ts +151 -0
- package/packages/prompts/src/humanize.ts +59 -0
- package/packages/prompts/src/index.ts +82 -0
- package/packages/prompts/src/install.ts +43 -0
- package/packages/prompts/src/onboarding.ts +35 -0
- package/packages/prompts/src/system.ts +57 -0
- package/packages/shared/src/build-info.ts +22 -0
- package/packages/shared/src/enums.ts +142 -0
- package/packages/shared/src/index.ts +19 -0
- package/packages/shared/src/schemas.ts +453 -0
- package/packages/workflows/src/definitions.ts +109 -0
- package/packages/workflows/src/index.ts +39 -0
- package/scripts/init.ts +371 -0
- package/tsconfig.json +32 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# 거절·피드백 루프 / Rejection Triage & Iteration — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
CareerMate 8단계 상태의 `rejected`를 "죽은 종착점"이 아니라 다음 지원을 개선하는 학습 신호로 환류시키는 도메인이다. 핵심은 (1) 탈락이 어느 게이트에서 났는지 단계 진단, (2) 여러 application의 `rejected` 기록을 가로질러 반복 패턴 감지, (3) 단계별로 차별화된 개선 액션 도출, (4) 정중하고 구조화된 피드백 요청(글로벌·경력 수시채용 한정), (5) 단계·변화증거 기반 재지원 타이밍, (6) 거절 누적에 따른 회복탄력성 관리다. 인접 도메인 `salary-negotiation`은 오퍼 시점의 협상 전술이고, 이 도메인은 그 전후의 "왜 게이트를 못 넘었나 진단 + 다음 사이클 개선"이다.
|
|
8
|
+
|
|
9
|
+
**중요(스키마 정직성):** 현재 `applications` 테이블은 평면 `status` + 자유텍스트 `notes`뿐이며, 탈락 단계(`rejection_stage`)나 받은 피드백을 담을 **전용 필드가 없다**(`docs/dev/DATA_MODEL.md` L223-237, `packages/shared/src/enums.ts`). 따라서 Phase A에서 단계 분류는 `notes`에 **합의된 접두 패턴**(예: `[stage:interview]`)으로 남기는 근사이고, 전 rejected 집계는 외부 AI의 **수동 집계**다(`get_application_context`는 최근 N건 cap + 동일 회사/직무 history만 반환하므로 자동 cross-tab을 못 준다). 전용 필드·집계 도구는 §5 Phase B에서 제안한다.
|
|
10
|
+
|
|
11
|
+
## 2. 플레이북
|
|
12
|
+
|
|
13
|
+
### 원칙
|
|
14
|
+
|
|
15
|
+
- **탈락을 진단·저장하기 전에 '탈락 단계'를 먼저 분류하라** — 게이트마다 실패 원인과 처방이 정반대다(서류=타겟팅/키워드, 면접=전달/적합도). 단계 enum(권장): `pre_screen`(서류/ATS) · `recruiter_screen`(리크루터 통화) · `aptitude_test`(인적성·코딩테스트, 한국 대기업에서 독립 게이트) · `assignment`(과제) · `interview`(면접) · `final_fit`(최종 fit·연봉·레퍼런스/평판조회) · `ghosted_pre`(서류 직후 무응답) · `ghosted_post`(최종 단계 후 무응답). 단, "어느 게이트였나"의 판정 자체는 사용자 진술/AI 추론이 필요한 **[ai] 작업**이지 토큰 grep으로 풀리지 않는다. _(출처: Pin Funnel Benchmarks; CareerMate DATA_MODEL)_
|
|
16
|
+
- **단일 탈락에서 결론을 내지 마라. '구조적'은 비율로 판정하라** — 절대 건수 임계(n=3)는 표본이 희박한 한국 신입/주니어에서 false positive가 많고(면접→오퍼 전환이 낮으면 3연속 면접탈락은 우연으로도 흔하다), 단계가 8개로 쪼개지면 셀당 표본이 더 얕다. 따라서 "진단 가능한 탈락 중 동일 단계가 **≥60%이고 절대건수 ≥3**"일 때만 구조적 신호로 보고, 그 미만은 "신호일 뿐 단정 금지"로 약화하라. 후반 단계(면접)의 산발적 탈락은 정상 분산이다. _(출처: Interview Guys Rejection Recovery; Pin Funnel)_
|
|
17
|
+
- **'본인이 못 고치는 탈락'을 1급 카테고리로 분리하라** — 모든 처방을 "내가 무엇을 고칠까"로 몰면 불필요한 자기교정·번아웃을 부른다. 구조적 외부요인 = ① 시장/포지션 미스매치(over/under-qualified·연봉밴드·비자/위치), ② 내정·내부추천(한국 경력 수시채용에서 공고가 형식인 경우), ③ 포지션 클로즈/예산취소, ④ 레퍼런스/평판조회 탈락(전 직장 관계 이슈). 이 넷은 자소서·면접 개선으로 안 풀리므로 "넘길 거절"로 표시한다. _(출처: 그리팅 HR 블로그; 블라인드 실무자 스레드)_
|
|
18
|
+
- **피드백 요청은 짧고 구체적이고 비도전적으로** — (a) 통보 후 24시간~1주, (b) 6문장 이하, (c) 일반론 대신 구체 질문 2~3개, (d) 결정 번복 시도 없이. 긴 메일은 회신율을 떨어뜨리고, 구체 질문은 답변 구조를 미리 제공한다. _(출처: Arcadia Career Launchpad; CareerSidekick)_
|
|
19
|
+
- **한국 공채에는 피드백 요청을 권하지 말고 자가진단으로 분기하라** — 공채는 합격자에게만 연락하고 일괄/무통보 탈락이 표준이라 개별 환류가 구조적으로 어렵다. 글로벌 조언을 그대로 적용하면 무응답 좌절만 키운다. 대신 인접 공고 `requirements` 역추적 + `fit_analysis.missing_keywords`/`gaps`로 갭을 자가추정하라. 피드백 요청은 '리크루터가 개인적으로 연락한 경력·수시·외국계'로 한정한다. _(출처: 그리팅 HR; 프라임커리어)_
|
|
20
|
+
- **재지원은 '시간 AND 변화 증거' 조건으로** — 시간 경과만으로는 같은 결과가 나온다. 실제 레버는 포지션 재공고·조직변화·새 hiring manager·본인의 가시적 변화(승진/자격증/프로젝트)다. 쿨다운 가이드(수시채용 기준): 서류만 탈락+다른 포지션=즉시 / 면접까지=3~6개월 / 동일 포지션=6~12개월. **단 한국 정기공채는 '다음 회차(상·하반기, 약 6개월 사이클)'가 자연 쿨다운**이므로 월수 대신 다음 공채 회차로 안내한다. 재지원 자소서엔 '지난 지원 이후 무엇이 달라졌는지'를 명시한다. _(출처: Indeed Reapply Guide; 프라임커리어)_
|
|
21
|
+
- **재지원 자소서는 '유지할 강점'과 '보완할 증거'를 분리해 차등 수정하라** — 무수정 재사용은 같은 탈락을 반복하고, 전면 재작성은 잘 맞던 부분까지 버린다. 추상 형용사를 행동+수치로 치환하는 것이 서류 단계의 핵심 레버다('꼼꼼함' → '출고 전 2회 교차검증, 6개월 오배송 0건'). 사실·수치·고유명사는 보존한다. _(출처: 프라임커리어/잡스미스르; Arcadia)_
|
|
22
|
+
- **거절 누적을 정서 신호로 게이팅하되 진단 과잉을 동시에 막아라** — 단기(30일) 내 rejected ≥5건이면 회복탄력성 모드: 'What's wrong with me'→'What can I learn' 인지 재구성, 거절 1건당 자기돌봄 1회, base rate 상기(성공적 구직도 평균 5~10 거절 포함). **동시에 과잉 진단을 fail 신호로 둔다** — 무응답·공채 일괄탈락까지 모두 깊게 파면 번아웃이 가속된다. _(출처: Interview Guys Rejection Fatigue; Psychology Today)_
|
|
23
|
+
- **진단을 '느낌'이 아니라 기존 데이터로 정량 앵커하라** — rejected 건들의 단계 분포, 각 건의 직전 `fit_analysis.score`/`missing_keywords`/`gaps`(주의: 공고당 fit_analysis는 1:N, `getByJob`은 `updated_at DESC` **최신 1건**을 돌려줌), 사용한 resume/cover_letter 버전을 묶어 표를 만들고 패턴을 읽어라. _(출처: CareerMate DATA_MODEL fit_analyses/applications)_
|
|
24
|
+
|
|
25
|
+
### Do
|
|
26
|
+
|
|
27
|
+
- 탈락 저장 시 단계를 먼저 분류하고, 전용 필드가 없으므로 `notes`에 합의된 접두 패턴(예: `[stage:interview] 사유=... 받은피드백=...`)으로 구조화해 남긴다.
|
|
28
|
+
- 과거 rejected를 진단할 땐 `get_application_context`의 `recent_applications`가 **기본 10건 cap**임을 인지하고, 지원이 11건 이상이면 누락 가능성을 사용자에게 고지한 뒤 수동 집계로 단계 분포표를 만든다(또는 §5의 `get_rejection_patterns` 선행).
|
|
29
|
+
- 구조적 결론은 "동일 단계 ≥60% 비율 + 절대건수 ≥3"일 때만 내리고, 그 미만은 "아직 신호 수준"으로 말한다.
|
|
30
|
+
- '본인이 못 고치는 탈락'(미스매치·내정·포지션 클로즈·레퍼런스)을 먼저 배제하고, 자기교정 액션은 그 다음에 제시한다.
|
|
31
|
+
- 피드백 요청 메일은 6문장 이하·구체 질문 2~3개·결정 비도전·1주 내(글로벌/경력/외국계 한정)로 작성한다.
|
|
32
|
+
- 한국 공채는 메일 대신 인접 공고 `requirements` 역추적 + `missing_keywords`/`gaps` 자가진단으로 다음 자소서 액션을 만든다.
|
|
33
|
+
- 재지원은 단계별 쿨다운 + '가시적 변화 증거'를 함께 묻고, 한국 정기공채는 다음 공채 회차로 안내한다.
|
|
34
|
+
- 재지원 자소서는 강점/증거를 분리해 차등 수정하고 추상 형용사를 행동+수치로 치환한다(사실·수치·고유명사 보존).
|
|
35
|
+
- 면접 단계 탈락이면 해당 job의 `interview_prep.notes`(면접 후기, 공고당 1건)를 읽어 막힌 질문을 STAR 갭으로 환원하고 다음 `prepare_interview`에 반영한다.
|
|
36
|
+
- 단기 거절 ≥5건이면 회복탄력성 모드 + 실행 액션 ≥1을 함께 준다(위로만 금지). 무응답·공채 일괄탈락은 깊이 진단하지 않는다.
|
|
37
|
+
- 도출한 개선 액션을 다음 도구 입력으로 명시 연결한다(예: '정량화 부족' → 다음 `save_cover_letter_version` 작성 지침).
|
|
38
|
+
|
|
39
|
+
### Don't
|
|
40
|
+
|
|
41
|
+
- 단 1건의 거절(특히 면접)에서 '내 이력서/역량이 문제'라고 단정한다.
|
|
42
|
+
- 탈락 단계를 묻지/분류하지 않고 일반론적 '더 노력하세요'를 준다.
|
|
43
|
+
- 절대 건수 3건만으로 '구조적'이라 단정한다(비율·표본 무시).
|
|
44
|
+
- 모든 거절을 동일 깊이로 진단해 사용자를 거절 피로로 몬다(무응답·공채 일괄탈락까지 파헤침).
|
|
45
|
+
- 피드백 요청 메일에서 결정을 번복하려 하거나, 길고 감정적으로 쓰거나, 답변을 강요한다.
|
|
46
|
+
- 한국 공채 지원자에게 '리크루터에게 피드백 요청하세요'를 그대로 권한다.
|
|
47
|
+
- 재지원 자소서를 이전 버전 그대로 재사용하거나, 반대로 잘 맞던 부분까지 전면 재작성한다.
|
|
48
|
+
- 같은 회사 동일 포지션에 쿨다운/변화 증거 없이 즉시 재지원하게 둔다.
|
|
49
|
+
- 미스매치·내정·레퍼런스 탈락을 '본인 개선'으로 처방해 헛수고를 시킨다.
|
|
50
|
+
- `fit_analysis`의 `score`/`gaps`/`missing_keywords` 같은 기존 데이터를 안 보고 추측으로 진단한다.
|
|
51
|
+
- STAR/자소서에서 사실·수치·회사명을 '개선'이라는 명목으로 바꿔치기·과장한다.
|
|
52
|
+
|
|
53
|
+
### 워크드 예시 (Before → After)
|
|
54
|
+
|
|
55
|
+
1. **Before:** 사용자 '또 떨어졌어요.' → AI '괜찮아요, 다음엔 잘 될 거예요. 이력서를 좀 더 다듬어 보면 어떨까요?'
|
|
56
|
+
**After:** AI가 먼저 단계 분류 — '어느 단계에서 마무리됐나요 — 서류, 인적성/리크루터 통화, 과제, 면접, 최종?' 사용자가 '면접 2차'라 답하면, 과거 rejected 4건을 수동 집계(recent_applications 10건 cap 고지)해 분포표 제시: 서류 통과 4/4, 면접 탈락 3/4(=동일 단계 75%, 절대 3건 → 구조적 신호). '서류는 잘 통과하시니 이력서 문제가 아니라 면접 전달이 반복 병목입니다.' 미스매치/내정 가능성 1차 배제 후, 해당 job의 `interview_prep.notes`에서 '역량검증 질문 구체 사례 약함'을 STAR 갭으로 환원, 다음 `prepare_interview` 액션 3개 제시.
|
|
57
|
+
**왜 더 나은가:** 단일 위로 대신 단계 진단 → 비율(75%≥60%)+절대건수(≥3) → 데이터 앵커(4/4 통과) → 정확한 병목 → 실행 액션. '이력서 다듬기'라는 잘못된 처방(서류는 멀쩡)을 피한다.
|
|
58
|
+
|
|
59
|
+
2. **Before:** 피드백 요청 메일(글로벌 경력직) — '안녕하세요, 불합격 통보 받았는데 정말 이해가 안 됩니다. 제가 가장 적합했다고 생각하는데 어떤 점이 부족했는지 전부 알려주시고, 재고해 주실 수 있는지도 부탁드립니다.' (12문장, 결정 재고 요청)
|
|
60
|
+
**After:** '안녕하세요 OOO님, 이번 [직무] 채용 결과 잘 받았습니다. 기회에 감사드립니다. 향후 지원에 참고하고자 두 가지만 여쭙고 싶습니다: (1) 제 [데이터 파이프라인] 경험이 이 역할 기대 수준에 비해 부족했던 부분이 있었을까요? (2) 면접에서 더 보완하면 좋을 한 가지를 꼽으신다면요? 짧게라도 의견 주시면 큰 도움이 되겠습니다. 감사합니다.' (6문장, 구체 질문 2개, 결정 비도전, 통보 후 3일 내)
|
|
61
|
+
**왜 더 나은가:** 짧아 회신율↑, 답변 구조를 미리 주는 구체 질문 2개, 결정 비도전으로 관계·재지원 기회 보존. 한국 공채라면 이 메일 자체를 보내지 않고 자가진단 경로로 분기.
|
|
62
|
+
|
|
63
|
+
3. **Before:** 재지원 자소서(한국, 서류 탈락 후) — 이전 버전 그대로 제출하며 '저는 꼼꼼하고 책임감이 강한 인재입니다.'
|
|
64
|
+
**After:** 유지할 강점(직무 적합 경험)은 보존하되 `fit_analysis.missing_keywords`의 '데이터 기반 의사결정'을 반영해 추상 형용사를 증거로 치환: '출고 전 SKU 2회 교차검증 프로세스를 도입해 6개월간 오배송 0건을 유지했습니다(직전 분기 월 평균 4건).' 서두에 '지난 상반기 지원 이후 OOO 역량을 보강했다'를 1줄 명시.
|
|
65
|
+
**왜 더 나은가:** 무수정 재사용(탈락 반복)과 전면 재작성(잘 맞던 부분 손실)을 모두 피한다. 추상→행동+수치는 서류 단계 핵심 레버이고, 수치는 날조 없이 실제 성과를 정량화한 것. 재지원 인지 문구로 '성장'을 신호한다.
|
|
66
|
+
|
|
67
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
68
|
+
|
|
69
|
+
| ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게; 의미판단 필요시 [ai]/H 표기) |
|
|
70
|
+
|----|-----------|-----------|--------------------------------|
|
|
71
|
+
| R1 | 탈락 진단 산출물에 단계가 enum 중 하나로 분류되어 있는가 | 1개 단계 토큰 존재=합격, 미분류/일반론=불합격 | det로는 `pre_screen\|recruiter_screen\|aptitude_test\|assignment\|interview\|final_fit\|ghosted_pre\|ghosted_post` 토큰 존재 여부만 셀 수 있음. **단계 분류의 정확성(어느 게이트였나)은 [ai]/H** — 전용 필드 부재로 notes free-text 토큰 매칭은 false positive 가능하므로 토큰 존재는 보조 신호로만 사용 |
|
|
72
|
+
| R2 | 구조적 결론이 비율+절대건수로 근거되었는가 | '구조적/반복/패턴' 표현 시 동일 단계 비율≥60% AND 절대건수≥3 명시=합격; 단정만=불합격 | det/pattern: '구조적\|반복\|패턴' 인근에 백분율(≥60%) 토큰과 정수 카운트(≥3)가 함께 있는지 정규식 검사. 둘 중 하나라도 없이 단정하면 fail |
|
|
73
|
+
| R3 | '본인이 못 고치는 탈락'(미스매치/내정/포지션클로즈/레퍼런스)을 배제·표시했는가 | 자기교정 액션 전에 외부요인 1개 이상 검토 언급=합격 | det/pattern: '미스매치\|내정\|내부추천\|포지션 클로즈\|예산\|레퍼런스\|평판조회' 중 1개 이상 토큰 존재 여부 |
|
|
74
|
+
| R4 | 피드백 요청 메일이 (a)6문장 이하 (b)구체 질문 2~3개 (c)결정 번복 요청 없음인가 | 세 조건 모두 충족=합격 | det(한국어 규칙): 문장 수는 종결부호(`.`/`?`/`다.`/줄바꿈 + 번호목록 `1)` `2)`)를 합산해 카운트(영어식 마침표 휴리스틱 단독 금지); 물음표 2~3개; '재고\|다시 검토\|번복\|reconsider' 부재(det). 정중함은 [ai]/H |
|
|
75
|
+
| R5 | 한국 공채 맥락에서 피드백 요청 비권장+자가진단 대안을 제시했는가 | 공채 신호 시 피드백요청 비권장 AND 자가진단 대안=합격 | det/pattern: 입력에 '공채\|공개채용\|블라인드\|인적성' 신호가 있으면 산출물에 '자가진단\|요건 역추적\|missing_keywords' 류 대안 존재 여부 |
|
|
76
|
+
| R6 | 재지원 타이밍이 단계별 차등 + '변화 증거' 조건을 담았는가 | 차등 구간 ≥2개 AND 변화증거 언급=합격; 단일 일률 기간=불합격 | det/pattern: 월 범위 토큰(3~6, 6~12 등) ≥2개 또는 '다음 공채 회차'; 그리고 '변화\|보강\|승진\|자격증\|재공고' 중 1개 토큰 존재 |
|
|
77
|
+
| R7 | 진단이 기존 데이터 필드를 인용해 정량 앵커되었는가 | 실제 데이터 필드 1개 이상 인용=합격, 순수 추측=불합격 | det: `score\|gaps\|missing_keywords\|단계 분포\|버전` 중 1개 이상 구체 참조 존재 여부 |
|
|
78
|
+
| R8 | 회복탄력성이 임계(단기 5건)에서만 켜지고 실행 액션을 동반했는가 | 거절≥5 시 base-rate 상기+자기돌봄+액션≥1=합격; 위로만=불합격 | det/pattern: 거절 카운트≥5일 때만 '정상\|base rate\|평균 5~10' 류 + 동사형 액션 권고 ≥1. **단 30일 윈도우 카운트는 status 변경 timestamp가 `updated_at` 1개뿐이라 불안정 → 카운트 자체는 H 보조** |
|
|
79
|
+
| R9 | 과잉 진단 가드레일 — 동일 응답에서 무응답/공채 일괄탈락까지 모두 깊게 진단하지 않았는가 | 진단 가치 낮은 건을 '넘김'으로 표시=합격; 전건 심층진단=불합격 | det/pattern: 'ghosted\|무응답\|일괄' 건에 대해 '진단 가치 낮음\|깊이 분석하지 않음' 류 표시 존재 여부(음성 체크) |
|
|
80
|
+
| R10 | 재지원/STAR에서 사실·수치·고유명사 보존 + 날조 0 | 기존 데이터 대비 신규 수치/회사명 날조 0건=합격 | [ai]/H: 기존 experiences/projects/cover_letter_versions와 대조해 새 수치·고유명사 출처 유무를 의미 판단 |
|
|
81
|
+
| R11 | 개선 액션이 다음 도구 산출물 입력으로 명시 연결됐는가 | 액션→다음 도구/단계 연결 1개 이상=합격 | det: `save_cover_letter_version\|prepare_interview\|save_fit_analysis` 도구명 또는 '다음 지원 시 ~를 반영' 류 연결 문장 존재 |
|
|
82
|
+
|
|
83
|
+
**주요 실패 모드:**
|
|
84
|
+
- 단계 토큰이 `notes` free-text에 우연히 등장(예: 무관한 "interview" 언급)해 R1 det가 false positive — 그래서 R1 분류 정확성은 [ai]/H로 강등.
|
|
85
|
+
- 절대건수 3만 보고 '구조적' 단정(R2 비율 누락) → 표본 희박 환경에서 과잉 자기교정.
|
|
86
|
+
- 미스매치·내정·레퍼런스 탈락을 자기개선으로 처방(R3 미배제) → 헛수고·번아웃.
|
|
87
|
+
- 한국 공채에 글로벌 피드백 메일을 그대로 권함(R5) → 무응답 좌절.
|
|
88
|
+
- 30일 5건 카운트를 det로 과신(R8) → status timestamp 단일성으로 카운트가 흔들림.
|
|
89
|
+
- 위로만 하고 액션 없음(R8) 또는 모든 건 심층진단(R9) → 양극단 실패.
|
|
90
|
+
|
|
91
|
+
## 4. 출처 (Provenance)
|
|
92
|
+
|
|
93
|
+
- **Pin — Recruitment Funnel Benchmarks 2026** — 단계별 전환율 벤치마크(미국/글로벌)와 '정상 분산' 정량 감각. **단, 단일 벤더(2차) 단일 출처이고 직군·연차·국가에 따라 수배 흔들리며 한국 공채 funnel(서류→인적성→실무→임원)과 구조가 다르므로 절대 퍼센트를 base rate로 박제하지 말고 '본인 funnel 단계 간 상대 낙폭'으로 사용.** 한국 전환율 정량 앵커는 공개 데이터 부재. · https://www.pin.com/blog/recruitment-funnel-benchmarks/
|
|
94
|
+
- **Arcadia University Career Launchpad — Ask for Feedback After Rejection** — 피드백 요청 메일 구조·타이밍·구체 질문·금기. 대학 커리어센터(1차 성격). · https://careerlaunchpad.arcadia.edu/blog/2024/10/30/how-to-ask-for-feedback-after-job-rejection-with-examples/
|
|
95
|
+
- **CareerSidekick — Asking for Feedback: Do's and Don'ts** — 짧게·구체질문·결정 비도전·1주 내. 2차(실무 코칭). · https://careersidekick.com/asking-feedback-job-rejection/
|
|
96
|
+
- **Indeed Career Guide — How To Reapply After Rejection** — 재지원 쿨다운(면접 3~6개월, 일반 6~12개월) 및 갱신 원칙. 2차(벤더). 한국 정기공채에는 '다음 회차' 분기 적용. · https://www.indeed.com/career-advice/finding-a-job/reapply-for-a-job
|
|
97
|
+
- **The Interview Guys — Rejection Recovery & Rejection Fatigue** — 거절 피로 정의·인지 재구성·base rate(평균 5~10 거절 정상). 2차. · https://blog.theinterviewguys.com/coping-with-job-rejection-fatigue/
|
|
98
|
+
- **Psychology Today — Overcome the Pain of Job Rejection** — 인지 재구성·정서 처리·자기돌봄 심리학 근거. 2차(심리). · https://www.psychologytoday.com/us/blog/frazzlebrain/202303/how-to-overcome-the-pain-of-job-rejection-0
|
|
99
|
+
- **프라임커리어 / 잡스미스르 — 재지원 시 바꿀 것·남길 것, 서류 탈락 사유** — 한국 맥락 차등 수정(강점 유지·증거 보완, 추상→구체), 이전 버전 재사용 금지. 2차(한국). · https://prime-career.com/student_article/1405
|
|
100
|
+
- **그리팅/나인하이어 HR 블로그 + 블라인드 실무자 스레드** — 한국 공채가 개별 피드백을 거의 주지 않고 합격자에게만 연락하는 현실(일괄/무통보 표준), 내정·내부추천 가능성 → 로케일 분기 근거. 2차(벤더 HR/커뮤니티). · https://blog.greetinghr.com/for-hr-reject-mail-information/
|
|
101
|
+
- **CareerMate `docs/dev/DATA_MODEL.md` + `packages/shared/src/enums.ts` + `packages/core/src/context.ts` + `packages/db/src/repositories.ts`** — 1차(코드베이스). 확인된 사실: `applications`는 평면 `status`+`notes`만 있고 단계/피드백 전용 필드 없음(L223-237); `rejected`는 `ALLOWED_STATUS_TRANSITIONS`상 draft 포함 7개 상태로 재전이 가능한 **비종착 상태**(enums.ts L74) — 따라서 '평면 종착점' 서술은 부정확하고, 진짜 빠진 건 '탈락 단계/사유의 구조화 저장'뿐; `fit_analyses`는 공고당 1:N이고 `fitRepo.getByJob`은 `ORDER BY updated_at DESC LIMIT 1`로 **최신 1건**을 돌려줌(repositories.ts L652-656); `get_application_context`는 `recent_applications` 기본 10건 cap + 동일 회사/직무 `related_history`만 반환하므로 전 rejected 자동 cross-tab 경로 없음(context.ts L40-55); `interview_preps.notes`='면접 후기/메모' 공고당 1건(L268).
|
|
102
|
+
|
|
103
|
+
> 제거된 무근거 통계: 원본 principles의 '79%는 피드백을 받으면 재지원 의사가 있다'와 '기술직 면접→오퍼 ~7%'(단계 정의 불명, funnel과 결합 시 비현실적)는 sources에 출처 매핑이 없어 삭제했다.
|
|
104
|
+
|
|
105
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
106
|
+
|
|
107
|
+
- **MCP 도구 아이디어:**
|
|
108
|
+
- 신규 쓰기 도구 `save_rejection_review`(job_id에 묶임, UNIQUE): 입력 `{job_id, rejection_stage(enum 8: pre_screen|recruiter_screen|aptitude_test|assignment|interview|final_fit|ghosted_pre|ghosted_post), external_factor?(mismatch|internal_candidate|position_closed|reference_check|none), perceived_reason?, feedback_received?, lessons[]?, improvement_actions[]?, reapply_eligible_after?(YYYY-MM)}`; 저장 후 `activities`에 `type='rejection_reviewed'` 로그. → 이것이 R1을 **진짜 det**로 만든다(전용 enum 필드).
|
|
109
|
+
- 신규 읽기 도구 `get_rejection_patterns`(인자 없음): 모든 `status='rejected'` application을 모아 단계별 카운트 + 각 건의 최신 `fit_analysis.score`/`missing_keywords`/사용 cover_letter 버전을 cross-tab해 `{stage_counts, structural_signal_stage?(비율≥60% AND 카운트≥3인 단계), recurring_missing_keywords[], rejected_in_window_30d}` 반환 → 외부 AI가 LLM 없이 패턴을 읽도록 사전계산 제공(현재 수동 집계·10건 cap 한계 해소).
|
|
110
|
+
- 보조 `get_reapply_timing(job_id)` → 마지막 단계 + external_factor 기반 권장 쿨다운/재지원 가능일(한국 공채면 '다음 회차'). `update_application_status`가 `rejected`로 바뀔 때 `document_passed` 힌트 패턴을 재사용해 'save_rejection_review로 다음 지원에 환류하세요' 힌트 동봉.
|
|
111
|
+
- **데이터 형태 힌트:**
|
|
112
|
+
- 신규 테이블 `rejection_reviews`(job_id UNIQUE FK, stage TEXT enum, external_factor TEXT?, perceived_reason TEXT?, feedback_received TEXT?, lessons TEXT(JSON), improvement_actions TEXT(JSON), reapply_eligible_after TEXT(YYYY-MM)?, created_at/updated_at). 전방향 멱등 마이그레이션 1건(`CREATE TABLE IF NOT EXISTS`).
|
|
113
|
+
- `enums.ts`에 `REJECTION_STAGES`(8개)와 `REJECTION_EXTERNAL_FACTORS` 추가, `ACTIVITY_TYPES`에 `'rejection_reviewed'` 추가, `ENTITY_TYPES`에 `'rejection_review'` 추가.
|
|
114
|
+
- 30일 윈도우 카운트(R8)를 det로 신뢰하려면 status 변경 이력을 별도로 남겨야 함 — 현재는 `updated_at` 1개뿐이고 `activities.application_status_changed`의 summary가 자유텍스트라 카운트가 불안정하다. `rejection_reviews.created_at`을 rejected 진입 시각의 안정 앵커로 사용.
|
|
115
|
+
- `get_application_context`를 확장해 해당 job의 `rejection_review` + 최신 `fit_analysis`를 함께 묶어 반환하면 진단 컨텍스트가 1콜로 완성(단, 전역 rejected 집계는 별도 `get_rejection_patterns`가 담당하도록 역할 분리).
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# 이력서 / Résumé — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
역시간순 구조 위에서 모든 경력 불릿을 **"강한 액션 동사 + 정량화된 임팩트"**로 쓰는 것이 이력서의 핵심이다. Google XYZ 공식과 Harvard·MIT 커리어센터 가이드가 공통으로 요구하는 것은 (1) 직무 나열이 아닌 성과 증명, (2) 측정된 결과, (3) (영문에서) 1인칭 제거, (4) ATS가 파싱 가능한 단순 구조다.
|
|
8
|
+
|
|
9
|
+
CareerMate는 LLM이 없으므로, 연결된 AI가 이 규칙으로 작성하고 아래 루브릭(개수·존재·비율·순서 기반)으로 **결정론적 자가검증**하도록 지식을 serve한다. 단 이 루브릭은 **형식·표면 위생(surface hygiene) 검사**일 뿐이며 — 직무 적합성·서사·도메인 임팩트의 깊이는 패턴으로 잴 수 없으므로 — **"모든 체크 통과 = 합격"이 아니다.** 또한 한국 채용 현실(국문 경력기술서, 사진·생년월일 칸이 고정된 자사 양식, 잡코리아/사람인/원티드/공채 시스템)과 직군·연차별 차이를 명시적으로 분기해 적용한다.
|
|
10
|
+
|
|
11
|
+
## 2. 플레이북
|
|
12
|
+
|
|
13
|
+
### 원칙
|
|
14
|
+
|
|
15
|
+
- **(불릿 = 측정된 성과)** 가능한 한 Google XYZ 공식 *"Accomplished X as measured by Y, by doing Z"*(무엇을 X만큼, Y로 측정되게, Z를 함으로써)를 따라 결과 X + 측정치 Y + 방법 Z를 담는다. 단 **모든 불릿에 Y를 강제하지 않는다** — Bock의 원 권고는 "성과 위주로 쓰라"이지 "전 불릿 측정치 필수"가 아니다. 신입·연구·창작 직군처럼 정량화가 원천적으로 어려운 맥락에서는 규모·범위·전후 비교 같은 정성적 임팩트로 대체한다. _(출처: Google XYZ Formula — Laszlo Bock, *Work Rules!*)_
|
|
16
|
+
- **(액션 동사 선행)** 영문 불릿은 1인칭 대명사 없이 강한 액션 동사로 시작한다(Led, Built, Reduced, Launched). 'Responsible for', 'Worked on', 'Helped with', 'Duties included' 같은 수동·약한 표현을 피한다. 단 한국어 경력기술서에서 **'~을 담당'은 역할 범위를 정직하게 기술하는 정상 표현**이므로 일괄 금지하지 않는다 — 문제는 "담당만 하고 성과가 없을 때"이지 '담당'이라는 단어 자체가 아니다. _(출처: Harvard FAS Career Services; MIT CAPD)_
|
|
17
|
+
- **(정량화)** 결과는 숫자·퍼센트·금액·규모(인원/예산/기간/건수)로 정량화하되, **연도(2024)·버전(v3, Python 3, React 18)·헤더(p95, h1) 같은 "맥락 숫자"는 임팩트가 아니다.** 임팩트는 증감 동사+숫자, %·배수·금액·전후 화살표(→) 같은 결과 신호로 표현한다. 정량화가 불가능하면 정성적 범위(전/후, 대비)라도 명시한다. _(출처: MIT CAPD; Harvard FAS)_
|
|
18
|
+
- **(역시간순·시제 통일)** 각 섹션 안에서 가장 최근 항목을 맨 위에 둔다. 현재 직무는 현재형, 과거 직무는 과거형으로 시제를 통일한다. _(출처: Harvard FAS; MIT CAPD)_
|
|
19
|
+
- **(분량 — 연차/직군별 분기)** 신입·주니어는 1페이지를 권장하지만, **2026년 기준 테크 2~3년차 이상·리드/EM·연구직은 2페이지가 일반적으로 수용된다.** '1페이지 절대규범'은 낡았다. 영문은 단어수, **국문은 글자수(공백 포함 1,800~2,000자 ≈ 1페이지)**로 분리해 판단하고, 단어수=페이지는 폰트·여백에 좌우되는 **약한 휴리스틱**임을 전제한다. 여백 0.5–1.0인치, 폰트 10–12pt. _(출처: MIT CAPD — 기본값으로 채택, 연차 보정은 2026 시장 관행)_
|
|
20
|
+
- **(ATS 파싱 — 위험도 등급화)** ATS 안전성의 진짜 변수는 폰트 종류가 아니라 **"텍스트가 실제 선택 가능한 텍스트인가(이미지·아웃라인화가 아님)"**이다. 현대 ATS(Workday/Greenhouse/Lever)는 임베드된 일반 폰트 대부분과 단순 2열 스킬 섹션을 정상 파싱한다. 고위험은 **텍스트박스·헤더/푸터에 담긴 핵심정보·이미지 속 텍스트·다단 본문**이고, 단순 표는 중위험이다. 폰트 화이트리스트(Arial/Calibri/Times/Garamond)는 **ATS가 아니라 사람 가독성·렌더 안정성** 근거로 권한다. _(출처: Jobscan / Santa Clara — 미국 ATS 기준; 한국 플랫폼 실증은 미확인)_
|
|
21
|
+
- **(키워드 매칭 — 정규화·동의어 전제)** 공고 핵심 키워드를 실제 경험과 함께 자연스럽게 반영하되, 매칭은 **소문자화·공백/점 제거 정규화 + 약어/동의어 사전(JS↔JavaScript, K8s↔Kubernetes, ML↔머신러닝↔기계학습, React.js↔React) + 한국어 부분/어간 매칭(백엔드/백엔드의/백엔드를)**을 전제한다. 단순 문자열 매칭은 표기만 달라도 미탐하여 오히려 키워드 스터핑을 유도한다(자기 모순). 키워드 스터핑은 금지한다. _(출처: MIT CAPD; Jobscan)_
|
|
22
|
+
- **(개인정보 배제)** 사진·나이/생년월일·성별·결혼 여부·주민등록번호·references를 기본 템플릿에서 배제한다. **단 한국 자사 양식이 사진·생년월일 칸을 강제하면, 그 양식을 따르지 않으면 지원 자체가 불가능**하므로 — 양식이 강제될 때는 "양식 우선, 배제 원칙은 자유 양식일 때" 분기를 안내한다. _(출처: Harvard FAS; 한국 양식 강제 분기는 실무 보정)_
|
|
23
|
+
- **(형식 일관성)** 불릿 기호·날짜 표기·들여쓰기·구두점을 문서 전체에서 일관되게 유지한다. 밑줄은 피하고 강조는 bold/italic으로 한다. _(출처: Harvard FAS; MIT CAPD)_
|
|
24
|
+
|
|
25
|
+
### Do
|
|
26
|
+
|
|
27
|
+
- 각 경력 불릿을 액션 동사로 시작하고 결과 임팩트(증감 동사+숫자, %, 배수, 금액, 전후 →)로 마무리하라.
|
|
28
|
+
- XYZ 3요소(무엇을 X / 얼마나 측정되게 Y / 어떻게 Z)를 한 줄씩 점검하되, 정량화가 어려운 직군은 규모·전후 비교로 대체하라.
|
|
29
|
+
- 역시간순 정렬, 현재 직무 현재형·과거 직무 과거형으로 시제를 통일하라.
|
|
30
|
+
- 공고 핵심 용어를 추출해 **실제 경험이 있는 항목에** 같은 표현으로 반영하라(정규화·동의어 고려).
|
|
31
|
+
- 텍스트가 선택 가능한 실제 텍스트로 출력되게 하라(이미지·아웃라인화 금지). 핵심정보를 텍스트박스·헤더/푸터에 넣지 마라.
|
|
32
|
+
- 연차·직군에 맞게 분량을 정하라(신입 1p, 시니어/리드/연구 2p 허용). 국문은 글자수 기준으로 압축하라.
|
|
33
|
+
- 같은 액션 동사 반복을 피하고 다양한 강한 동사를 쓰되 과장은 금지하라.
|
|
34
|
+
- **수치·고유명사·기술 스택은 사용자 데이터 그대로 보존하고, 없는 숫자는 지어내지 말고 사용자에게 확인하라(save 단계에서 "이 수치 확인됨?" 게이트).**
|
|
35
|
+
|
|
36
|
+
### Don't
|
|
37
|
+
|
|
38
|
+
- 'Responsible for', 'Worked on', 'Helped with', 'Duties included'로 시작하지 마라(영문). 단 국문 '담당'은 성과가 붙으면 정상이다.
|
|
39
|
+
- (영문) 1인칭 주격/소유격 'I/me/my'를 대명사 문맥에서 쓰지 마라. 단 'our team of 8', 'reduced our infra cost'처럼 팀 규모·소속을 나타내는 정당한 'we/our'는 허용한다.
|
|
40
|
+
- 핵심정보를 이미지·아이콘·텍스트박스·다단 본문·헤더/푸터에 넣지 마라(고위험). 단순 표는 가능하면 피하되 절대 금지는 아니다.
|
|
41
|
+
- 사진·나이·성별·생년월일·주민번호·references를 자유 양식 기본 템플릿에 넣지 마라(양식 강제 시 예외).
|
|
42
|
+
- 정량화 없이 'improved', 'increased', 'managed'만 쓰고 끝내지 마라 — 가능하면 측정치를 붙여라.
|
|
43
|
+
- 'Microsoft Office, 팀워크, 성실함' 같은 일반·자명한 항목으로 칸을 채우지 마라.
|
|
44
|
+
- 공고 키워드를 경험과 무관하게 스터핑하거나, **없는 성과·숫자를 꾸며내지 마라**(루브릭이 숫자 존재를 보상한다고 해서 아무 숫자나 박는 게이밍을 하지 마라).
|
|
45
|
+
- 비표준 섹션 제목('My Journey', 'What I Bring')으로 ATS 섹션 경계를 흐리지 마라.
|
|
46
|
+
|
|
47
|
+
### 워크드 예시 (Before → After)
|
|
48
|
+
|
|
49
|
+
1. **Before:** Responsible for managing the company social media accounts and helping increase engagement.
|
|
50
|
+
**After:** Grew Instagram engagement 15% and follower base 20% in 6 months by launching a weekly content calendar and 3 paid campaigns.
|
|
51
|
+
**왜 더 나은가:** Before는 수동표현('Responsible for', 'helping')에 결과 숫자가 없다. After는 액션 동사(Grew)로 시작하고 X(engagement/follower 증가) + Y(15%/20%, 6개월) + Z(콘텐츠 캘린더+캠페인) 3요소를 갖춰 임팩트를 증명한다. 여기서 '6 months'는 맥락이지만 '15%/20%'가 결과 신호다.
|
|
52
|
+
|
|
53
|
+
2. **Before:** Worked on backend APIs and helped improve system performance.
|
|
54
|
+
**After:** Cut p95 API latency 240ms→90ms (-62%) by adding Redis caching and rewriting 4 N+1 queries, serving 1.2M daily requests.
|
|
55
|
+
**왜 더 나은가:** Before는 'Worked on/helped'로 기여 범위가 모호하다. After는 전후 화살표(240ms→90ms)와 -62% 같은 **결과 신호**, 방법(Redis, N+1 제거), 규모(1.2M/day)를 담아 깊이와 영향력을 동시에 보여준다. 'p95'·'1.2M'은 맥락/규모 수치이고 진짜 임팩트는 '-62%'임에 주의(채점기는 이를 구분해야 한다).
|
|
56
|
+
|
|
57
|
+
3. **Before:** 고객 응대 업무를 담당했으며 팀 분위기를 좋게 만들기 위해 노력함.
|
|
58
|
+
**After:** 월 평균 320건 고객 문의를 응대해 CSAT를 78%→91%로 개선했고, 응대 매뉴얼을 표준화해 신입 온보딩 기간을 2주 단축함.
|
|
59
|
+
**왜 더 나은가:** Before는 직무 나열+정성적 자기평가('노력함')라 검증 불가다. After는 규모(월 320건), 측정 결과(CSAT 78→91%), 방법(매뉴얼 표준화)과 2차 효과(온보딩 2주 단축)까지 정량화해 국문 경력기술서에서도 XYZ 원칙을 충족한다. 국문 '담당'은 여기서 '응대해…개선했고'라는 성과로 연결돼 정상 사용이다.
|
|
60
|
+
|
|
61
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
62
|
+
|
|
63
|
+
> **스코프 한정 (먼저 읽을 것):** 이 루브릭은 **형식·표면 위생** 검사다. 모든 항목 통과(score 1.0)는 "ATS 파싱과 6초 스캔에 형식적으로 걸림돌이 적다"는 뜻이지 **"합격" 또는 "내용이 좋다"는 보장이 아니다.** passBar 임계값(verb 90%, quantified 60% 등)은 출처가 제시한 정성 지침을 운영화한 **권장 기본값(튜닝 가능)**이며, 통과/실패의 이진 도장이 아니라 **점수+코칭**으로 다룬다. **신입·연구·창작·임원 직군과 연차에 따라 임계값을 분기**하라(아래 표의 보정 열 참조).
|
|
64
|
+
|
|
65
|
+
| ID | 검사 항목 | 합격 기준(권장 기본값·튜닝 가능) | 측정 방법(LLM 없이 셀 수 있게) |
|
|
66
|
+
|----|-----------|-----------|--------------------------------|
|
|
67
|
+
| R1 | 액션 동사 선행 (영문) | 경력 불릿의 90% 이상이 동사 선행. 국문은 N/A(별도 약한표현 체크로 대체) | 각 불릿 첫 토큰을 액션 동사 사전(Harvard/MIT 기반, 활용형 led/leads/leading 포함·수백 개·한영 병행)과 대조해 비율 산출. 사전 미스 시 미탐 가능을 경고로 표기 |
|
|
68
|
+
| R2 | 정량화된 임팩트 (결과 불릿 한정) | **결과 불릿**의 60% 이상에 임팩트 신호 1개 이상. **신입/연구/창작은 30~40%로 하향** | (1) 연도 `(19\|20)\d{2}`·버전 `v?\d+(\.\d+)*`·헤더 `p\d+\|h\d` 토큰을 **먼저 제외**, (2) 임팩트 신호 = `\d+%`, `[\$₩]\s?\d`, 배수(`\d+\s?(배\|x\|×)`), 전후 화살표 `\d+\s?(→\|->)\s?\d`, 증감동사 근접(`(reduced\|cut\|grew\|increased\|줄\|단축\|개선\|향상).{0,20}\d`)으로 매칭. 스킬/요약 불릿은 분모에서 제외 |
|
|
69
|
+
| R3 | 1인칭 대명사 없음 (영문 한정) | 영문 본문에서 대명사 문맥의 'I/me/my' 0건. 'we/our'는 **팀 규모·소속 용례 허용**(전면 금지 아님). 국문은 N/A | 'I'는 **문장 시작 또는 대명사 문맥만** 매칭(로마숫자 Phase I/Type II, 약어 제외). 'my' 단어경계 매칭. 'we/our'는 카운트만 하되 패스 차감하지 않음 |
|
|
70
|
+
| R4 | 약한·직무나열 표현 회피 | 영문 'Responsible for'/'Worked on'/'Helped with'/'Duties included' 0건. 국문은 **'담당'에 성과 부재가 결합될 때만** 경고(단순 '담당' 카운트 아님) | 영문 문자열 검색=0. 국문은 '담당' 출현 불릿 중 같은 불릿에 R2 임팩트 신호가 0인 비율을 경고값으로 산출(0건 강제 아님) |
|
|
71
|
+
| R5 | 분량 (언어·연차 분기) | 영문: 신입 ≤600단어, 시니어/리드/연구 ≤1,000단어(2p). 국문: ≤2,000자(공백 포함, 1p) / 시니어 ≤4,000자. **약한 휴리스틱으로 강등 표기** | 영문 단어수 / 국문 글자수를 **언어 감지 후 분리** 카운트해 연차 분기 임계값과 비교. 실제 렌더 페이지수는 보장 못 함을 명시 |
|
|
72
|
+
| R6 | ATS 안전 구조 (원본 파일 한정) | 텍스트박스·다단 본문·이미지속텍스트 0건 + 표준 헤딩 2개 이상 존재 | **⚠️ 평문 resumeText로는 검증 불가**(다단·표 구조가 평문화 시 소실). 가능하면 **원본 .docx/.pdf 레벨**에서 다단/텍스트박스/이미지 감지. 평문 입력이면 "원본 포맷 보장 못 함"을 결과에 명시하고 표준 헤딩 존재 여부(Experience/Education/Skills 또는 경력/학력/기술 중 2개)만 부분 검사 |
|
|
73
|
+
| R7 | 역시간순 정렬 (구조화 입력 전제) | Experience **섹션 내** 항목의 종료 연도가 내림차순, Present/현재가 최상단 | **섹션별 항목 배열 + startYear/endYear 필드**를 전제로 비교. 평문 본문에서 연도 정규식만 긁으면 학력·자격증·프로젝트 연도가 섞여 오작동하므로 **구조화 입력이 없으면 이 체크는 스킵/경고**. 한국식 표기(`YYYY.MM`, `YYYY년 M월`, `2021.03~2023.06`)도 파싱 |
|
|
74
|
+
| R8 | 키워드 커버리지 (정규화·동의어 전제) | 공고 상위 키워드의 50% 이상 등장(기본값·튜닝 가능) | 정규화(소문자·공백/점 제거) + 약어/동의어 사전 + 한국어 부분/어간 매칭으로 교집합/공고키워드수 산출. **단순 문자열 매칭 금지**(한국어 교착·약어 미탐 구조적). 임계값 근거는 데이터 부재 — 기본값임을 명시 |
|
|
75
|
+
| R9 | 개인정보 배제 (양식 강제 시 예외) | 생년월일/성별/주민번호/references 키워드 0건. 사진은 평문 입력에선 무력함을 명시 | 키워드 검색('references','생년월일','주민','성별','나이') + **한국 주민번호 13자리** 정규식 `\d{6}\s?[-–]\s?\d{7}` 및 마스킹형 `\d{6}\s?[-–]\s?[1-4*]\*{6}`. 사진/이미지는 원본 파일에서만 검출 가능 |
|
|
76
|
+
|
|
77
|
+
**주요 실패 모드:**
|
|
78
|
+
- **R2 게이밍 / 숫자 인플레이션:** 루브릭이 "숫자 존재"를 보상하면 연결된 AI·사용자가 측정 불가한 성과에 가짜 숫자를 붙이도록 유인된다(perverse incentive). 방어: (1) 맥락 숫자(연도/버전) 제외로 false positive 차단, (2) 결과 불릿 한정, (3) **save 단계의 "이 수치 사용자 확인됨?" 게이트** — 정직성은 LLM 없이 못 재므로 인간 확인으로 보완.
|
|
79
|
+
- **R6 환상의 게이트:** 평문 입력에서 ATS 구조 체크는 실제로 작동하지 않는다. 가장 중요한 ATS 실패(2단·텍스트박스)는 원본 파일에서만 보이므로, 평문 채점 결과를 "통과"로 오해하면 안 된다.
|
|
80
|
+
- **R7 거짓 정렬 판정:** 구조화 입력 없이 본문 연도만 긁으면 섹션이 섞여 오작동 → 구조화 필드가 없으면 스킵이 정직하다.
|
|
81
|
+
- **언어 미분기:** 영문 단어수 임계값을 국문에 적용하면 분량 판정이 왜곡된다. 언어 감지 후 분리 필수.
|
|
82
|
+
- **단순 문자열 키워드 매칭:** 한국어 교착·영문 약어 변형에서 구조적 false negative → 통과할 이력서를 탈락 판정. 정규화·동의어 사전 없이는 채점기로 쓰지 말 것.
|
|
83
|
+
- **과탐(false positive) 탈락:** 멀쩡한 시니어 이력서(2p, 단순 표)를 1p·표0건 이진 게이트로 떨어뜨리는 것. 위험도 등급화·연차 분기로 방어.
|
|
84
|
+
|
|
85
|
+
## 4. 출처 (Provenance)
|
|
86
|
+
|
|
87
|
+
- **Google XYZ Formula — Laszlo Bock, *Work Rules!* (1차 출처)** — 불릿 핵심 공식 'Accomplished X as measured by Y, by doing Z'. 1차는 Bock의 저서/그가 직접 쓴 LinkedIn 원글이며, theladders 등은 2차 인용임에 유의. Bock은 2016년 Google을 떠났으므로 "현 구글 공식 채용 가이드"로 권위 프레이밍하지 말 것. · 2차 참조: https://www.theladders.com/career-advice/google-recruiters-say-they-always-want-to-see-the-x-y-z-formula-on-successful-resumes-heres-how-to-use-it
|
|
88
|
+
- **Harvard FAS Mignone Center for Career Success — Create a Strong Resume** — 역시간순, 액션 동사, fact-based 정량화, 형식 일관성, 1인칭/사진/나이/성별/references 배제, 'passive language가 최대 실수'. · https://careerservices.fas.harvard.edu/resources/create-a-strong-resume/
|
|
89
|
+
- **Harvard Extension School — Resumes & Cover Letters (PDF)** — 불릿 구조·액션 동사 카테고리·정량화 예시. · https://cdn-careerservices.fas.harvard.edu/wp-content/uploads/sites/161/2024/08/2024-HES_resume-and-letter.pdf
|
|
90
|
+
- **MIT CAPD — Resume Checklist & Action Verbs** — 분량(연차 보정의 기본값), 여백·폰트, 동사 선행+시제, 'quantify size/scale/budget/staff', 공고 키워드 매칭. · https://capd.mit.edu/resources/resume-checklist/
|
|
91
|
+
- **Jobscan / Santa Clara University — ATS Formatting Guides (2026)** — 텍스트박스·이미지속텍스트·다단/헤더푸터 위험, 단순 표·일반 폰트는 대체로 파싱됨(폰트 화이트리스트는 미신에 가까움). **미국 ATS(Workday/Greenhouse/Lever/Taleo) 기준이며 한국 플랫폼(잡코리아/사람인/원티드/공채)의 동일 동작은 미검증** — 한국 ATS 실증은 후속 과제. · https://www.jobscan.co/blog/ats-formatting-mistakes/
|
|
92
|
+
|
|
93
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
94
|
+
|
|
95
|
+
- **MCP 도구 아이디어:**
|
|
96
|
+
- `get_resume_playbook` — 작성/개선 전 호출하면 (1) 원칙, (2) do/dont, (3) **액션 동사 사전(한영 병행·활용형 포함·갱신 주체 명시)**, (4) 약한표현 블랙리스트, (5) **동의어/약어 사전**, (6) rubricChecks(패턴·임계값·연차/언어 분기 포함)를 JSON으로 반환.
|
|
97
|
+
- `validate_resume_draft` — 이력서 텍스트 + (선택) 공고 키워드 + (선택) yearsExperience·jobFamily·language를 받아 루브릭을 정규식·카운트·순서로 실행, 항목별 pass/fail + 측정값 + 코칭을 반환(LLM 없이 채점). **R6은 원본 파일이 함께 오면 .docx/.pdf 구조도 점검, 평문만 오면 "구조 미검증" 플래그.** save_fit_analysis / add_resume / keywords 흐름과 연계.
|
|
98
|
+
- **데이터 형태 힌트:**
|
|
99
|
+
```
|
|
100
|
+
playbook: {
|
|
101
|
+
principles:[{rule,rationale,source}], doList:[str], dontList:[str],
|
|
102
|
+
actionVerbs:{en:[str], ko:[str]}, // 활용형 포함, 갱신 주체 명시
|
|
103
|
+
weakPhrases:{en:[str], ko:[str]}, // ko는 '담당' 단독 금지 아님 → 성과부재 결합 시 경고
|
|
104
|
+
synonyms:[[str,...]], // [["JavaScript","JS"],["Kubernetes","K8s"],["머신러닝","ML","기계학습"]]
|
|
105
|
+
rubricChecks:[{ id, check, passBar,
|
|
106
|
+
measure:{ type:'ratio'|'count'|'exists'|'order',
|
|
107
|
+
pattern?:regex, exclude?:[regex], // exclude=연도/버전/헤더 등 맥락 숫자
|
|
108
|
+
threshold?:number,
|
|
109
|
+
scope?:'resultBullets'|'all',
|
|
110
|
+
language?:'en'|'ko'|'any',
|
|
111
|
+
requiresStructuredInput?:bool, // R7 등: 구조화 입력 없으면 skip
|
|
112
|
+
requiresOriginalFile?:bool } }] // R6: 평문이면 부분검사
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
validate 입력: { resumeText:str, originalFile?:bytes,
|
|
116
|
+
jobKeywords?:[str], yearsExperience?:number,
|
|
117
|
+
jobFamily?:'eng'|'design'|'pm'|'research'|'sales'|'newgrad',
|
|
118
|
+
language?:'en'|'ko' }
|
|
119
|
+
validate 출력: { checks:[{id, passed:bool|null, value:number|bool,
|
|
120
|
+
passBar, note?:str /* 'skipped: needs structured input' 등 */}],
|
|
121
|
+
score:0..1, failedIds:[str], warnings:[str],
|
|
122
|
+
disclaimer:'형식 위생 검사이며 합격을 보장하지 않음' }
|
|
123
|
+
```
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# 연봉 협상 / Salary Negotiation — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
연봉 협상에서 협상력은 개인 사정이 아니라 **데이터(시장 벤치마크)와 BATNA(대안)**에서 나온다. 이 플레이북은 연결된 AI가 (1) 직무·지역·레벨·통화·시점이 일치하는 시장 데이터로 요구액을 정당화하고, (2) total comp을 구성요소(base/bonus/equity/sign-on/relocation, 한국은 +사이닝·직책수당·성과급 비중)로 분해해 협상하며, (3) **BATNA 강도와 지원자 연차·시장 수급에 맞게 협상 강도를 캘리브레이션**하도록 안내한다. 무리한 앵커는 오퍼 철회 리스크를 키우므로, 업사이드뿐 아니라 **하방 리스크와 안전 한계선**도 함께 가르친다. 한국 맥락(포괄임금제·연봉 일원화·스톡옵션 과세·원천징수영수증 관행)을 반영하되 글로벌 베스트프랙티스를 우선한다.
|
|
8
|
+
|
|
9
|
+
## 2. 플레이북
|
|
10
|
+
|
|
11
|
+
### 원칙
|
|
12
|
+
|
|
13
|
+
- **(요구액은 시장 데이터로 정당화한다 — 개인 사정 금지)** 매 요구 금액 옆에 명명된 벤치마크 출처와 **직무·지역·레벨·통화·수집 시점(연도)**을 함께 붙인다. 개인 사정(대출·생활비)은 회사가 통제 불가하고 설득력이 없다. _(출처: Levels.fyi Negotiation Guide; UH Bauer Rockwell Career Center)_
|
|
14
|
+
- **(시장 앵커 출처에는 정밀도 위계가 있다)** 시장 앵커는 **levels.fyi·회사별 실데이터(직무·레벨·지역·equity 반영)를 1순위**로 쓴다. BLS OEWS·정부 통계는 광역 직업분류 평균이라 테크 직무에 과소·지연 집계되므로 **하한 참고·보조**로만 강등한다. 한국은 사람인·잡코리아·원티드 직무 통계와 동종업계 레인지를 1차로 쓴다. _(출처: Levels.fyi Guide; BLS OEWS May 2025 한계)_
|
|
15
|
+
- **(임금 투명성이 기본 환경이다 — 공개 레인지를 디폴트로 다룬다)** NYC/CA/CO/WA 공고 레인지 의무공개, EU Pay Transparency Directive(2026 시행)로 회사 레인지가 이미 공개된 경우가 많다. **공개 레인지가 있으면 그것을 즉시 앵커 기준으로 활용**한다. 단 한국은 일반 임금공개 의무가 없으므로, 한국 시장에서는 역질문으로 레인지를 끌어내는 전략을 디폴트로 둔다. _(출처: NYC Local Law 32; EU Directive 2023/970)_
|
|
16
|
+
- **(정보가 충분하면 먼저 앵커, 부족하면 디플렉션 — 조건부 규칙)** "먼저 숫자 말하면 진다"는 과도한 일반화다. 협상학 실증(Galinsky & Mussweiler 2001)은 **시장 정보를 충분히 확보했을 때 먼저 데이터 기반으로 앵커하는 쪽이 결과가 좋음**을 보인다. 따라서 (a) 시장가·레벨 구조를 충분히 알면 먼저 데이터 앵커를, (b) 정보 비대칭이 크면 회사 레인지를 먼저 끌어내는 역질문을 쓴다. _(출처: Galinsky & Mussweiler, JPSP 2001; Harvard PON)_
|
|
17
|
+
- **(하향 범위가 아니라 단일 앵커로 핵심 요구액을 제시한다)** 핵심 요구 base는 자기 양보를 내포한 **하향 범위(X에서 Y, X~Y where X<Y)로 제시하지 않는다** — 상대는 항상 하단으로 점프한다. 단일 숫자로 타깃의 **+5~15%** 위를 앵커하되 **인용된 시장 p75를 넘지 않게**(최대 p90), 그 차이를 정당화할 근거를 준비한다. **total comp 구성 시나리오(A/B/C로 분해된 여러 숫자)는 이 규칙의 예외**다 — 분해는 양보가 아니라 경로 제시다. _(출처: UT Dallas Career Center; UH Bauer; Anchoring 이론)_
|
|
18
|
+
- **(total comp을 구성요소로 분해해 협상한다)** base / annual bonus / equity / sign-on / relocation으로 나누고, 동일 타깃 총액을 만드는 **2~3개 구성 시나리오**를 제시한다. "올려달라"(쉽게 'no')가 아니라 "어느 구성이 내부적으로 가능한가"로 질문을 바꾼다. sign-on은 밴드·내부 형평성에 걸리지 않아 base보다 양보받기 쉽다. annual bonus는 레벨 고정인 회사가 많지만, **타깃 보너스 %·첫 해 비례지급(proration)·보장 보너스(guaranteed first-year)**는 협상 가능한 경우가 흔하므로 무조건 빼지 않는다. _(출처: Levels.fyi Guide; The Salary Negotiator Total Comp guide)_
|
|
19
|
+
- **(equity는 구성요소 1개가 아니라 별도 전장으로 다룬다)** **베스팅 스케줄(4년·1년 클리프)·refresh(리프레셔)·RSU vs 옵션·409A/행사가·비상장 유동성·세금**을 분해해 평가한다. 시니어·스태프급은 base보다 **equity refresh·베스팅·레벨(다운레벨 방지)**이 진짜 협상 포인트다. 한국 스톡옵션은 **적격/비적격 행사이익 과세·행사 요건**이 실질이며, 4년 베스팅이 표준이 아닌 관행도 확인한다. _(출처: The Salary Negotiator; 한국 벤처기업법 스톡옵션 과세특례)_
|
|
20
|
+
- **(BATNA를 명시하고 강도에 따라 협상 강도를 분기한다)** 협상 전 BATNA(다른 오퍼·현직 유지·다음 사이클 대기)를 한 문장으로 정의하고 워크어웨이 라인을 정한다. **(a) 강한 BATNA(검증 가능한 서면 오퍼)만 금액 레버리지로 사용**한다. **(b) 약/무 BATNA(주니어·단일 오퍼·이직 절박)면 경쟁 오퍼 언급 자체를 금지**하고 시장 데이터만으로 협상한다 — 모호한 경쟁 오퍼는 리크루터가 "어느 회사 어느 단계냐, 그 타임라인에 맞춰주겠다"로 5분이면 무너뜨린다. _(출처: Fisher & Ury, Getting to Yes; Harvard PON; 리크루터 역이용 시나리오)_
|
|
21
|
+
- **(협상 강도를 BATNA·연차·시장 수급에 매핑하고 오퍼 리스크를 관리한다)** 공격적 단일 앵커 + 타깃 위 + exploding offer 연장이 겹치면 — 특히 주니어·평범한 BATNA에서 — **오퍼가 식거나 철회될 실제 리스크**가 있다. p90 초과 앵커, 밴드 상한 무시, "서면 전엔 신뢰 안 함"식 압박은 위험 신호다. 강한 BATNA·시니어·수급 우위면 세게, 약한 BATNA·주니어·수급 열위면 시장 중앙값~p75 안에서 부드럽게 민다. _(출처: 채용 매니저 오퍼 철회 리스크; UH Bauer 캘리브레이션)_
|
|
22
|
+
- **(거짓·검증 불가 경쟁 오퍼를 만들지 않는다)** 강한 BATNA가 있을 때만 사실 범위 안에서 활용한다. 없는 오퍼를 지어내거나 검증 불가능한 모호한 오퍼를 언급하면, 오퍼레터 요구 한 번에 신뢰가 붕괴되고 협상이 무너진다. _(출처: Levels.fyi Guide; 리크루터 검증 압박)_
|
|
23
|
+
- **(즉답 금지 → 24~48시간 검토 → 서면 확인)** 감사+열의를 표한 뒤 검토 시간을 요청하고, 모든 합의(금액·구성·시작일·조건)는 오퍼레터·이메일로 서면화한다. _(출처: UMD/UW Career Center; Levels.fyi Guide)_
|
|
24
|
+
- **(한국 맥락: 포괄임금제와 base 외 레버를 본다)** **포괄임금제(고정OT)는 base가 같아도 실수령·근로시간이 다른 진짜 함정**이므로 먼저 확인한다. **연봉계약서 vs 근로계약서**, 인센티브의 **확정 vs 변동**, 직책수당·연봉테이블 등급 조정·사이닝(스타트업·유니콘은 점점 흔함)을 분해 대상으로 삼는다. **원천징수영수증/현재 연봉 요구**는 처우협의 단계에서 강하게 들어올 수 있으므로 단순 회피가 아니라 "희망연봉은 시장가 기준"으로 프레이밍하고, 강하게 요구될 때의 대응 스크립트를 준비한다. _(출처: 글로벌 원칙의 한국 적용; 근로기준법 포괄임금 판례)_
|
|
25
|
+
- **(비금전 레버와 합법성/형평성을 협상 표면에 올린다)** 시작일·재택/하이브리드·직책/타이틀·교육비·리뷰 주기 앞당기기·재협상 시점 합의 등 비금전 레버를 활용한다. 회사 거절 사유 1위는 보통 **밴드 상한·내부 형평성(internal equity)**이므로, "왜 안 되는지"를 이해하고 형평성에 안 걸리는 sign-on으로 우회한다. 반경쟁조항·전 직장 연봉 질문의 지역별 합법성도 확인한다. _(출처: 채용 매니저 밴드/형평성; 지역별 salary history ban)_
|
|
26
|
+
|
|
27
|
+
### Do
|
|
28
|
+
|
|
29
|
+
- 작업 전 levels.fyi·회사별 실데이터(또는 한국이면 사람인·잡코리아·원티드·동종업계 레인지)에서 **직무·지역·레벨·통화·수집 연도**별 p25/p50/p75를 수집하고 출처를 기록한다. BLS OEWS는 하한 보조로만.
|
|
30
|
+
- 요구 금액마다 "시장가 $X(출처·직무·지역·레벨·연도) + 차별화 요소(즉시 기여·무 램프업·희소 스킬) → 따라서 $Y"의 데이터 문장으로 정당화한다.
|
|
31
|
+
- 공개 레인지가 있으면 즉시 앵커 기준으로 쓰고, 없으면(한국 디폴트) 역질문으로 회사 레인지를 먼저 끌어낸다.
|
|
32
|
+
- 핵심 요구 base는 단일 숫자로, 타깃의 +5~15% 위를 앵커하되 인용된 p75(최대 p90)를 넘지 않게 한다.
|
|
33
|
+
- total comp을 base/bonus/equity/sign-on/relocation으로 분해하고 동일 총액의 2~3개 구성 시나리오를 만든다.
|
|
34
|
+
- equity는 베스팅·refresh·RSU/옵션·행사가·세금까지 분해해 평가한다. 시니어면 레벨·refresh를 핵심 협상 포인트로 둔다.
|
|
35
|
+
- 협상 전 BATNA를 한 문장으로 명시하고, **강도에 따라 협상 강도를 분기**한다(강하면 금액 레버리지, 약하면 시장 데이터만).
|
|
36
|
+
- 오퍼 수신 시 감사+열의 표현 후 24~48시간 검토를 요청하고, 최종 합의를 서면 확인한다.
|
|
37
|
+
- 한국이면 포괄임금제·연봉계약서·확정/변동 인센티브·사이닝·직책수당·연봉등급을 별도 협상 포인트로 식별한다.
|
|
38
|
+
- 비금전 레버(시작일·재택·타이틀·교육비·재협상 시점)와 밴드 상한·내부 형평성 현실을 함께 고려한다.
|
|
39
|
+
|
|
40
|
+
### Don't
|
|
41
|
+
|
|
42
|
+
- 생활비·대출·집세·부양 등 **개인 사정으로 요구액을 정당화하지 않는다**.
|
|
43
|
+
- 핵심 요구 base를 **하향 범위(X에서 Y, X<Y)로 제시하지 않는다** — 상대는 하단으로 점프한다. (단 total comp 구성 시나리오의 다중 숫자는 예외)
|
|
44
|
+
- 정보가 부족한데 먼저 구체적 숫자를 던지지 않는다(반대로 정보가 충분하면 먼저 앵커한다).
|
|
45
|
+
- 현재/전 직장 연봉을 묻기 전에 자발적으로 노출하지 않는다.
|
|
46
|
+
- 오퍼를 받자마자 그 자리에서 수락·거절하지 않는다.
|
|
47
|
+
- **약/무 BATNA에서 경쟁 오퍼를 언급하지 않는다**(주니어·단일 오퍼·이직 절박 시 순손실).
|
|
48
|
+
- 존재하지 않거나 검증 불가능한 모호한 경쟁 오퍼를 지어내거나 암시하지 않는다.
|
|
49
|
+
- 인용된 시장 p90을 초과하는 무리한 앵커로 오퍼 철회 리스크를 자초하지 않는다.
|
|
50
|
+
- base 한 숫자에만 집중해 sign-on·equity·포괄임금·기타 구성요소를 놓치지 않는다.
|
|
51
|
+
- annual bonus를 "레벨 고정"이라며 무조건 협상에서 빼지 않는다(타깃 %·비례·보장 보너스 협상 여지).
|
|
52
|
+
- "당장 이 오퍼가 꼭 필요하다"는 절박함을 드러내지 않는다.
|
|
53
|
+
- 출처 없는 단일 블로그·커뮤니티 숫자나 통화·지역·시점이 안 맞는 데이터를 시장가 근거로 쓰지 않는다.
|
|
54
|
+
- 구두 합의를 서면 확인 없이 신뢰하지 않는다.
|
|
55
|
+
|
|
56
|
+
### 워크드 예시 (Before → After)
|
|
57
|
+
|
|
58
|
+
1. **Before:** "기대 연봉이 어떻게 되세요?" → "음, 한 6천에서 7천5백만 원 사이면 좋을 것 같아요. 지금 전세 대출도 있고 해서요."
|
|
59
|
+
**After:** "이 역할에 대해 책정하신 연봉 레인지가 있으실 텐데 먼저 공유해 주실 수 있을까요? 저는 동일 직무·서울·시니어 기준, 2026년 사람인·동종업계 데이터를 반영해 말씀드리겠습니다." (회사가 6천~7천5백 제시 시) "해당 직무 75 백분위가 7천2백 수준이고, 저는 온보딩 램프업 없이 첫 분기부터 X를 바로 맡을 수 있어 **base 7천5백**을 기준으로 보고 있습니다."
|
|
60
|
+
**왜 더 나은가:** After는 (1) 한국 디폴트인 역질문으로 정보를 먼저 확보하고, (2) 하향 범위 대신 단일 앵커(7천5백)를 제시하며, (3) 개인 대출이 아니라 직무·지역·레벨·시점이 명시된 시장 백분위+차별화 요소로 정당화한다. 앵커는 인용 p75 안에 있어 무리하지 않다. Before는 범위·개인사정·하단 노출로 협상력을 모두 잃는다.
|
|
61
|
+
|
|
62
|
+
2. **Before:** "제안하신 base 9천만 원 좋습니다. 혹시 조금만 더 올려주실 수 있을까요?"
|
|
63
|
+
**After:** "감사합니다, 팀과 미션에 매우 끌립니다. 검토를 위해 이틀만 시간을 주시면 좋겠습니다. total comp 기준으로 보면 levels.fyi 동일 레벨·지역 중앙값(2026)이 1억1천(base+equity+bonus)인데, 제 타깃은 1억2천입니다. 세 가지 구성안을 드릴게요: **(A) base 1억500 + 사이닝 1천**, **(B) base 1억 + 사이닝 1천5백 + equity 상향(베스팅·refresh 포함)**, **(C) base 1억1천 + 성과급 비중 확대**. sign-on은 밴드·형평성에 안 걸려 양보가 쉬울 텐데, 어느 쪽이 내부적으로 가능할까요?"
|
|
64
|
+
**왜 더 나은가:** After는 단일 base가 아니라 total comp으로 앵커하고, "올려달라"(쉽게 'no')가 아니라 "어느 구성이 가능한가"로 질문을 바꾸며, 검토 시간을 확보하고, sign-on이 형평성에 안 걸리는 이유를 짚어 회사가 yes하기 쉬운 경로를 연다. 다중 시나리오의 여러 숫자는 양보가 아니라 경로 제시이므로 단일-앵커 규칙의 예외다.
|
|
65
|
+
|
|
66
|
+
3. **Before:** (다른 오퍼가 없는데) "사실 다른 데서 1억3천 오퍼 받았어요. 맞춰주세요."
|
|
67
|
+
**After (강한 BATNA가 있을 때만):** "현재 한 곳에서 서면 오퍼를 받았고 그 타임라인이 이번 주입니다. 객관적으로 동일 직무 75 백분위가 약 1억2천이라, **base 1억2천 또는 동등 total comp면 바로 진행**하고 싶습니다. 결정 타임라인을 맞추기 위해 이번 주 내 확정 가능할까요?"
|
|
68
|
+
**After (약/무 BATNA일 때):** (경쟁 오퍼를 언급하지 않는다) "이 역할에 대한 확신이 큽니다. 다만 시장 데이터를 보면 동일 직무·레벨 중앙값이 1억1천이라, base 1억1천~total comp 기준에서 합의했으면 합니다. 검토 시간을 이틀만 주시겠어요?"
|
|
69
|
+
**왜 더 나은가:** 강한 BATNA 버전은 거짓 금액을 지어내지 않고(오퍼레터 요구 시 신뢰 붕괴 회피) 검증 가능한 서면 오퍼+시장 백분위로 레버리지를 만든다. 약/무 BATNA 버전은 **경쟁 오퍼를 아예 꺼내지 않고** 시장 데이터만으로 협상해 역이용 리스크를 차단한다. Before는 검증 요청 한 번에 신뢰를 잃고 협상이 붕괴된다.
|
|
70
|
+
|
|
71
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
72
|
+
|
|
73
|
+
루브릭은 **순수 카운트·존재·패턴**으로 닫히게 설계했다(의미 이해 없이 판정 가능). "정당화 문맥" 같은 의미 조건은 제거하고 토큰 비교로 환원했다. **치명(critical)** 항목은 하나라도 실패하면 산출물 반려, **권고(advisory)** 항목은 점수 차감.
|
|
74
|
+
|
|
75
|
+
| ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) | 가중 |
|
|
76
|
+
|----|-----------|-----------|--------------------------------|------|
|
|
77
|
+
| R1 | market_anchor_cited — 요구액에 시장 출처가 동반되는가 | 명명된 출처 토큰 수 ≥ 통화금액 토큰 수, 그리고 출처 ≥ 1 | 통화/금액 토큰(`₩`·`$`·`만원`·`억`·`base`·`사이닝` + 4자리↑ 숫자) 개수와 출처 토큰(`levels.fyi`·`Glassdoor`·`사람인`·`잡코리아`·`원티드`·`BLS`·`고용노동부`) 개수를 세어 `sources_count >= amount_tokens_count` 확인 | critical |
|
|
78
|
+
| R2 | anchor_quality — 인용 금액에 직무·지역·레벨·통화·시점이 공존하는가 | 같은 출력 안에 4개 토큰군 중 ≥3 공존 + 연도 토큰 ≥1 | 토큰군 {직무명, 지역(서울/SF/remote 등), 레벨(주니어/시니어/L5 등), 통화기호} distinct 등장 수 ≥3, 그리고 `20\d\d` 패턴 ≥1 존재 | advisory |
|
|
79
|
+
| R3 | no_downward_range — 핵심 요구액이 하향 범위로 제시되지 않는가 | 하향 범위 패턴 0건(구성 시나리오 제외) | "A/B/C 시나리오" 블록을 제외한 영역에서 `숫자 (에서|~|-|to|between) 숫자` 매칭 후, 좌측<우측인 경우만 카운트 → 0이면 통과. (분해 시나리오는 `+`/`,`/`(A)` 마커로 식별해 제외) | critical |
|
|
80
|
+
| R4 | anchor_within_market — 앵커가 인용 시장 상단을 넘지 않는가 | 앵커 금액 ≤ 인용된 p75(없으면 p90) | 산출물에 `p75`/`p90`/`75 백분위` 수치가 명시되고, 핵심 앵커 금액 토큰이 그 값 이하인지 수치 비교 | advisory |
|
|
81
|
+
| R5 | total_comp_decomposed — base 외 구성요소로 분해됐는가 | 구성 카테고리 ≥2 distinct | 키워드 집합 {base/기본급, bonus/성과급, equity/스톡/주식, sign-on/사이닝, relocation/이주} 중 distinct 카테고리 수 ≥2 | critical |
|
|
82
|
+
| R6 | batna_present_and_branched — BATNA가 명시되고 강도 분기가 있는가 | BATNA 문장 ≥1 그리고 강/약 분기 표현 ≥1 | 패턴 {BATNA, 대안, 다른 오퍼, 워크어웨이, walk away, 현직 유지, 차선책} ≥1 **그리고** {강한 BATNA, 약한 BATNA, 검증 가능, 서면 오퍼, 언급 금지} ≥1 | critical |
|
|
83
|
+
| R7 | no_personal_justification — 개인 사정 단어가 등장하지 않는가 | 개인사정 패턴 0건 | 패턴 {대출, 전세, 월세, 생활비, 집세, 빚, 부양, mortgage, rent, bills} 등장 횟수 == 0 (의미 판정 없이 단순 부재 확인) | critical |
|
|
84
|
+
| R8 | no_unverifiable_competing_offer — 검증 불가 경쟁 오퍼 블러핑이 없는가 | 거짓/모호 오퍼 안티패턴 0건, 또는 "서면/검증 가능" 한정어 동반 | "다른 데서 ... 받았" 류 패턴이 등장하면 같은 문장 30토큰 내 {서면, 검증 가능, 오퍼레터} 동반 여부 확인 → 미동반 0건이면 통과 | critical |
|
|
85
|
+
| R9 | first_number_strategy — 정보 수준에 따른 앵커/디플렉션 전략이 있는가 | 역질문 또는 선제 앵커 조건 문장 ≥1 | 패턴 {레인지 공유, 책정 레인지, 먼저 여쭤, salary range, 공개 레인지, 정보가 충분하면 먼저 앵커} ≥1 | advisory |
|
|
86
|
+
| R10 | review_time_requested — 검토 시간 요청이 있는가 | 검토 시간 표현 ≥1 | 패턴 {24시간, 48시간, 이틀, 며칠, 검토 시간, 다음 주, get back to you, time to review} 매칭 ≥1 | advisory |
|
|
87
|
+
| R11 | written_confirmation — 서면 확인 안내가 있는가 | 서면화 언급 ≥1 | 패턴 {서면, 오퍼레터, 이메일로 확인, in writing, written} 존재 | advisory |
|
|
88
|
+
| R12 | kr_context_depth — 한국 맥락의 실질 함정을 다루는가(한국 시장 시) | 한국 특수 항목 ≥2 distinct | 패턴 집합 {포괄임금, 고정OT, 연봉계약서, 원천징수, 스톡옵션 과세, 사이닝, 직책수당, 연봉등급} distinct ≥2 | advisory |
|
|
89
|
+
| R13 | offer_risk_calibrated — 오퍼 철회/협상 강도 캘리브레이션이 있는가 | 리스크·강도 매핑 문장 ≥1 | 패턴 {오퍼 철회, 철회 리스크, 협상 강도, 캘리브레이션, 밴드 상한, 너무 세게} ≥1 | advisory |
|
|
90
|
+
|
|
91
|
+
**종합 판정 규칙:** critical(R1·R3·R5·R6·R7·R8) 6개 전부 통과해야 "승인". 하나라도 실패면 "반려". advisory는 통과 개수를 점수로 환산(7개 중 N개 → N/7)해 품질 등급(상/중/하)을 매긴다.
|
|
92
|
+
|
|
93
|
+
**주요 실패 모드:**
|
|
94
|
+
- **출처 게이밍:** 출처 "이름"만 박고 통화·지역·레벨·시점이 안 맞음 → R1(카운트 비교)+R2(공존+연도)+R4(상단 초과)로 다층 방어.
|
|
95
|
+
- **범위 오탐:** total comp 시나리오(A/B/C)를 하향 범위로 오인 → R3에서 분해 마커(`+`/`(A)`)로 명시 제외, 좌<우 조건만 카운트.
|
|
96
|
+
- **체크리스트 채우기:** 키워드만 박아 통과 → critical에 부재 확인(R7·R8)과 강도 분기(R6) 같은 게임하기 어려운 안티패턴 가드 배치.
|
|
97
|
+
- **약 BATNA에서 블러핑:** 없는 경쟁 오퍼 암시 → R6(강/약 분기)+R8(서면 한정어 동반)으로 차단.
|
|
98
|
+
- **무리한 앵커:** p90 초과로 오퍼 철회 자초 → R4(상단 이하)+R13(강도 캘리브레이션)로 경고.
|
|
99
|
+
|
|
100
|
+
## 4. 출처 (Provenance)
|
|
101
|
+
|
|
102
|
+
- **Roger Fisher & William Ury, 『Getting to Yes』 / Harvard Program on Negotiation (PON)** — BATNA 정의, 워크어웨이 기준, 협상력의 원천 · https://www.pon.harvard.edu/daily/batna/
|
|
103
|
+
- **Galinsky & Mussweiler, "First Offers as Anchors", JPSP (2001)** — 정보가 충분할 때 선제 앵커가 유리하다는 협상학 실증(플레이북의 "먼저 말하면 진다" 단정 교정 근거) · https://psycnet.apa.org/record/2001-05428-005
|
|
104
|
+
- **Levels.fyi Ultimate Negotiation Guide** — 데이터 앵커링, total comp 구성요소별 협상, 경쟁 오퍼·exploding offer, 현재 연봉 노출 회피, equity 디스카운트(1순위 시장 데이터) · https://www.levels.fyi/blog/ultimate-negotiation-guide.html
|
|
105
|
+
- **The Salary Negotiator — What is Total Compensation** — total comp 구성요소(base/bonus/equity/sign-on) 정의 및 equity 베스팅·refresh 평가 · https://www.thesalarynegotiator.com/resource-center/totalcompensation
|
|
106
|
+
- **NYC Local Law 32 / EU Pay Transparency Directive 2023/970(2026 시행)** — 공개 레인지를 디폴트로 다루는 근거(임금 투명성 환경) · https://eur-lex.europa.eu/eli/dir/2023/970
|
|
107
|
+
- **UH Bauer Rockwell Career Center — Salary Negotiation** — 타깃 위 앵커링, 90일 가치창출 브리프, 협상 강도 캘리브레이션 · https://careercenter.bauer.uh.edu/salary-negotiation/
|
|
108
|
+
- **UMD & University of Washington Career Centers** — 오퍼 수신 시 감사+열의, 24~48시간 검토 요청, 오퍼 평가 절차 · https://careers.umd.edu/find-jobs-internships/offers-salary-negotiation
|
|
109
|
+
- **BLS OEWS May 2025 (보조·하한 참고로 강등)** — 정부 임금 통계. 테크 직무는 광역 분류·집계 지연으로 과소평가되므로 1차 앵커로 부적합 · https://www.bls.gov/oes/
|
|
110
|
+
- **한국 맥락 — 벤처기업법 스톡옵션 과세특례·근로기준법 포괄임금 판례·사람인/잡코리아/원티드 직무 통계** — 포괄임금·스톡옵션 과세·연봉계약서·사이닝 등 한국 실무 함정의 근거
|
|
111
|
+
|
|
112
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
113
|
+
|
|
114
|
+
- **MCP 도구 아이디어:**
|
|
115
|
+
- `get_salary_negotiation_playbook(stage?, market?, batna_strength?)` — 단계(prep/first_number/counter/closing)·시장(global|kr)·BATNA 강도(strong|weak|none)에 맞는 원칙·스크립트·루브릭 서브셋을 반환하는 read-only 지식 도구. `batna_strength`로 경쟁 오퍼 전술 노출 여부를 분기.
|
|
116
|
+
- `save_compensation_benchmark(role, location, level, source, currency, p25, p50, p75, captured_at)` — 사용자가 수집한 시장 데이터를 저장. **captured_at·currency·region 필수**.
|
|
117
|
+
- `save_offer_breakdown(job_id, currency, base, annual_bonus, equity_annualized, sign_on, relocation, total_comp, batna_note)` — 오퍼를 구성요소별로 구조화 저장.
|
|
118
|
+
- `evaluate_offer(job_id)` — 저장된 오퍼 vs 벤치마크 vs BATNA를 표로 반환. **신선도 검사**: `captured_at`이 N개월(예: 6) 초과면 "stale" 플래그, 오퍼 통화·지역과 벤치마크가 불일치하면 "mismatch" 플래그를 함께 반환(LLM 없이 규칙으로).
|
|
119
|
+
- **데이터 형태 힌트:**
|
|
120
|
+
- `playbook: { principles:[{rule,rationale,source,weight:'critical'|'advisory'}], doList:[str], dontList:[str], scripts:[{situation, batna_strength, line}], rubricChecks:[{id,check,passBar,howToMeasure,weight}] }`
|
|
121
|
+
- `benchmark: { role, location, level, source, currency, p25, p50, p75, captured_at }` — 신선도/통화/지역 검증 가능하게 평탄화.
|
|
122
|
+
- `offerBreakdown: { job_id, currency, base, annual_bonus, equity_annualized, sign_on, relocation, total_comp, batna_note, batna_strength }`
|
|
123
|
+
- 루브릭은 LLM 없이 셀 수 있게 카운트/존재/패턴 필드로 평탄화: `cited_sources_count`, `amount_tokens_count`, `is_downward_range:boolean`, `anchor_within_p75:boolean`, `comp_components:[enum]`, `batna_strength:enum`, `kr_context_components:[enum]`, `check_weight:'critical'|'advisory'`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ATS 호환성 (ATS-compatibility) — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 커리어 산출물(이력서·자소서·면접 답변·LinkedIn 등)을 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사는 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
## 1. 목적
|
|
6
|
+
|
|
7
|
+
이 검증기는 커리어 산출물이 **Applicant Tracking System(ATS)에 의해 정확히 파싱되고, 채용공고(JD)의 핵심 키워드를 충분히 담고 있는지**를 보장한다. 산업 조사에 따르면 채용 담당자의 대다수(Jobscan 조사 기준 ~99.7%)가 ATS로 지원서를 1차 필터링한다. ATS는 대부분 텍스트 레이어를 **선형(좌→우, 위→아래)**으로 읽기 때문에, 표·다단·헤더/푸터·이미지·아이콘처럼 읽기 순서를 깨는 요소가 있으면 사람이 보기엔 멀쩡한 문서도 "단어 샐러드(word salad)"가 되어 검색에서 누락된다.
|
|
8
|
+
|
|
9
|
+
따라서 이 루브릭은 두 축을 본다.
|
|
10
|
+
1. **파싱 안전성(parse-safety)** — ATS가 텍스트를 깨뜨리지 않고 구조를 인식할 수 있는가(표준 헤더·단일 컬럼·연락처 위치·날짜 형식·폰트/아이콘·파일형식).
|
|
11
|
+
2. **JD 키워드 커버리지(keyword coverage)** — JD에서 반복·강조된 하드스킬/직무명/필수요건 용어가 산출물 본문에 실제로 존재하는가, 과도한 키워드 스터핑 없이.
|
|
12
|
+
|
|
13
|
+
핵심 설계 원칙: 모든 항목은 **LLM 없이도 셀 수 있는 형태(개수·존재여부·비율·정규식 패턴)**로 환원해 두어, 연결된 AI가 기계적으로 카운트해 합격/불합격을 판정하고 루프를 돌 수 있게 한다. 이력서·LinkedIn·자소서(텍스트 본문 기준)에 공통 적용한다.
|
|
14
|
+
|
|
15
|
+
## 2. 검사 항목
|
|
16
|
+
|
|
17
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게) |
|
|
18
|
+
|----|------|-----------|------------------------|
|
|
19
|
+
| C1 | 표준 섹션 헤더 존재 | 핵심 섹션이 표준 라벨로 존재 (이력서: Experience/Work Experience/Professional Experience, Education, Skills 중 최소 2개 일치; LinkedIn: About/Experience/Skills) | 산출물에서 헤더 라인을 추출해 표준 라벨 화이트리스트와 정확/근접 일치(대소문자 무시)한 **개수 ≥ 2**. "My Journey"·"내 이야기"·"The Toolkit" 같은 창의적 헤더는 0으로 카운트 |
|
|
20
|
+
| C2 | 비표준/창의적 헤더 부재 | 표준 화이트리스트에 없는 섹션 헤더 = 0개 | 헤더 라인 중 화이트리스트 밖 라벨 개수. **0이면 합격** |
|
|
21
|
+
| C3 | 단일 컬럼(다단 금지) | 다단 레이아웃 신호 없음 | 한 줄에 큰 공백(탭/2칸 이상 스페이스 ≥3개) 또는 좌우 분리 패턴이 있는 라인 비율 **< 10%**. 마크다운/플레인텍스트 추출본에서 같은 줄에 두 개의 독립 항목이 나란히 오는 라인 = 0 목표 |
|
|
22
|
+
| C4 | 표·텍스트박스 부재 | 표 구조 0개 | 마크다운 표 구분자(`\|---\|`)·HTML `<table>`·텍스트박스 마커 출현 횟수 **= 0** |
|
|
23
|
+
| C5 | 이미지·아이콘·스킬바 부재 | 그래픽 요소 0개 | 이미지 마크업(`![]`, `<img`)·이모지/심볼로 표기된 연락처 아이콘·"skill bar" 채움문자(예: ●●●○○, █) 출현 횟수 **= 0** |
|
|
24
|
+
| C6 | 연락처가 본문 상단에 위치 | 이메일·전화가 헤더/푸터가 아닌 본문 첫 영역에 존재 | 본문 텍스트 첫 15% 구간(또는 첫 5줄) 안에서 이메일 정규식(`[\w.+-]+@[\w-]+\.[\w.]+`) 매치 **≥ 1** 그리고 전화 패턴 매치 **≥ 1** |
|
|
25
|
+
| C7 | 일관된 날짜 형식 | 경력/학력 기간이 ATS가 인식하는 형식으로 통일 | 날짜 토큰을 추출해 허용 패턴(`MMM YYYY`, `Month YYYY`, `MM/YYYY`, `YYYY.MM`, `YYYY-MM`) 중 **단일 패턴 비율 ≥ 90%**. 혼용·"현재/Present" 외 자유서술 날짜 비율 < 10% |
|
|
26
|
+
| C8 | JD 하드스킬 키워드 커버리지 | JD 상위 키워드의 충분 비율을 본문이 포함 | JD에서 추출한 상위 하드스킬/도구/자격 키워드 집합 N개 대비, 산출물 본문에 (어형 정규화 후) 존재하는 개수 M → **M/N ≥ 0.75** (Jobscan 권장 75%+, 스위트스폿 80%). JD 미제공 시 본 항목은 N/A 처리하고 사유 기록 |
|
|
27
|
+
| C9 | 직무명(target job title) 일치 | JD의 핵심 직무명이 본문에 등장 | JD 헤드라인 직무명을 본문(이력서 요약/타이틀, LinkedIn 헤드라인)에서 정확/근접 일치로 탐색 → 매치 **≥ 1** |
|
|
28
|
+
| C10 | 키워드 스터핑 방지(과최적화) | 특정 키워드 반복이 과하지 않음 | C8 키워드 각각의 본문 등장 횟수 중 **어떤 단일 키워드도 6회 초과 금지**, 그리고 키워드 토큰이 전체 토큰에서 차지하는 비율 **< 6%**. 위반 키워드 개수 = 0 목표 |
|
|
29
|
+
| C11 | 약어·풀네임 병기 | 핵심 약어가 풀네임과 함께 1회 이상 병기 | JD/본문 공통 약어(예: ATS, SQL, PM) 중 본문에 약어만 단독 등장하고 풀네임 동반이 0인 항목 개수 → **0 목표**(파서/사람 양쪽 매칭 보장) |
|
|
30
|
+
| C12 | 파일 형식 안전 | 제출 형식이 `.docx` 또는 텍스트 레이어 있는 `.pdf` | 산출물 export 시 형식이 `.docx`/`.pdf`(텍스트 레이어 존재) 중 하나. 스캔 이미지 PDF·`.hwp`만 단독 제출 = 불합격 신호 |
|
|
31
|
+
|
|
32
|
+
> 측정 주체 안내: 위 패턴/카운트는 연결된 AI가 본문 텍스트(이미 추출된 플레인/마크다운)에 대해 직접 세면 된다. CareerMate는 원문 추출(`read_document`)과 본 루브릭만 제공한다.
|
|
33
|
+
|
|
34
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
35
|
+
|
|
36
|
+
불합격 항목이 하나라도 있으면, 연결된 AI는 **저장(`save_*`)·내보내기(`export_cover_letter`) 전에** 아래 순서로 수정하고 재검증(C1–C12 재실행)한다. 통과까지 반복하되, 사실·수치·고유명사는 절대 변경하지 않는다.
|
|
37
|
+
|
|
38
|
+
- **C1/C2 (헤더):** 창의적 헤더를 표준 라벨로 치환한다(예: "내 이야기" → "Experience", "보유 역량" → "Skills"). 누락된 표준 섹션은 기존 내용을 재배치해 신설.
|
|
39
|
+
- **C3/C4/C5 (레이아웃·표·그래픽):** 다단/표/텍스트박스/이미지/스킬바를 제거하고 **단일 컬럼 + 불릿 텍스트**로 평탄화한다. 아이콘은 텍스트 라벨("Email:", "Phone:")로 대체.
|
|
40
|
+
- **C6 (연락처):** 헤더/푸터에 있던 연락처를 본문 최상단으로 이동.
|
|
41
|
+
- **C7 (날짜):** 가장 많이 쓰인 단일 날짜 형식으로 전부 통일하고, 자유서술 기간을 표준 패턴으로 재작성.
|
|
42
|
+
- **C8/C9 (키워드/직무명):** JD에서 누락된 상위 키워드와 직무명을, **실제 경험이 있는 항목에 한해** 자연스럽게 본문에 통합한다. 경험이 없는 키워드는 넣지 않고 갭으로 보고만 한다(허위 금지).
|
|
43
|
+
- **C10 (스터핑):** 6회 초과·비율 초과 키워드의 등장 횟수를 줄이고 동의어/맥락 문장으로 분산.
|
|
44
|
+
- **C11 (약어):** 첫 등장 시 풀네임 병기(예: "ATS(Applicant Tracking System)") 추가.
|
|
45
|
+
- **C12 (형식):** `export_cover_letter` 등으로 `.docx`/텍스트 PDF로 내보내도록 안내. 스캔 PDF는 텍스트 레이어 버전으로 재생성.
|
|
46
|
+
|
|
47
|
+
재검증 후에도 C8이 JD 미제공으로 N/A면, 사용자에게 대상 공고를 `save_job_posting`으로 저장하도록 안내하고 커버리지 측정을 보류한다. 모든 항목 통과 시에만 "ATS 호환 확인됨"으로 표시하고 대시보드 링크(`http://127.0.0.1:4319`)를 안내한다.
|
|
48
|
+
|
|
49
|
+
## 4. 출처 (Provenance)
|
|
50
|
+
|
|
51
|
+
- **Jobscan — ATS Formatting Mistakes / Match Rate Guidance** — 표·다단·헤더/푸터·아이콘 금지, 연락처 본문 배치, 표준 헤더, 매치율 권장 75%+(스위트스폿 80%), 채용담당자 ~99.7% ATS 사용 통계 근거 · https://www.jobscan.co/blog/ats-formatting-mistakes/ , https://support.jobscan.co/hc/en-us/articles/41334833854099-What-match-rate-should-I-aim-for
|
|
52
|
+
- **Jobscan — Tables & Columns Break Parsing** — 선형 파싱·다단/표가 텍스트 순서를 깨 "word salad"가 되는 메커니즘 근거 · https://www.jobscan.co/blog/resume-tables-columns-ats/
|
|
53
|
+
- **Indeed Career Advice — How To Write an ATS Resume** — 표준 섹션 헤더(Work Experience/Education/Skills), 역연대기 형식, JD 키워드 자연 통합, 표준 폰트 권장 근거 · https://www.indeed.com/career-advice/resumes-cover-letters/ats-resume-template
|
|
54
|
+
- **Ohio Northern University Career Center — ATS Resume Guide (PDF)** — 대학 커리어센터 1차 자료: 표준 헤더·다단/헤더푸터/텍스트박스 회피·연락처 본문 배치 근거 · https://my.onu.edu/sites/default/files/applicant_tracking_system_resume_guide.pdf
|
|
55
|
+
- **프레임워크 근거:** 위 항목들의 공통 합의(single-column, standard headings, body-placed contact, JD keyword coverage)를 셀 수 있는 카운트/비율 체크로 환원함. 날짜 형식·약어 병기·스터핑 임계치는 Jobscan/Indeed 권고를 정규식·카운트 규칙으로 운영화한 것.
|
|
56
|
+
|
|
57
|
+
## 5. Phase B 힌트
|
|
58
|
+
|
|
59
|
+
- **MCP 도구 아이디어:** `get_verifier({ id: "ats-compat" })` — 본 루브릭(JSON 형태의 C1–C12 + 패턴/임계치)을 연결된 AI에게 그대로 serve. 보조로 `get_jd_keywords({ job_id })`가 저장된 공고에서 상위 하드스킬/직무명 키워드 집합(N)을 추출해 C8/C9/C10 카운트의 입력으로 제공.
|
|
60
|
+
- **데이터 형태 힌트:**
|
|
61
|
+
- 루브릭 항목: `{ id, check, pass_rule, measure: { type: "count"|"ratio"|"presence"|"regex", target, threshold, pattern } }` 배열.
|
|
62
|
+
- JD 키워드 페이로드: `{ job_id, hard_skills: string[], job_titles: string[], abbreviations: [{ short, long }] }` — C8(분모 N), C9, C11 입력.
|
|
63
|
+
- 검증 결과 로그: `{ artifact_id, results: [{ id, passed, observed, threshold }], overall_pass, revised: boolean }` — 루프 재검증 추적용. `save_fit_analysis`/버전 메타에 첨부 가능.
|
|
64
|
+
- 표준 헤더 화이트리스트와 허용 날짜 패턴은 도구가 상수로 보유해 클라이언트별 일관성 확보.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 교차 산출물 일관성 (Cross-artifact consistency) — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 커리어 산출물(이력서·자소서·면접 답변·LinkedIn 등)을 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사는 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
## 1. 목적
|
|
6
|
+
|
|
7
|
+
지원자의 여러 산출물(resume ↔ cover letter ↔ 면접 스토리 ↔ LinkedIn)이 **하나의 일관된 사실 서사**를 말하도록 보장한다. 채용 담당자는 "triangulation(삼각 대조)" — 즉 이력서를 LinkedIn·자소서·공개 데이터와 교차 대조해 진위를 확인한다. 따라서 **날짜·직함·회사명·학력·수치·핵심 서사**가 산출물 간에 모순되면 즉시 의심·탈락·평판 손상으로 이어진다.
|
|
8
|
+
|
|
9
|
+
이 검증기가 보장하는 것:
|
|
10
|
+
|
|
11
|
+
- **단일 진실 원천(single source of truth):** 이력서를 기준으로 다른 산출물이 이력서와 **모순되지 않음**(확장·강조는 허용, 변조·충돌은 불가).
|
|
12
|
+
- **사실 앵커의 동일성:** 같은 사실(입·퇴사 월/년, 직함, 회사명, 학위·졸업년도, 정량 수치)이 모든 산출물에서 **같은 값**으로 나타남.
|
|
13
|
+
- **서사의 무모순:** 면접 스토리·자소서가 이력서의 타임라인·역할과 충돌하지 않음(예: 이력서엔 없는 "팀 리드" 주장 등).
|
|
14
|
+
|
|
15
|
+
이 검증기는 *문장이 좋은가*(품질)가 아니라 *서로 어긋나지 않는가*(정합성)만 본다. LLM 없이도 값 비교·존재 여부·개수로 다수 항목을 셀 수 있게 설계했다.
|
|
16
|
+
|
|
17
|
+
## 2. 검사 항목
|
|
18
|
+
|
|
19
|
+
> 측정 단위: "사실 앵커(fact anchor)" = (회사명, 직함, 시작 월/년, 종료 월/년, 정량 수치, 학위명, 졸업년도) 같은 **비교 가능한 토큰**. 검사는 산출물별로 앵커를 추출해 **쌍대 비교(pairwise)** 한 뒤 불일치 개수를 센다.
|
|
20
|
+
|
|
21
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게) |
|
|
22
|
+
|----|------|-----------|------------------------|
|
|
23
|
+
| C1 | 회사명 일치 | 모든 산출물에서 동일 회사를 **같은 표기**(정규화 후)로 지칭. 불일치 0건 | 각 산출물의 회사명 토큰을 추출→소문자·법인접미사(Inc/Ltd/㈜) 정규화 후 집합 비교. 다른 표기로 같은 시기를 지칭하는 쌍 개수 = 0 |
|
|
24
|
+
| C2 | 직함 일치 | 같은 재직 기간의 직함이 산출물 간 동일하거나 명시적 승진 progression. 모순 0건 | (회사, 기간)별 직함 문자열 비교. 동일 (회사,기간)에 서로 다른 직함이 매핑된 쌍 개수 = 0 |
|
|
25
|
+
| C3 | 입·퇴사 날짜 일치 | **월/년 단위**까지 동일. 허용 오차 0개월(채용 배경조사 기준 권장) | 각 경력의 (start MM/YYYY, end MM/YYYY)를 산출물 간 비교. 월 단위 차이가 있는 쌍 개수 = 0. (연도만 적힌 산출물이 있으면 "월 누락" 경고 1건 카운트) |
|
|
26
|
+
| C4 | 타임라인 무모순(중복/공백) | 경력 구간이 산출물 간 동일한 정렬·중복 여부. 한 산출물에만 존재하는 미설명 공백/중복 0건 | 경력 구간을 시간순 정렬 후 산출물 간 구간 집합 차이(set difference) 개수 = 0. 6개월 이상 미설명 공백은 별도 플래그(개수) |
|
|
27
|
+
| C5 | 학력 일치 | 학위명·전공·학교·졸업년도가 모든 산출물에서 동일. 불일치 0건 | (학교, 학위, 졸업년도) 튜플을 산출물 간 비교. 불일치 튜플 쌍 개수 = 0 |
|
|
28
|
+
| C6 | 정량 수치 일치 | 같은 성과의 수치(%, 금액, 인원, 기간)가 산출물 간 동일. 충돌 0건 | 각 산출물에서 숫자+단위 패턴(`\d+%`, 금액, `\d+명` 등) 추출→같은 성과에 매핑된 수치쌍 비교. 값이 다른 쌍 개수 = 0 |
|
|
29
|
+
| C7 | 면접 스토리 앵커 정합 | 면접 STAR 스토리의 회사·역할·시기·수치가 이력서 앵커에 **존재**. 이력서에 없는 신규 사실 0건 | 면접 답변에서 추출한 (회사/역할/수치) 앵커 중 이력서 앵커 집합에 없는 항목 개수 = 0 |
|
|
30
|
+
| C8 | 핵심 스킬/키워드 정합 | 자소서·면접에서 강조한 핵심 역량 상위 N개가 이력서 스킬 섹션에 존재. 누락 ≤ 1 | 자소서/면접 빈출 역량 토큰 상위 N(기본 5)을 이력서 스킬 토큰 집합과 대조→미존재 개수 ≤ 1 |
|
|
31
|
+
| C9 | 연락처/식별자 일치 | 이름·이메일·전화·LinkedIn URL 등 식별 정보가 산출물 간 동일. 불일치 0건 | 정규식으로 식별자 추출 후 정확 일치 비교. 불일치 필드 개수 = 0 |
|
|
32
|
+
| C10 | 산출물 커버리지 | 비교 가능한 산출물이 **2종 이상** 존재해야 교차검증이 의미. 1종이면 "교차검증 불가" 경고 | 입력으로 제공된 산출물 종류 개수 ≥ 2 (미달 시 검사 skip + 경고 1건) |
|
|
33
|
+
|
|
34
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
35
|
+
|
|
36
|
+
검사 결과는 **불일치 앵커 목록**으로 반환한다. 각 항목은 `{check_id, artifact_a, artifact_b, value_a, value_b, severity}` 형태.
|
|
37
|
+
|
|
38
|
+
- **C1·C2·C3·C5·C9 불일치(critical):** 즉시 **이력서를 진실 원천으로 고정**하고, 충돌하는 다른 산출물을 이력서 값에 맞춰 수정 지시. 단, 이력서 자체가 사실과 다르다는 사용자 확인이 있으면 이력서를 먼저 정정한 뒤 전 산출물 동기화. 수정 후 **C1~C9 재검증**(불일치 0 될 때까지 루프).
|
|
39
|
+
- **C4 공백/중복(warning):** 6개월+ 미설명 공백은 사용자에게 설명(연수·육아·창업 등) 요청 → 모든 산출물에 동일 문구로 반영. 재검증.
|
|
40
|
+
- **C6 수치 충돌(critical):** 어느 수치가 사실인지 사용자에게 확인 → 단일 값으로 통일(과장 금지). 사실·고유명사·수치는 보존이 원칙이므로 임의 평균·추정 금지. 재검증.
|
|
41
|
+
- **C7 신규 사실(critical):** 면접 스토리에만 등장하는 사실은 (a) 이력서에 추가하거나 (b) 스토리에서 제거. 두 산출물이 같은 앵커를 공유할 때까지 루프.
|
|
42
|
+
- **C8 키워드 누락(warning):** 핵심 역량을 이력서 스킬 섹션에 추가하거나, 자소서/면접에서 과대 강조를 완화. 재검증.
|
|
43
|
+
- **C10 커버리지 부족:** 검사를 막지 말고 "교차검증 불가, 산출물 1종만 존재"를 사용자에게 안내. 다른 산출물 추가 시 재실행.
|
|
44
|
+
- **종료 조건:** critical 불일치 0건 + warning은 사용자 확인 완료. 통과 시 `save_fit_analysis`/`save_cover_letter_version` 등 다음 단계로 진행, 대시보드 링크 안내.
|
|
45
|
+
|
|
46
|
+
## 4. 출처 (Provenance)
|
|
47
|
+
|
|
48
|
+
- **Triangulation / 단일 진실 원천 원칙** — 채용 담당자가 이력서를 LinkedIn·자소서·공개 데이터와 교차 대조해 진위 확인. Washington State University, Carson College of Business 커리어 가이드 · https://business.wsu.edu/resumes-references-and-cover-letters/
|
|
49
|
+
- **Resume·Cover Letter·LinkedIn 동기화(직함/날짜/회사명/수치 일치)** — The Interview Guys, "Resume, Cover Letter, and LinkedIn Profile Synchronization" · https://blog.theinterviewguys.com/resume-cover-letter-and-linkedin-profile-synchronization/
|
|
50
|
+
- **월/년 단위 날짜 일치, 수치 충돌(40% vs 75%) 신뢰 훼손** — Resume Worded, "Should Your LinkedIn Match Your Resume?" · https://resumeworded.com/should-linkedin-match-resume-key-advice
|
|
51
|
+
- **Employment verification(직함·재직기간·역할 확인)** — LinkedIn Business, HR Glossary: Employment Verification · https://business.linkedin.com/in/en/hire/resources/hr-glossary/employment-verification
|
|
52
|
+
- **STAR 프레임워크(Situation·Task·Action·Result)와 정량 결과** — MIT Career Advising & Professional Development(CAPD), "The STAR Method for Behavioral Interviews" · https://capd.mit.edu/resources/the-star-method-for-behavioral-interviews/
|
|
53
|
+
- **이력서/자소서 STAR bullet과 면접 스토리 정합(같은 정량 성과 재사용)** — San Francisco State University, Career & Leadership Development: Resume/Cover Letter/LinkedIn · https://career.sfsu.edu/resume-cv-cover-letter-linkedin
|
|
54
|
+
|
|
55
|
+
## 5. Phase B 힌트
|
|
56
|
+
|
|
57
|
+
- **MCP 도구 아이디어:** `get_verifier({ id: "consistency" })` — 이 루브릭(JSON 직렬화) 반환. `run_consistency_check({ artifacts })` — 연결된 AI가 추출한 앵커 배열을 받아 C1~C10 쌍대 비교를 코드로 수행(LLM 불필요)하고 불일치 목록 반환.
|
|
58
|
+
- **데이터 형태 힌트:**
|
|
59
|
+
- 입력: `{ artifacts: [{ type: "resume"|"cover_letter"|"interview"|"linkedin", anchors: { companies, titles, dates, education, metrics, identifiers, skills } }] }`. 앵커 추출(자연어→구조화)은 연결된 AI 담당, 비교 로직은 결정적 코드.
|
|
60
|
+
- 출력: `{ pass: bool, criticals: [...], warnings: [...], mismatches: [{check_id, artifact_a, artifact_b, value_a, value_b}] }`.
|
|
61
|
+
- 저장: `get_application_context`가 이미 프로필·대표 이력서·기존 자소서를 반환하므로, 그 앵커를 캐시해 두면 신규 산출물만 추가 비교 가능. 결과는 `save_fit_analysis`의 일부 메타로 보관 가능.
|