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.
Files changed (137) hide show
  1. package/AGENTS.md +33 -0
  2. package/INSTALL.md +230 -0
  3. package/LICENSE +21 -0
  4. package/README.md +532 -0
  5. package/THIRD_PARTY_NOTICES.md +57 -0
  6. package/bin/careermate.mjs +77 -0
  7. package/dist/career-os/README.md +78 -0
  8. package/dist/career-os/eop/cover-letter.md +46 -0
  9. package/dist/career-os/eop/fit-analysis.md +48 -0
  10. package/dist/career-os/eop/interview-prep.md +39 -0
  11. package/dist/career-os/eop/job-analysis.md +42 -0
  12. package/dist/career-os/eop/profile-extraction.md +37 -0
  13. package/dist/career-os/knowledge/ats.md +131 -0
  14. package/dist/career-os/knowledge/company-research.md +137 -0
  15. package/dist/career-os/knowledge/cover-letter.md +135 -0
  16. package/dist/career-os/knowledge/fit-matching.md +121 -0
  17. package/dist/career-os/knowledge/human-writing.md +118 -0
  18. package/dist/career-os/knowledge/interview-behavioral.md +132 -0
  19. package/dist/career-os/knowledge/interview-technical.md +126 -0
  20. package/dist/career-os/knowledge/linkedin-profile.md +152 -0
  21. package/dist/career-os/knowledge/networking-referrals.md +166 -0
  22. package/dist/career-os/knowledge/offer-evaluation-decision.md +121 -0
  23. package/dist/career-os/knowledge/onboarding-first-90-days.md +126 -0
  24. package/dist/career-os/knowledge/portfolio.md +121 -0
  25. package/dist/career-os/knowledge/recruiter-screen.md +105 -0
  26. package/dist/career-os/knowledge/rejection-triage-iteration.md +115 -0
  27. package/dist/career-os/knowledge/resume.md +123 -0
  28. package/dist/career-os/knowledge/salary-negotiation.md +123 -0
  29. package/dist/career-os/knowledge/verifiers/ats-compat.md +64 -0
  30. package/dist/career-os/knowledge/verifiers/consistency.md +61 -0
  31. package/dist/career-os/knowledge/verifiers/human-voice.md +82 -0
  32. package/dist/career-os/knowledge/verifiers/recency-staleness.md +72 -0
  33. package/dist/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
  34. package/dist/career-os/knowledge/verifiers/truthfulness.md +67 -0
  35. package/dist/doctor.mjs +79094 -0
  36. package/dist/mcp.mjs +96108 -0
  37. package/dist/migrate.mjs +4735 -0
  38. package/dist/pdf.worker.min.mjs +28 -0
  39. package/dist/public/app.js +150 -0
  40. package/dist/public/fonts/PretendardVariable.woff2 +0 -0
  41. package/dist/public/icon-180.png +0 -0
  42. package/dist/public/index.html +52 -0
  43. package/dist/public/lib.js +394 -0
  44. package/dist/public/pages/applications.js +107 -0
  45. package/dist/public/pages/documents.js +467 -0
  46. package/dist/public/pages/home.js +261 -0
  47. package/dist/public/pages/interview.js +227 -0
  48. package/dist/public/pages/jobs.js +493 -0
  49. package/dist/public/pages/profile.js +556 -0
  50. package/dist/public/pages/settings.js +240 -0
  51. package/dist/public/styles.css +498 -0
  52. package/dist/site/analytics.js +97 -0
  53. package/dist/site/favicon.svg +1 -0
  54. package/dist/site/fonts/PretendardVariable.woff2 +0 -0
  55. package/dist/site/icon-180.png +0 -0
  56. package/dist/site/icon-512.png +0 -0
  57. package/dist/site/index.html +598 -0
  58. package/dist/site/landing.js +54 -0
  59. package/dist/site/llms-install.txt +217 -0
  60. package/dist/site/robots.txt +4 -0
  61. package/dist/site/sitemap.xml +21 -0
  62. package/dist/site/start.html +326 -0
  63. package/dist/site/style.css +550 -0
  64. package/dist/site/vercel.json +20 -0
  65. package/dist/web.mjs +46852 -0
  66. package/docs/FAQ.md +101 -0
  67. package/docs/MCP_TOOLS.md +311 -0
  68. package/docs/README.md +28 -0
  69. package/docs/START_WORKFLOW.md +137 -0
  70. package/docs/SUPPORTED_AI_APPS.md +112 -0
  71. package/docs/WORKFLOWS.md +202 -0
  72. package/docs/career-os/README.md +78 -0
  73. package/docs/career-os/eop/cover-letter.md +46 -0
  74. package/docs/career-os/eop/fit-analysis.md +48 -0
  75. package/docs/career-os/eop/interview-prep.md +39 -0
  76. package/docs/career-os/eop/job-analysis.md +42 -0
  77. package/docs/career-os/eop/profile-extraction.md +37 -0
  78. package/docs/career-os/knowledge/ats.md +131 -0
  79. package/docs/career-os/knowledge/company-research.md +137 -0
  80. package/docs/career-os/knowledge/cover-letter.md +135 -0
  81. package/docs/career-os/knowledge/fit-matching.md +121 -0
  82. package/docs/career-os/knowledge/human-writing.md +118 -0
  83. package/docs/career-os/knowledge/interview-behavioral.md +132 -0
  84. package/docs/career-os/knowledge/interview-technical.md +126 -0
  85. package/docs/career-os/knowledge/linkedin-profile.md +152 -0
  86. package/docs/career-os/knowledge/networking-referrals.md +166 -0
  87. package/docs/career-os/knowledge/offer-evaluation-decision.md +121 -0
  88. package/docs/career-os/knowledge/onboarding-first-90-days.md +126 -0
  89. package/docs/career-os/knowledge/portfolio.md +121 -0
  90. package/docs/career-os/knowledge/recruiter-screen.md +105 -0
  91. package/docs/career-os/knowledge/rejection-triage-iteration.md +115 -0
  92. package/docs/career-os/knowledge/resume.md +123 -0
  93. package/docs/career-os/knowledge/salary-negotiation.md +123 -0
  94. package/docs/career-os/knowledge/verifiers/ats-compat.md +64 -0
  95. package/docs/career-os/knowledge/verifiers/consistency.md +61 -0
  96. package/docs/career-os/knowledge/verifiers/human-voice.md +82 -0
  97. package/docs/career-os/knowledge/verifiers/recency-staleness.md +72 -0
  98. package/docs/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
  99. package/docs/career-os/knowledge/verifiers/truthfulness.md +67 -0
  100. package/package.json +89 -0
  101. package/packages/core/src/context.ts +74 -0
  102. package/packages/core/src/index.ts +8 -0
  103. package/packages/core/src/onboarding.ts +81 -0
  104. package/packages/core/src/services.ts +187 -0
  105. package/packages/core/src/summary.ts +104 -0
  106. package/packages/db/src/connection.ts +76 -0
  107. package/packages/db/src/index.ts +23 -0
  108. package/packages/db/src/paths.ts +52 -0
  109. package/packages/db/src/repositories.ts +891 -0
  110. package/packages/db/src/runtime.ts +58 -0
  111. package/packages/db/src/schema.ts +307 -0
  112. package/packages/exporters/src/html.ts +110 -0
  113. package/packages/exporters/src/index.ts +364 -0
  114. package/packages/exporters/src/markdown.ts +178 -0
  115. package/packages/knowledge/src/index.ts +168 -0
  116. package/packages/mcp-tools/src/bridge.ts +106 -0
  117. package/packages/mcp-tools/src/index.ts +17 -0
  118. package/packages/mcp-tools/src/result.ts +49 -0
  119. package/packages/mcp-tools/src/tools.ts +747 -0
  120. package/packages/mcp-tools/src/update.ts +330 -0
  121. package/packages/parsers/src/documents.ts +533 -0
  122. package/packages/parsers/src/html.ts +86 -0
  123. package/packages/parsers/src/index.ts +231 -0
  124. package/packages/parsers/src/keywords.ts +151 -0
  125. package/packages/prompts/src/humanize.ts +59 -0
  126. package/packages/prompts/src/index.ts +82 -0
  127. package/packages/prompts/src/install.ts +43 -0
  128. package/packages/prompts/src/onboarding.ts +35 -0
  129. package/packages/prompts/src/system.ts +57 -0
  130. package/packages/shared/src/build-info.ts +22 -0
  131. package/packages/shared/src/enums.ts +142 -0
  132. package/packages/shared/src/index.ts +19 -0
  133. package/packages/shared/src/schemas.ts +453 -0
  134. package/packages/workflows/src/definitions.ts +109 -0
  135. package/packages/workflows/src/index.ts +39 -0
  136. package/scripts/init.ts +371 -0
  137. package/tsconfig.json +32 -0
@@ -0,0 +1,121 @@
1
+ # 포트폴리오 / Portfolio — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ 포트폴리오는 "예쁘게 보여주기"가 아니라 **채용 의사결정자가 짧은 시간에 지원자의 문제 해결 능력을 신뢰하게 만드는 증거 모음**이다. 핵심은 다섯 축이다: (1) `problem → approach → impact` 3막 서사, (2) 직무에 맞는 3~6개 선별(큐레이션), (3) 팀 작업에서 "내가 실제로 한 것"을 1인칭으로 분리, (4) 정량 결과(숫자·전후 비교)로 임팩트 입증, (5) 직군별 규범(eng/design/PM/data) 준수. CareerMate는 LLM이 없으므로, 작성은 연결된 외부 AI가 하고 CareerMate는 그 결과를 **구조화 레코드(`PortfolioItem`)로 저장**한 뒤 **LLM 없이 결정적으로 셀 수 있는 lint 루브릭**으로 검증한다. 따라서 아래 루브릭은 자유 텍스트가 아니라 **구조화 필드를 입력 전제**로 설계되어 있다.
8
+
9
+ ## 2. 플레이북
10
+
11
+ ### 원칙
12
+
13
+ - **각 항목을 `problem(문제) → approach/역할(접근) → impact(결과)` 3막으로 쓰고, 결과물 스크린샷보다 "왜 그 결정을 했는가"에 분량을 더 쓴다.** — 채용 담당자는 결과물 자체가 아니라 트레이드오프를 다루는 방식으로 미래 협업을 상상한다. why가 빠진 케이스는 "예쁘지만 기억에 안 남는" 항목이 된다. _(출처: uxfol.io UX Case Study Structure)_
14
+ - **직무에 맞는 강한 항목으로 선별한다(가이드 기본값 3~6개, 단 경력 레벨·직군에 따라 조정).** 10개 이상의 얕은 항목보다 4개의 깊은 항목이 낫다. 다만 시니어/풀스택은 다직군 7~8개가 정상이고, 신입은 2개가 최선일 수 있다 — 개수는 **하드 실패가 아니라 soft-warning**이다. _(출처: icreatives Portfolio Review / Hakia Developer Portfolio Guide — SEO 콘텐츠, 4절 신뢰도 주석 참조)_
15
+ - **팀 프로젝트에서는 `my_role` 필드에 본인이 소유한 결정·구현·산출물을 동작 동사(설계/구현/주도/분석)로 명시한다.** `we/우리`로만 서술하면 개인 기여가 불명확해진다. 더 위험한 것은 **팀 작업을 `solo`로 태깅해 단독 기여로 포장하는 과대표현**이므로, 임팩트 수치마다 측정 범위(`method`)를 함께 적어 귀속을 분명히 한다. _(출처: thecrit.co Portfolio Project Examples)_
16
+ - **임팩트는 가능한 한 숫자 + 단위 + 전후(before→after) 비교로 표현한다(예: 전환율 3.2%→4.7%, +47%, 처리시간 -40%).** 숫자가 없으면 비교 기준·규모·범위(사용자 수·기간·트래픽)라도 제시한다. **이 수치는 반드시 사용자가 제공한 실측이어야 하며, AI가 그럴듯하게 지어내선 안 된다.** _(출처: The Muse STAR Method)_
17
+ - **직군별 규범을 따른다.** eng = 실행 가능한 README(목적·문제·실행법·라이브 데모/스크린샷) + 깔끔한 커밋 + 최소 1개 end-to-end 프로젝트; design = 리서치→결정→반복의 why; PM = 북극성/가드레일/진단 지표로 가치 정의; data = train/test 분리·복수 평가지표·온라인 A/B·가드레일·비즈니스 임팩트 정량화. _(출처: Flatiron README best practices / Meta Analytics DS framework)_
18
+ - **작업 당시의 제약(constraints)을 한 줄이라도 명시한다** — 마감, 기존 브랜드/legacy 시스템, 기술적 제약, 이해관계자/NDA. 제약 속 결정을 보여줘 맥락 인지를 입증한다. _(출처: icreatives Portfolio Review)_
19
+ - **한국 채용 맥락의 '경력기술서'는 포트폴리오 역할을 하되 형식이 다르다.** 회사·기간·역할·성과를 표/불릿로 쓰는 경우가 많아 산문 3막을 강제하면 정상 경력기술서를 오탐한다. 따라서 3막 검증은 **`item_type`이 `case_study`인 항목에만** 적용하고, `경력기술서` 유형은 필드(역할·성과·기간) non-empty로만 검증한다. 사실·수치·고유명사는 **절대 과장·날조하지 않는다**(AGENTS.md 프라임 디렉티브). _(출처: AGENTS.md 사실 보존 규칙)_
20
+
21
+ ### Do
22
+
23
+ - 각 항목을 `problem → approach → impact` 구조화 필드로 채우고, 맨 위에 한 줄 요약(무엇을 / 누구를 위해 / 결과)을 둔다.
24
+ - 팀 프로젝트는 `my_role` 필드에 본인 기여를 동작 동사로 1인칭 서술하고, 임팩트 수치마다 측정 범위·방법(`method`)을 적어 귀속을 분명히 한다.
25
+ - 임팩트를 숫자 + 단위 + 전후 비교로 표기한다(예: 전환율 3.2%→4.7%, +47%). 사내/NDA로 절대수치를 못 쓰면 **상대값·비율·범위·배수**로 대체한다(예: "전환율 약 1.5배", "두 자릿수 % 개선").
26
+ - 직군에 맞는 증거를 `evidence` 링크로 첨부한다: eng = 라이브 데모/repo/README, design = 리서치 근거·트레이드오프, PM = 지표 정의, data = 평가지표·A/B·노트북.
27
+ - 지원 직무(`target_job_ids`)의 핵심 스킬 키워드와 항목을 매핑해 "왜 이 항목이 이 직무에 적합한가"를 드러낸다(1차 ATS/스크리너 게이트).
28
+ - 최근 2~3년 내 항목을 우선 배치하고, `date`/기간 필드를 채워 신선도를 드러낸다.
29
+ - 케이스 스터디는 핵심 800~1,500단어 범위로 유지하되, **엔지니어 README·한국 경력기술서는 불릿 중심으로 훨씬 짧게** 쓴다(직군별 분량 규범이 다르다).
30
+
31
+ ### Don't
32
+
33
+ - 최종 결과물 스크린샷만 나열하고 "왜 그렇게 결정했는지"를 생략하지 않는다.
34
+ - `우리/we`로만 서술해 개인 기여를 불명확하게 두지 않는다. **반대로 팀 성과를 `solo`로 태깅해 단독 기여인 양 포장하지도 않는다.**
35
+ - 직무와 무관한 얕은 항목을 분량 채우기로 끼워 가장 강한 항목을 희석하지 않는다.
36
+ - "성능을 크게 개선했다 / 안정적으로 운영했다 / 성공적으로 최적화했다" 같은 **모호 형용사로 끝내지 않는다**(수치·범위 없이). 숫자가 있어도 형용사 슬롭을 함께 쓰지 않는다.
37
+ - **입력 사실에 없는 숫자·성과·회사명·고유명사를 지어내거나 과장하지 않는다.** 환산·추정 손실액 같은 "그럴듯한 정량화"도 실측 근거 없이는 금지.
38
+ - README/실행법/라이브 데모 없이 코드 저장소 링크만 던지지 않는다(eng). **죽은 데모 링크·private 404는 최악 신호**다.
39
+ - 제약·트레이드오프 없는 "완벽한 이상적 결과"만 제시하지 않는다.
40
+ - 기술 스택 약어를 맥락 없이 나열하지 않는다. 5년 전 노후 스택(예: jQuery)만으로 채운 포트폴리오는 즉시 감점된다.
41
+
42
+ ### 워크드 예시 (Before → After)
43
+
44
+ > 아래 after의 모든 수치는 **사용자가 제공한 실측 데이터**라는 전제다. AI가 임의로 만든 숫자가 아니다. 예시의 정합성(예: 이탈률 감소폭과 완료율 증가폭)도 사용자 입력에서 검증되어야 한다.
45
+
46
+ 1. **Before:** 결제 페이지를 새로 디자인했습니다. 우리는 사용자 경험을 개선하기 위해 UI를 현대화하고 결제 흐름을 단순화했습니다. 깔끔하고 직관적인 디자인으로 만들었습니다. (스크린샷 4장)
47
+ **After:** **문제:** 결제 단계 이탈률 68%(업계 평균 50% 상회). **제약:** 기존 PG 연동 변경 불가, 2주 스프린트. **내 역할(my_role):** 퍼널 분석으로 '주소 입력'을 이탈 핫스팟으로 특정, 3단계→1단계 통합 흐름을 설계·프로토타이핑하고 5명 사용성 테스트를 진행. **결과:** 결제 이탈률 68%→41%(-27%p, A/B 2주 p<0.05). 이 -27%p는 실측이며, 매출 환산은 사용자가 제공한 가정이 있을 때만 기재. [Figma 링크 / 테스트 노트]
48
+ **왜 더 나은가:** before는 `we`·형용사 위주로 개인 기여·임팩트가 안 보인다. after는 문제를 숫자로 정의, 제약 명시, `my_role`로 본인 기여를 동작 동사로 분리, 결과를 전후 비교 + 통계로 정량화한다. (환산 매출은 사실 추적이 안 되면 빼는 것이 원칙.)
49
+
50
+ 2. **Before:** 프로젝트: TaskFlow — 할 일 관리 앱. React, Node.js, MongoDB로 만들었습니다. GitHub: github.com/user/taskflow
51
+ **After:** **TaskFlow** — 팀 할 일 관리 앱(풀스택, 1인 개발). **문제:** 소규모 팀이 Slack에 흩어진 할 일을 추적 못 함. **접근:** React+Node+MongoDB로 실시간 동기화(WebSocket), 낙관적 업데이트로 체감 지연 제거. **임팩트/규모:** 베타 사용자 120명, 일 평균 작업 1,400건, p95 응답 180ms. **트레이드오프:** 동시 편집 충돌을 CRDT 대신 last-write-wins + 버전 벡터로 해결(문서화). [라이브 데모(200 확인)] [README: 30초 실행법·아키텍처] [데모 영상 90초]
52
+ **왜 더 나은가:** before는 스택 나열 + repo 링크뿐이라 목적·실행법·임팩트를 알 수 없다. after는 README/라이브 데모/실행법을 앞세우고(eng 규범), 문제→접근→임팩트를 정량화하며, 기술적 트레이드오프를 드러낸다. `WebSocket`·`CRDT`는 허용되는 기술 용어이지 날조 고유명사가 아니다.
53
+
54
+ 3. **Before:** 추천 모델을 개발해 추천 품질을 향상시켰습니다. 다양한 알고리즘을 실험하고 가장 좋은 것을 선택했습니다.
55
+ **After:** **문제:** 신규 사용자 첫 주 이탈률 54%, 콜드스타트가 인기상품 위주라 관련성 낮음. **접근:** train/test 시계열 분리, 베이스라인(인기순) 대비 협업필터링·콘텐츠기반·하이브리드 3종 비교, 오프라인 NDCG@10·Recall@20 + 온라인 A/B 평가. **결과:** 하이브리드가 베이스라인 대비 CTR +15%, 첫 주 리텐션 54%→61%(+7%p). **가드레일:** 추천 다양성(카탈로그 커버리지) 비저하 확인. (연 매출 기여 추정치는 사용자 제공 가정이 있을 때만.) [노트북 / 지표 대시보드]
56
+ **왜 더 나은가:** before는 평가지표·비즈니스 임팩트가 전무하다. after는 data 직군 규범(train/test 분리·복수 평가지표·온라인 A/B·가드레일)을 따르고 모델 성능을 비즈니스 지표로 번역한다.
57
+
58
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
59
+
60
+ > **전제(중요):** 모든 루브릭은 자유 텍스트가 아니라 **`PortfolioItem` 구조화 레코드 배열**을 입력으로 받는다. "항목(item) 경계"는 **레코드 1개 = 1 항목**으로 못박는다. 자유 텍스트는 루브릭 대상이 아니며, 먼저 `save_portfolio_item`으로 구조화해야 한다. 이로써 대부분 체크가 키워드 매칭 대신 **필드 non-empty / 패턴 카운트**로 결정적(deterministic)·LLM-프리가 된다.
61
+
62
+ | ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) |
63
+ |----|-----------|-----------|--------------------------------|
64
+ | R1 PF-STRUCT-3ACT | (case_study 유형) 3막 필드가 모두 채워졌는가 | `item_type=case_study`인 항목 100%가 `problem`·`approach`·`impact` 필드 non-empty | 각 레코드의 세 필드가 빈 문자열/공백이 아닌지 `len(trim)>0` 카운트. `경력기술서` 유형은 대상에서 제외(역할·성과·기간 필드 non-empty로 대체 검증). |
65
+ | R2 PF-QUANT-IMPACT | 임팩트에 **의미 있는** 정량 지표가 있는가 | 각 항목 `impact[]`의 80% 이상에 단위·전후·증감 신호가 동반된 숫자 1개 이상 | `impact` 필드/배열에서만 매칭. **맨정수(bare integer) 단독은 불통과.** 통과 패턴: `\d+%`, `\d+\s*→\s*\d+`, `[+\-]\d+`, `x\d+`/`\d+배`, 단위 부착(`ms`,`초`,`원`,`건`,`p95`). 연도/버전/인원수(예: `2026`, `React 18`, `5명`)는 impact 필드 밖이면 자동 배제. |
66
+ | R3 PF-ROLE-OWN | 본인 기여가 동작 동사로 명시되고 귀속이 분명한가 | 모든 항목에 `my_role` non-empty + 동작 동사(설계/구현/주도/분석/개발/리드/built/led/designed/analyzed) ≥1, 그리고 팀 성과 수치엔 `method`/범위 동반 | `my_role` 길이 + 동사 사전 매칭(한/영). 한국어는 대명사 없이 `~했다/담당/주도`도 1인칭으로 인정. **solo 과대표현 가드:** `role_tag=solo`인데 `impact[].method`에 팀/공동 신호가 있으면 확인 플래그. |
67
+ | R4 PF-CURATION-COUNT | 항목 수가 큐레이션 범위인가 (soft) | 권장 3~6개. 범위 밖이면 **경고**(하드 실패 아님) | 레코드 개수 `n` 카운트. `n<3` 또는 `n>6`이면 warning + 경력 레벨/직군 다양성 메타로 맥락 판단 권고. 신입 2개·시니어 다직군 7~8개는 정상으로 허용. |
68
+ | R5 PF-CONSTRAINT | 각 항목에 제약이 명시되는가 | 항목의 70% 이상에 `constraints[]` 길이 ≥1 | `constraints` 배열 비어있지 않은 항목 비율 카운트. NDA/사내 항목은 "수치 제한" 자체가 제약으로 인정. |
69
+ | R6 PF-ENG-RUNNABLE | (eng 항목) 실행 가능성 증거가 있는가 | `domain=eng` 항목 100%에 `evidence` 중 `type∈{readme,demo,repo}` ≥1 + 실행법/데모 신호 | `evidence[].type` 카운트 + `approach`/`evidence`에 `README`·`실행/run/install/setup`·`demo/데모` 패턴 존재. eng인데 미충족 0건이면 통과. |
70
+ | R7 PF-LINK-FORMAT | 증거 링크가 형식·도달성 기준을 통과하는가 | `evidence[].url` 100%가 유효 URL 형식 + private/placeholder 패턴 아님. (네트워크 허용 시 HEAD 200) | URL 정규식 검증 + `localhost`/`example.com`/`TODO`/`<...>` 같은 placeholder 차단. **외부 네트워크 금지 정책 안에서는 형식·private 패턴 검사만**, 사용자가 허용하면 HEAD 요청으로 200 확인. |
71
+ | R8 PF-NO-VAGUE | 모호 형용사 슬롭이 없는가 | 모호 형용사 단독(또는 형용사 동반) 결과 문장 0건 | 확장 사전 매칭 — 한국어: `크게/대폭/현저히/많이/훨씬/확연히/눈에 띄게/유의미하게/큰 폭으로/효율적으로/안정적으로/성공적으로/원활하게/최적화/개선되었다/향상시켰다`; 영어: `significantly/greatly/substantially/dramatically/notably/seamlessly/improved/enhanced/streamlined/optimized`. 문장 분할은 `[.!?。\n]` 기준. **숫자가 있어도 형용사가 동반되면 경고**(숫자만 깔끔히 두도록 유도). |
72
+ | R9 PF-JD-MATCH | 대상 직무 키워드를 항목이 커버하는가 | `target_job_ids`가 있는 항목에서 직무 핵심 스킬 토큰 중 항목 텍스트 등장 비율 ≥40% | `get_application_context`의 직무 스킬 토큰 집합 ∩ 항목(`problem`+`approach`+`my_role`+`impact`) 토큰 집합 / 직무 토큰 수. 1차 ATS 게이트 신호. |
73
+ | R10 PF-RECENCY | 최신성 신호가 있는가 (soft) | 항목의 50% 이상이 최근 3년 내(`date` 필드 기준) | `date`/기간 필드 파싱 후 `현재연도 - year <= 3` 비율. 미충족 시 "노후 스택 감점 위험" 경고(하드 실패 아님). |
74
+ | R11 PF-WORDCOUNT | 항목 분량이 직군 규범 내인가 (soft) | case_study 800~1,500단어; eng README/경력기술서는 별도 하한만 적용 | `word_count` 필드(또는 토큰 카운트)로 측정. case_study가 <400(깊이 부족) 또는 >2,500(편집력 부족)이면 경고. eng/경력기술서는 산문 상한 미적용. |
75
+ | R12 PF-FACT-PRESERVE | 입력에 없는 수치/고유명사가 새로 생성되지 않았는가 | **자동 합격 판정 없음 — human/AI 확인 플래그(검토 필요).** | **이 체크는 순수 set-diff로 자동 통과/실패를 내지 않는다**(환산·반올림·단위변환·기술용어로 거짓양성 폭발, NER은 LLM 작업). 좁힌 결정적 검사만 수행: 사용자가 명시 입력한 `impact[].before`/`impact[].after` 필드값이 산출 텍스트에 그대로 등장하는지 literal-match. 그 외 신규 수치·고유명사는 "검토 필요" 목록으로 모아 사람/AI에게 토스. |
76
+
77
+ **주요 실패 모드:**
78
+ - **루브릭 측정 사기(가장 위험):** R12를 set-diff로 "0건 통과" 처리하는 것 — 거짓양성 폭탄. 반드시 확인 플래그로만 둔다.
79
+ - **거짓양성 카운트:** R2에서 연도·버전·인원수를 임팩트로 오인 → impact 필드로 매칭 범위를 한정하고 맨정수를 배제.
80
+ - **항목 경계 붕괴:** 자유 텍스트를 입력하면 R1·R4·R3가 무의미 → 반드시 구조화 레코드 전제.
81
+ - **한국어/직군 누락:** R8 사전이 얕거나 R1을 경력기술서에 강제하면 정상 산출물 오탐 → 사전 확장 + `item_type` 분기.
82
+ - **과대표현 무력화:** 팀 성과를 `solo`로 포장 → R3의 method/범위 동반 + solo 가드로 플래그.
83
+
84
+ ## 4. 출처 (Provenance)
85
+
86
+ > **신뢰도 주석:** 아래 다수(uxfol.io·uxpilot.ai·hakia·icreatives·interviewmaster.ai·thecrit.co)는 **SEO 콘텐츠/도구 마케팅 블로그**로 표본·연도·방법론이 명시된 1차 채용 설문이 아니다. "hiring manager surveys"라는 라벨은 근거를 과대표현하므로 **방향성 참고용**으로만 쓰고, "톱티어 담당자가 가장 선호" 같은 단정은 피한다. STAR(The Muse)·Meta 프레임워크가 상대적으로 단단하다. (원본의 PMC7924487 role-clarity 논문 인용은 주장과 논문 사이 간극이 커 **제거**했다.)
87
+
88
+ - **uxfol.io — UX Case Study Structure & Template** — case-study 3막 구조, why 중심 서술, 분량 가이드 · https://blog.uxfol.io/ux-case-study-structure/ _(SEO 콘텐츠)_
89
+ - **uxpilot.ai — Product Design Portfolios Analyzed** — 깊은 케이스 우선, 결과물보다 why·정량 임팩트 · https://uxpilot.ai/blogs/product-design-portfolio-case-studies _(도구 블로그)_
90
+ - **icreatives — 7-Step Portfolio Review Process** — 큐레이션=편집 판단력, 제약 명시=맥락 인지 · https://www.icreatives.com/iblog/the-7-step-portfolio-review-process-every-creative-hiring-manager-needs/ _(SEO 콘텐츠)_
91
+ - **Hakia — Developer Portfolio Guide** — polished 소수 항목 우위, 선별의 신호 가치 · https://hakia.com/skills/building-portfolio/ _(SEO 콘텐츠)_
92
+ - **Flatiron School — GitHub & README best practices** — eng 규범: README·라이브 데모·실행법·깔끔한 커밋 · https://flatironschool.com/blog/github-profile-and-git-practices-for-job-seekers/
93
+ - **The Muse — STAR Interview Method** — Result 정량화('Numbers are always impactful'), 전후 비교 · https://www.themuse.com/advice/star-interview-method _(상대적 단단)_
94
+ - **Meta Analytics — DS Framework for Product Strategy** — PM/data 규범: 북극성·가드레일·진단 지표, 비즈니스 임팩트 정량화 · https://medium.com/@AnalyticsAtMeta/data-scientists-framework-for-navigating-product-strategy-as-data-leaders-2eb62b20f505 _(상대적 단단)_
95
+ - **interviewmaster.ai — Build a Data Science Portfolio** — data 규범: train/test 분리·복수 평가지표·A/B · https://www.interviewmaster.ai/content/how-to-build-a-data-science-portfolio-the-complete-2025-guide _(도구 블로그)_
96
+ - **thecrit.co — Portfolio Project Examples** — 'we'만 쓰면 개인 기여 불명확 → 역할 명확화 필요 · https://www.thecrit.co/resources/portfolio-project-examples _(SEO 콘텐츠)_
97
+ - **AGENTS.md (CareerMate 프라임 디렉티브)** — 사실·수치·고유명사 보존, 과장·날조 금지 · 저장소 내부
98
+
99
+ ## 5. Phase B 힌트 (아키텍처로 연결)
100
+
101
+ - **MCP 도구 아이디어:**
102
+ - `get_portfolio_guide(role?, item_type?)` — 직군(eng/design/PM/data)·유형(case_study/repo/경력기술서)에 맞춘 3막 템플릿 + 직군별 증거 체크리스트 + 정량화 예시 + 루브릭을 반환하는 read-only 지식 도구.
103
+ - `save_portfolio_item(...)` — 아래 `PortfolioItem`을 **구조화 필드로 강제** 저장(자유 텍스트 금지 → 항목 경계 문제 해소, 루브릭 결정성 확보).
104
+ - `lint_portfolio(target_job_id?)` — R1~R12를 LLM 없이 패턴/카운트/필드-non-empty로 실행. **R12·R4·R10·R11은 pass/fail 대신 `warn` 또는 `needs_review`** 상태를 반환(자동 합격 판정 금지). `get_application_context`와 연동해 R9(직무 적합도)를 산출.
105
+ - **데이터 형태 힌트:**
106
+ ```
107
+ PortfolioItem {
108
+ id, title,
109
+ item_type: 'case_study' | 'repo' | '경력기술서',
110
+ role_tag: 'solo' | 'team' | 'lead',
111
+ domain: 'eng' | 'design' | 'pm' | 'data' | 'other',
112
+ problem: string, approach: string, my_role: string,
113
+ impact: [{ metric, before?, after, unit, method? }], // before/after는 사용자 실측만
114
+ constraints: string[],
115
+ evidence: [{ type:'demo'|'repo'|'readme'|'figma'|'notebook'|'video', url }],
116
+ target_job_ids: string[],
117
+ date: string, // 신선도(R10)
118
+ word_count: int // 분량(R11)
119
+ }
120
+ ```
121
+ 루브릭 결과는 `RubricResult { checkId, status:'pass'|'fail'|'warn'|'needs_review', measured:number|string, failingItemIds:string[] }[]` 형태로, **R12와 soft 체크는 절대 `pass`를 자동 부여하지 않는다.** 모든 산출은 구조화 필드의 정규식/카운트/필드-존재 검사로 결정적으로 계산된다.
@@ -0,0 +1,105 @@
1
+ # 리크루터 스크린·지원서 사전문항 / Recruiter Screen & Application Screening — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ behavioral·technical 인터뷰 앞에 놓인 **첫 게이트**를 통과하는 도메인이다. 두 갈래로 나뉜다. (1) 비동기 자동 게이트 = 지원서 사전문항(knockout questions: 근무가능일·최소연봉·근무지·취업자격·자격증을 yes/no·단답으로 묻는 ATS 필터), (2) 동기 인간 게이트 = 15~30분 전화/화상 리크루터 스크린(지원동기·기대연봉·가용 타임라인·근무지·현재 상태 확인). 핵심 원리는 **"knockout은 정직·정확하게 통과하되 불필요한 self-knockout을 피하고, 인간 스크린에서는 정보 비대칭이 클 때만 첫 숫자를 디플렉션하면서 탈락 사유(red flag)를 제거해 다음 라운드로 넘어가는 것"**이다. 이 도메인은 숫자를 **깎는** 곳이 아니라 **탈락당하지 않는** 곳이며, 오퍼 후 협상은 salary-negotiation 도메인으로 위임한다.
8
+
9
+ ## 2. 플레이북
10
+
11
+ ### 원칙
12
+
13
+ - **(knockout 정직성 + self-knockout 회피)** knockout 사전문항은 반드시 정직하게, 그러나 불필요한 self-knockout을 피하도록 '현재 시점' 프레이밍으로 답하라. 단 '현재 시점 프레이밍'은 **검증 가능한 사실의 정확한 진술**에 한정되며, 사실 자체를 다르게 적는 것은 허위다. 리스크는 항목별로 다르다: 비자·자격증·학위·연차처럼 **객관·검증가능**한 항목의 허위는 합격 후 적발 시 철회 사유이고, 입사가능일·희망연봉처럼 **협상가능·주관**적 항목은 현실값+'협의 가능'으로 적는 것이 정상 절차이지 철회 리스크가 아니다. — _(출처: Duke/Buffalo/Interstride 커리어센터, HireTruffle/Recruitee)_
14
+ - **(비자/취업자격 2문항 분리는 US-specific)** 미국 ATS(Workday 등)의 표준 2문항 — '지금 합법적으로 일할 자격이 있는가(Q1)'와 '지금 또는 미래에 sponsorship이 필요한가(Q2)' — 은 **분리해서** 답하라. OPT/CPT/취업가능 비자 보유자는 Q1=YES, Q2는 '현재 권한 잔여기간 동안은 비용·sponsorship 불필요'로 정확히 구분한다. **이 2문항 프레임은 미국 전용이다.** UK는 CoS(Certificate of Sponsorship) 단일 문항, EU는 Blue Card, 한국은 체류자격 코드 기재 방식이라 문항 구조 자체가 다르므로 로케일에 맞게 적용하라. — _(출처: Duke/Buffalo/Interstride 1차)_
15
+ - **(기대연봉: 디플렉션은 정보 비대칭이 클 때만 — salary-negotiation R9 상속)** 기대연봉 문항이 **직무 정보가 충분치 않은 단계**에 나오면 디플렉션 피벗을 한 번 쓰되, **시장 정보를 충분히 확보했다면 디플렉션 대신 리서치 기반 레인지로 먼저 앵커하는 편이 낫다**. '먼저 숫자=무조건 진다'는 과일반화이며, salary-negotiation.md가 인용하는 Galinsky & Mussweiler(JPSP 2001) 실증은 정보가 충분할 때 먼저 데이터 앵커한 쪽의 결과가 더 좋음을 보인다. 디플렉션/레인지 분기와 walk-away 보호의 **전술 권위는 salary-negotiation 도메인에 있고**, 이 도메인은 그 조건부 규칙을 **상속**해 게이트 통과 맥락에만 적용한다. — _(출처: Robert Half; salary-negotiation.md R9 / Galinsky & Mussweiler 2001)_
16
+ - **(양식 강제 입력: 레인지 하단 또는 내규)** 양식이 숫자를 강제하면 공란·회피는 ATS 0처리·탈락을 부른다. 경력직은 '리서치된 시장 레인지의 하단 근처', 한국 신입·공채는 '회사 내규에 따름'을 적되, 본인 walk-away 미만은 절대 적지 마라. 동시에 회사 연봉테이블을 크게 초과한 희망연봉도 self-knockout이다(테이블 데이터가 없어 자동 측정 불가 → 사용자에게 직접 확인). — _(출처: Jobkorea/Superookie 한국 실무; Robert Half)_
17
+ - **(리크루터 스크린 = 탈락 사유 제거 라운드)** 리크루터 스크린(15~30분)은 적합도 평가가 아니라 'must-have 확인 + red flag 제거' 라운드다. 4개 축에 각 1~2문장 준비답을 만들어라: (a) 지원동기(외적 보상만이 아니라 직무·회사 리서치 근거 1개 이상), (b) 가용 타임라인/입사가능일, (c) 근무지/리로케이션/원격 선호, (d) 현재 상태·이직 사유(전 고용주 비방 금지). — _(출처: Recruitee/Pin/HireHive; SHRM Sample Interview Questions 1차)_
18
+ - **(이직 사유·갭은 간결+전향적)** 이직 사유와 공백은 '회피'가 아니라 '간결+전향적' 프레임으로 답하라. 전 직장·상사 비방을 피하고 사유를 '성장·역할 정렬'로 1~2문장에 담는다. 회피 자체가 은폐 의심 red flag이므로 짧고 정직하게 닫는 게 회피보다 안전하다. 백채널 레퍼런스 체크가 이직 사유를 교차검증할 수 있으므로 사실과 어긋나지 않게 한다. — _(출처: Recruitee 35 red flags; My Career GPS)_
19
+ - **(입사가능일: 통지기간은 법정 강제가 아님)** 입사가능일은 '협상 가능한 현실값'을 제시하라. 재직 중이면 통지기간을 반영하되 — 통지기간은 **법정 의무가 아니라** 취업규칙/계약/민법 제660조(한국)·계약상 notice period(영국·EU)·at-will 2주 관행(미국 일부)의 영향이므로 본인 계약을 기준으로 한다 — 양식엔 '협의 가능' 여지를 남긴다. 사실이 아닌 '즉시 가능'은 적지 마라. — _(출처: HireTruffle/Recruitee; 한국 표준 지원양식 '희망근무기간')_
20
+ - **(한국 게이트: 공채 자소서·증빙·체류자격)** 한국은 ATS knockout보다 **자사양식 필수항목 + 공채 자기소개서**가 1차 게이트다. ① 공채 자기소개서(지원동기·입사후포부·직무역량 문항, 글자수 제한, 블라인드/NCS 기반, 유사도·AI작성 필터)는 **cover-letter 도메인으로 라우팅**한다(이 도메인은 사전문항·스크린만 담당). ② 처우협의 단계의 진짜 함정은 '희망연봉 칸'이 아니라 **현재연봉 증빙(원천징수영수증) 요구**다 — 제출은 법적 의무가 아니며 거부 가능하고, 시장가 프레이밍으로 응대한다(전술 권위는 salary-negotiation). ③ 외국인은 체류자격(E7/E9/F2/F5/F6 등)을 정확히 기재하되 **본인 체류자격 확인을 전제**한다: F5(영주)는 취업 제한 거의 없음, F6(결혼이민)은 혼인관계 존속 등 유지조건·갱신 이슈가 있을 수 있고, E7은 직무 대체불가성 입증이 **고용주 측 사증 요건**이지 지원자가 양식 기재로 통과시키는 것이 아니다. — _(출처: 찾기쉬운 생활법령정보 1차; KB/IMMIKOREA; Jobkorea)_
21
+ - **(ATS는 가중치 스코어링일 수 있음)** 모든 knockout이 하드 yes/no=즉시 reject는 아니다. preferred(우대) 항목은 가중치 스코어링이라 한 항목 미달이 곧 탈락은 아니다. required vs preferred를 구분해 과최적화(우대 항목까지 거짓 최적화)를 피하라. — _(출처: HireTruffle knockout 가이드; 실무 ATS 운영)_
22
+
23
+ ### Do
24
+
25
+ - 미국 양식의 비자 2문항을 '근무자격(Q1)'과 'sponsorship 필요(Q2, 현재 시점 기준)'로 분리해 정확히 답한다. 다른 로케일(UK CoS·EU Blue Card·한국 체류자격 코드)은 해당 양식 구조대로 답한다.
26
+ - 기대연봉이 직무 대화 전이면 한 번 디플렉션 피벗을 쓰고, 정보가 충분하거나 양식 강제 칸이면 리서치 기반 레인지 하단(경력직) 또는 '회사 내규에 따름'(신입·공채)을 적는다.
27
+ - 리크루터 스크린 전에 4축(동기·타임라인·근무지·현재상태/이직사유) 각 1~2문장 답을 미리 작성한다.
28
+ - 지원동기에 직무·회사 리서치 근거(제품·과제·고유명사)를 1개 이상 포함해 '외적 보상만'으로 들리지 않게 한다.
29
+ - 입사가능일은 본인 계약상 통지기간을 반영한 현실값+'협의 가능' 여지로 적는다.
30
+ - 이직 사유·갭은 짧고 전향적으로 닫고, 전 고용주·동료 비방을 절대 하지 않는다(백채널 레퍼런스 교차검증 가능성 고려).
31
+ - knockout 답은 항상 정직하되, 검증 가능한 사실 한정으로 '현재 시점' 프레이밍해 불필요한 self-knockout을 피한다.
32
+ - 한국 외국인 지원자는 체류자격(E7/E9/F2/F5/F6 등)과 직무 적격성을 양식에 정확히 기재하되 본인 체류자격을 먼저 확인한다.
33
+ - 현재연봉 증빙(원천징수영수증) 요구를 받으면 의무가 아님을 알고 시장가 프레이밍으로 응대한다(한국 처우협의 빈출 게이트).
34
+ - 스크린 말미 질문은 단계에 맞춘다: 리크루터(HR) 스크린에선 다음 단계·일정·팀 구성 같은 로지스틱스 질문 1개로 충분하고, 깊은 직무 질문은 hiring manager 라운드로 미룬다.
35
+ - 모든 게이트 답변을 `get_application_context`가 제공하는 프로필·`desired_conditions`·이력과 대조해 일관성을 확인한다.
36
+
37
+ ### Don't
38
+
39
+ - 기대연봉 양식 칸을 공란·회피로 두기(ATS 0처리·탈락 유발).
40
+ - 직무 정보·시장 정보가 충분한데도 계속 숫자를 디플렉션하기('회피적'으로 읽혀 역효과 — 정보 충분 시 레인지 앵커가 낫다).
41
+ - 본인 walk-away 미만, 또는 회사 연봉테이블을 크게 초과한 희망연봉 적기(양방향 self-knockout).
42
+ - 미래에 sponsorship이 필요하다는 이유로, 현재 권한이 있는데도 미국 Q1/Q2를 뭉뚱그려 보수적으로 표시하기.
43
+ - 검증가능 항목(비자·자격증·학위·연차)에 허위 기재(합격 후 적발 시 철회).
44
+ - 사실이 아닌 '즉시 입사 가능'을 적기(통지기간 충돌로 신뢰 붕괴).
45
+ - 이직 사유·갭 질문을 회피하거나 얼버무리기(은폐 의심 red flag).
46
+ - 전 상사·회사·동료 비방하기(태도 우려로 탈락).
47
+ - 지원동기를 연봉·타이틀·복지 등 외적 보상만으로 설명하기.
48
+ - 리크루터 스크린을 협상 라운드로 착각해 오퍼 전에 숫자를 깎으려 들기(협상은 salary-negotiation 도메인).
49
+ - 한국 공채 자기소개서 작성을 이 도메인에서 처리하기(cover-letter 도메인으로 라우팅).
50
+ - 비자 2문항 프레임을 한국·UK·EU 양식에 그대로 강요하기(US-specific).
51
+
52
+ ### 워크드 예시 (Before → After)
53
+
54
+ 1. **Before:** (전화 스크린, 직무 설명 전) "저는 8천만 원 정도 생각하고 있습니다."
55
+ **After:** "역할의 범위와 책임, 팀 구성을 먼저 이해하고 싶습니다. 혹시 이 포지션에 책정된 연봉 범위를 공유해 주실 수 있을까요? 서로 정렬되는지 확인하는 데 도움이 될 것 같습니다." (양식 강제 입력이거나 이미 직무 정보가 충분하면) "시장 조사 기준으로는 7,800~9,000만 원 범위가 합리적이라고 보고 있습니다."
56
+ **왜 더 나은가:** 정보 비대칭이 큰 단계에서 첫 점값을 던지면 천장이 고정된다. 디플렉션으로 회사 밴드를 먼저 끌어내되, **정보가 충분하거나 양식이 강제하면** 디플렉션을 고집하지 않고 리서치 레인지(하단이 walk-away 이상)를 제시한다 — salary-negotiation의 조건부 규칙을 상속해 '회피적'으로 읽히는 역효과를 피한다.
57
+
58
+ 2. **Before:** (미국 ATS, OPT 2년 잔여 F-1 학생) Q1 '합법적 근무자격 있는가?'→NO, Q2 'sponsorship 필요한가?'→YES (미래에 필요하니 둘 다 보수적으로).
59
+ **After:** Q1 '합법적 근무자격 있는가?'→YES (OPT 권한 보유). Q2 'sponsorship 필요한가?'→ 면접 단계면 "현재 OPT로 N개월간 추가 절차·비용 없이 근무 가능하며, 이후 H-1B로 연장될 수 있습니다"로 맥락 첨부. 양식 yes/no 강제면 정책에 맞춰 정직하게 답하되 메모 칸에 OPT 기간 명시. (이 2문항은 미국 양식에만 적용; 한국 양식이면 체류자격 코드 기재로 대체)
60
+ **왜 더 나은가:** 두 문항을 뭉뚱그려 보수적으로 답하면 현재 권한이 있는데도 ATS가 자동 reject 라우팅한다. Q1은 현재 OPT 권한으로 YES가 정확하고, Q2는 '현재 무비용 근무 가능' 맥락으로 self-knockout을 피하면서 미래 필요성을 정직하게 드러낸다.
61
+
62
+ 3. **Before:** (리크루터 스크린 '왜 이직하려 하세요?') "지금 회사가 연봉도 짜고 팀장이 마이크로매니징이 심해서 도저히 못 버티겠어요."
63
+ **After:** "현재 역할에서 핵심 역량은 충분히 쌓았고, 이제 더 큰 책임과 제품 임팩트를 맡고 싶어 찾고 있습니다. 이 포지션의 데이터 플랫폼 확장 과제가 제가 다음으로 키우고 싶은 부분과 정확히 맞닿아 지원했습니다."
64
+ **왜 더 나은가:** 전 직장·상사 비방은 리크루터가 가장 흔히 떨어뜨리는 태도 red flag이고, 백채널 레퍼런스로 교차검증될 수 있다. 같은 동기를 전향적으로 담고 회사 리서치 근거(데이터 플랫폼 과제)를 붙이면 '외적 보상 중심 동기'와 '비방' 두 red flag를 동시에 제거한다.
65
+
66
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
67
+
68
+ > **데이터 모델 주의:** 현재 코드의 `ApplicationContext`(packages/core/src/context.ts, packages/shared/src/schemas.ts)에는 `hardGate(minYears·visaStatus·location·salaryFloor)` 정형 필드가 **없다**. 연봉·지역·근무형태는 `profile.desired_conditions`라는 **단일 자유텍스트**(schemas.ts:100·116)에만 존재한다. 따라서 walk-away·비자상태·근무지를 저장값과 1:1 수치 비교하는 검사는 자유텍스트 파싱이 필요해 **현재로선 완전한 det가 아니다([ai]/H로 강등)**. 정형 `hardGate` 4필드 신설은 Phase B 선행 의존성이다(§5). fit-matching.md와 마찬가지로 `hardGate`는 AI가 도출하는 **라벨**이지 저장된 정형 입력이 아니다.
69
+
70
+ | ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게; 의미판단 필요시 [ai]/H 표기) |
71
+ |----|-----------|-----------|--------------------------------|
72
+ | R1 | 정보 부족 단계에서 기대연봉에 '맨숫자'를 먼저 던지지 않았는가 | 단일 점값이 아니라 디플렉션 문구 또는 min~max 레인지 형태가 존재 | [det] 텍스트에서 '범위/range/~/물결표' 또는 디플렉션 핵심구('먼저 이해/책정된 범위/공유해 주실') 패턴 존재 + 콤마·단위 붙은 단일 숫자만 단독 등장하는지 정규식 검사 |
73
+ | R2 | **지금이 디플렉션해도 되는 시점(정보 충분도)인가** | 정보 충분 단계인데 디플렉션만 반복하지 않음(충분 시 레인지 앵커) | [ai]/H — 채널(말 vs 양식)·정보충분도는 의미판단. det로 잴 수 없음을 정직하게 표기. 보조 [det]: 양식 강제 칸인데 디플렉션 문구만 있고 숫자/레인지 없으면 fail |
74
+ | R3 | 양식 기재 최소/희망연봉이 walk-away 미만이 아닌가 | 기재 숫자 >= 사용자 연봉하한 | [ai]/H(현재) — 연봉하한이 `desired_conditions` 자유텍스트에만 있어 파싱 필요. 정형 `salaryFloor` 신설 시 [det] 수치 비교(>=)로 승격 가능 |
75
+ | R4 | (한국 self-knockout) 희망연봉이 회사 내규를 크게 초과하지 않는가 | 내규 대비 과도 초과 아님 | **측정 불가/H** — 회사 연봉테이블 데이터가 없어 자동 측정 불가. 사용자에게 직접 확인하도록 안내 |
76
+ | R5 | (미국 양식) 비자 답이 Q1(근무자격)·Q2(sponsorship) 2문항으로 분리되고 권한 보유 시 Q1=YES인가 | 근무자격 1건 + sponsorship 1건 = 2개 응답 존재 | [det] 응답 개수 카운트==2(미국 로케일일 때만 적용). Q1과 비자상태 모순 룰체크는 [ai]/H(비자상태가 자유텍스트라 파싱 필요). 미래 맥락 적절성은 [ai]/H |
77
+ | R6 | 리크루터 스크린 준비답이 4축을 모두 커버했는가 | motivation/timeline/location/reason 4개 키 존재 | [det] 준비답 객체 키 존재 카운트 == 4 |
78
+ | R7 | 이직 사유·현재상태 답에 전 고용주 비방 표현이 없는가 | 비방 사전 패턴 0건 | [det] 보조 — 키워드 사전('짜다/마이크로매니징/못 버티/싫/최악/toxic/incompetent') 매칭 0건. 단 우회 단어가 많아 거짓음성 큼 → **핵심 판정은 [ai]/H** |
79
+ | R8 | 지원동기가 외적 보상만이 아니라 리서치 근거를 1개 이상 포함했는가 | 회사/제품/직무 고유명사·구체 과제 1개 이상, 외적보상 단독 아님 | [ai]/H — 고유명사 1토큰 카운트는 거짓양성/음성이 커 신뢰 낮음. 진정성·근거성은 의미판단 |
80
+ | R9 | 입사가능일이 통지기간을 반영하고 허위 '즉시'가 아닌가 | 재직 중일 때 '즉시/오늘' 단독이 아니라 통지기간 반영·'협의 가능' 존재 | [det] 보조 — 현재상태=재직이면 '즉시/오늘'만 단독 등장 시 fail, '협의/통지/N주·N개월' 존재 시 pass(현재상태가 자유텍스트면 [ai]/H) |
81
+ | R10 | 산출물이 로케일에 맞는 항목·관행을 적용했는가 | 한국: 병역/취업자격/내규연봉/증빙 반영; 미국: 비자 2문항/ATS; UK/EU: CoS/Blue Card — 해당 마커 1개 이상 | [det] 로케일 플래그별 기대 항목 키 존재 카운트>=1 |
82
+ | R11 | 한국 공채 자기소개서를 이 도메인에서 작성하지 않고 cover-letter로 라우팅했는가 | 자소서 본문 생성 0건, 라우팅 안내 존재 | [det] 산출물에 자소서 장문 본문 부재 + 'cover-letter 도메인' 라우팅 마커 존재 여부 |
83
+
84
+ **주요 실패 모드:**
85
+ - **데이터 모델 허구화** — `hardGate` 정형 필드가 있다고 가정하고 det 검사를 돌리면 비교 대상이 없어 무조건 통과/오류. 정형 필드 신설 전까지 R3·R5·R9의 저장값 비교는 [ai]/H다.
86
+ - **인접 도메인 충돌** — '먼저 숫자=무조건 진다'로 후퇴해 salary-negotiation의 조건부 규칙(정보 충분 시 앵커)과 모순되는 조언을 내는 것. 디플렉션/레인지 분기는 salary-negotiation에 위임된 단일 권위를 따른다.
87
+ - **로케일 일반화** — 미국 비자 2문항을 한국/UK/EU에 강요하거나, 한국 통지기간·증빙·자소서 게이트를 빠뜨리는 것.
88
+ - **det 가장(假裝)** — 비방 사전·고유명사 토큰·정보충분도를 det처럼 제시. R2·R4·R7·R8은 핵심 판정이 [ai]/H임을 정직하게 표기해야 한다.
89
+
90
+ ## 4. 출처 (Provenance)
91
+
92
+ - **SHRM 2025 Talent Acquisition Benchmarking & Sample Interview Questions** — 리크루터 스크린 표준 질문셋(1차). '공고당 평균 250 지원·knockout 40%+ 자동 탈락' 수치는 **단일 출처·산업/문항수 의존이 커 인과가 아닌 방향성 신호로만** 차용(fit-matching의 TalentWorks 60% 강등과 동일 취급). https://www.shrm.org/topics-tools/tools/interview-questions
93
+ - **Robert Half — "What's Your Expected Salary?" (2026 Salary Guide 연계)** — 디플렉션 피벗·레인지 vs 디플렉션 분기·리서치 앵커링(2차/벤더, 실무 신뢰). https://www.roberthalf.com/us/en/insights/career-development/how-to-answer-whats-your-expected-salary
94
+ - **Duke / University at Buffalo / Interstride — Work Authorization & Sponsorship 가이드** — 미국 비자 2문항 분리 로직(F-1/OPT/CPT는 Q1=YES, Q2는 현재 무비용 프레이밍), 정직성 원칙(1차/대학 커리어센터). https://careerhub.students.duke.edu/blog/2025/10/03/how-to-answer-will-you-now-or-in-the-future-require-sponsorship-to-work-in-the-us-2/
95
+ - **Recruitee / Pin / HireHive / My Career GPS — 리크루터 스크린 구조·red flag** — 15~30분 구조, 평가 4축, 대표 red flag(외적보상 동기·질문회피·갭은폐·비방)(2차/벤더, 실무). https://recruitee.com/blog/interview-red-flags
96
+ - **HireTruffle / Recruitee — Knockout Questions in Hiring** — knockout 정의(yes/no·자동 reject 라우팅), required vs preferred 가중치 스코어링(2차/벤더). https://www.hiretruffle.com/blog/knockout-questions
97
+ - **Jobkorea / Superookie — 이력서 희망연봉·자사양식·증빙 가이드** — 한국 '회사 내규에 따름' 기본값, 내규 초과 self-knockout, '희망근무기간' 필수항목, 원천징수영수증 요구(2차/한국 실무). https://www.jobkorea.co.kr/goodjob/tip/view?News_No=19603
98
+ - **찾기쉬운 생활법령정보 / KB·IMMIKOREA — 외국인 취업·체류자격(E7/E9/F계열)** — 한국 외국인 채용 게이트=체류자격 적격성; F5는 취업 거의 무제한, F6은 유지조건 존재, E7 대체불가성은 고용주 측 사증 요건(1차/정부 법령·2차/행정사). https://easylaw.go.kr/CSP/CnpClsMain.laf?popMenu=ov&csmSeq=3&ccfNo=1&cciNo=1&cnpClsNo=1
99
+ - **salary-negotiation.md (CareerMate 인접 도메인) / Galinsky & Mussweiler (JPSP 2001)** — 디플렉션/레인지/walk-away 전술의 **단일 권위 출처**. 정보 충분 시 먼저 앵커가 유리하다는 실증(1차/피어리뷰 + 내부 도메인 위임). (저장소 내부: docs/career-os/knowledge/salary-negotiation.md)
100
+
101
+ ## 5. Phase B 힌트 (아키텍처로 연결)
102
+
103
+ - **선행 의존성(필수):** 이 도메인의 det 루브릭(R3·R5·R9·R10)이 실제로 작동하려면, 현재 `profile.desired_conditions` 단일 자유텍스트(schemas.ts:100)에 묻혀 있는 게이트 입력을 **정형 `hardGate { minYears, visaStatus, location, salaryFloor }`로 신설**하고 `ApplicationContext`에 추가하는 작업이 선행되어야 한다. 그 전까지 이 검사들은 [ai]/H(자유텍스트 파싱)다. 이 신설은 fit-matching 도메인의 hardGate **라벨**과 의미가 다르므로(여기선 저장 입력), 단일 출처화 시 이름 충돌을 정리해야 한다.
104
+ - **MCP 도구 아이디어:** `get_screening_kit(job_id)` — 대상 공고와 프로필을 받아 (a) 그 공고의 knockout 사전문항 체크리스트(근무가능일·최소연봉·근무지·취업자격·자격증)를 채워 반환하고(정형 hardGate 신설 후 대조), (b) 리크루터 스크린 4축(동기·타임라인·근무지·이직사유) 준비답 슬롯과 기대연봉 스크립트를 **로케일(KR/US/UK/EU)별**로 serve한다. 디플렉션/레인지 결정은 salary-negotiation 도메인 로직을 **호출/위임**해 중복·충돌을 막는다. 보조로 `save_screening_answers(job_id, answers)`로 저장하고, `validate_screening(job_id)`로 **det 가능 항목만**(4축 키 개수·비방 사전·재직 시 '즉시' 단독·미국 비자 2응답 개수·로케일 마커) 룰체크하며, 저장값 비교가 필요한 항목은 정형 hardGate 신설 전까지 'H(수동 확인)'로 표시한다.
105
+ - **데이터 형태 힌트:** `ScreeningKit { jobId, locale: 'KR'|'US'|'UK'|'EU', hardGate?: { minYears, visaStatus, location, salaryFloor }, knockout: [{ field, prompt, suggestedAnswer, sourceFromHardGate: bool, honestyRisk: 'objective'|'negotiable' }], salaryScript: { mode: 'deflect'|'range'|'company_policy', deflectionPivot?, rangeLow?, rangeHigh?, delegatedTo: 'salary-negotiation' }, screenAxes: { motivation, timeline, location, reasonForLeaving }, routing: { coverLetterToCoverLetterDomain: bool }, validation: { detViolations: [{ checkId, detail }], manualChecks: [{ checkId, reason }] } }`. `hardGate`는 신설 전까지 옵셔널이며, `honestyRisk`로 객관/협상가능 항목의 철회 리스크를 구분한다. answers는 application 레코드에 묶여 8단계 상태('planned→applied' 전환 직전 게이트)의 스냅샷으로 저장한다.
@@ -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
+ ```