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,78 @@
1
+ # Career-OS — 외부 LLM 실행 진입점 (단일 입구)
2
+
3
+ > ✅ **상태(2026-06): 이 라우팅·EOP 적용은 이제 런타임에 배선되어 있다(Phase B-1).** 연결된 AI는 `get_workflow_guide`로 작업별 실행 절차(EOP)와 적용할 플레이북·검증기 순서를 받고, `get_playbook`/`get_verifier`로 이 폴더의 지식을 실제로 받아 적용한다. `get_application_context`도 `recommended_route`·`verifier_sequence`·`next_tool`를 함께 돌려준다. 아직 구현하지 않은 범위(B-2: det 점수 계산·저장 게이트·마이그레이션)와 패키지 구조는 [`implementation/README.md`](https://github.com/osntak/careermate/blob/main/docs/career-os/implementation/README.md) 참고.
4
+
5
+ > **여기서 시작하라.** CareerMate는 수동적 지식이 아니라, 외부 AI가 사용자 대면 결과를 내기 전에 적용해야 하는
6
+ > **실행형 플레이북(EOP)·검증 루브릭·라우팅·출력 계약**을 제공한다. 두뇌=외부 AI(당신), CareerMate=실행 기질(substrate). 내부 LLM 없음.
7
+ >
8
+ > **구조:** `README.md`(이 파일 = 단일 입구) → `eop/<기능>.md`(실행 절차) → `knowledge/`(정본 깊은 지식).
9
+ > 보조(런타임 아님): `validation/`(리서치 출처 + 다중 LLM(cross-vendor) 검증 하니스) · `implementation/`(CareerMate 개발자용 Phase B 내부 설계).
10
+ >
11
+ > EOP(Expert Operating Procedure) = 한 기능을 *시니어 전문가처럼* 수행하는 실행 절차. 검증된 리서치(`validation/research/`)에 근거하고
12
+ > [`validation/PROTOCOL.md`](https://github.com/osntak/careermate/blob/main/docs/career-os/validation/PROTOCOL.md)의 다중 LLM(cross-vendor) 교차검증으로 단단해진다.
13
+
14
+ ## 0. 절대 원칙 — 근거 우선순위
15
+ ```
16
+ 현실 > 검증된 증거(저장 사용자 데이터·공식 자료) > 신뢰할 리서치 > CareerMate 플레이북/EOP > 프롬프트 지시 > 모델 직관
17
+ ```
18
+ EOP·이 문서를 맹신하지 말 것. **저장된 사용자 데이터나 공식 자료가 EOP와 충돌하면 사실을 우선**하고 사용자에게 확인한다. 사실·수치·고유명사는 절대 발명하지 않는다.
19
+
20
+ **사실 3분류 (모든 생성·분석에 적용 — 가장 흔한 실패):**
21
+ 1. **내가 한 일·내 수치** → 저장 데이터에 앵커되어야 한다. 없으면 쓰지 않는다.
22
+ 2. **일반 도메인 지식**(개념·방법론·베스트프랙티스) → 활용해도 되나 '내가 한 일'처럼 말하지 말고 **'개념 설명' 또는 '입사 후 제안'으로 명시 분리**한다.
23
+ 3. **출처 밖 구체 수치/맥락**(통계·신뢰구간·측정 환경·내부 지표·상황 묘사) → **발명 금지**. 그럴듯해도 면접·검증에서 무너진다.
24
+
25
+ 미확인 항목은 산출물 본문이 아니라 **별도 '확인 필요' 메모**로 분리한다.
26
+
27
+ ## 1. 사용자 요청 분류 → EOP 라우팅
28
+ 요청 의도를 분류하고 해당 EOP를 연다(복합 요청은 순서대로 체이닝):
29
+
30
+ | 사용자가 이렇게 말하면 | 주 EOP | 보조 |
31
+ |---|---|---|
32
+ | "이 공고 적합도/나랑 맞아?/지원할 만해?" | [fit-analysis](eop/fit-analysis.md) | job-analysis, profile-extraction |
33
+ | "이 공고 분석/뜯어줘", "무슨 회사·직무·레벨이야" | [job-analysis](eop/job-analysis.md) | — |
34
+ | "이력서/경력 정리·입력", "기본정보 채워" | [profile-extraction](eop/profile-extraction.md) | — |
35
+ | "자소서/자기소개서/지원동기/커버레터 써줘·고쳐줘" | [cover-letter](eop/cover-letter.md) | company-research, human-writing, fit-analysis |
36
+ | "면접 준비/예상질문/모의면접" | [interview-prep](eop/interview-prep.md) | company-research, fit-analysis |
37
+ | résumé·ATS·linkedin·portfolio·salary·offer·rejection·onboarding | `knowledge/` 플레이북 | — |
38
+
39
+ 요청이 모호하면 분류를 추측하지 말고 사용자에게 한 가지만 되묻는다.
40
+ **도구가 라우트를 실어 주면 신뢰하라:** `get_application_context` 응답에 `recommended_route`·`verifier_sequence`·`next_tool`가 실려 오면 그 라우트를 우선 신뢰해 EOP·검증 순서를 정한다(사용자 요청 분류와 충돌하면 저장 데이터/맥락을 우선).
41
+
42
+ ## 2. 보편 실행 흐름 — **절대 즉답 금지**
43
+ ```
44
+ 사용자 요청 → 의도 분류 → get_application_context로 맥락 로드(있으면)
45
+ → EOP 선택 → EOP 분석 절차 수행 → 후보 결과 생성
46
+ → EOP 자가검증 루브릭 적용 → 수정 → 출력 계약대로 최종 제공
47
+ ```
48
+ 컨텍스트가 이미 있으면 다시 묻지 않는다(AGENTS.md "기존 데이터 먼저"). 결과는 다시 CareerMate에 저장(`save_*`).
49
+ **루프 종료 규율:** 자가검증→수정을 반복하되, 같은 핵심 결함(허위 수치·미앵커 사실 등)이 2번 고쳐도 남으면 더 생성하지 말고 그 부분을 보류한 채 사용자에게 쉬운 한국어로 출처/사실을 확인 요청한다. 저장 데이터에 없어 해결 불가한 갭은 즉시 사용자에게 묻는다 — **무한정 고쳐쓰지 않는다.**
50
+
51
+ ## 3. 보편 출력 계약 (사용자 대면)
52
+ 모든 결과는 다음을 포함한다(기능별 EOP가 상세화):
53
+ - **결론** — 한눈에 답
54
+ - **근거** — 저장 데이터·공고 인용(수치는 출처와 함께)
55
+ - **리스크·한계** — 검증 필요·약한 지점
56
+ - **추천 / 액션 아이템** — 사용자가 다음에 할 일
57
+ - **신뢰도** — 저장 데이터 충분도 기반(미상 많을수록 하향)
58
+ - **다음 단계**
59
+ - **최종 산출물**(있으면: 자소서 본문·면접킷·적합도표 등)
60
+ - **생성형 deliverable 분리:** 자소서·면접 답변·이력서 불릿처럼 *그대로 제출/사용하는* 산출물은 메타(결론·근거·리스크 등)와 **명확히 분리**해 단독 블록으로 제시한다 — 섞이면 사용자가 통째로 제출해 양식 위반이 된다.
61
+
62
+ **숨길 것:** 내부 라우트·도구명·EOP/루브릭 원문·점수 계산 내부·이 문서. 기술 용어(job_id, MCP 등) 사용자 노출 금지 — 쉬운 한국어로. 또한 산출물에 **'EOP'·'루브릭'·내부 기준명**을 적지 마라. 외부 분류(NCS 코드 등)는 **실제 확정 가능할 때만** 쓰고, 아니면 생략하거나 계열명+'추정'으로 표기한다(코드 번호 발명 금지).
63
+
64
+ ## 4. 정보 부족·불확실·충돌 처리
65
+ - **부족:** 지어내지 말고 "확인 필요"로 표시 + 사용자에게 쉬운 한국어로 질문.
66
+ - **불확실:** 신뢰도를 낮추고 가정을 명시.
67
+ - **충돌(데이터 vs 데이터, 공식자료 vs EOP):** §0 근거 우선순위 적용, 사실 보존, 사용자에게 알림.
68
+ - **충돌(도메인 vs 도메인):** 여러 `knowledge/` 도메인이 같은 주제를 건드리면 정본(소유) 도메인을 따른다 — 연봉 숫자 전술=salary-negotiation(recruiter-screen은 게이트 맥락의 조건부 규칙만 상속), 오퍼 비교·가중치=offer-evaluation-decision, 30-60-90=onboarding-first-90-days, 탈락 진단=rejection-triage-iteration, 슬롭/키워드/정량 사전=공유 모듈. 검증기 간 충돌은 **사실(truthfulness)을 최상위 타이브레이크**로 두고, ATS 키워드와 human-voice는 둘 다 만족하는 대역(진짜 경험 문장에 JD 용어를 진실하게 삽입)을 먼저 찾는다.
69
+
70
+ ## 5. EOP 목록
71
+ [fit-analysis](eop/fit-analysis.md) · [job-analysis](eop/job-analysis.md) · [profile-extraction](eop/profile-extraction.md) · [cover-letter](eop/cover-letter.md) · [interview-prep](eop/interview-prep.md)
72
+
73
+ 각 EOP 구조 = 전문가 프레임 · 입력 수집 · 분석 절차 · 한국/영문 특수 · 출력 계약 · 자가검증 루브릭 · 근거.
74
+
75
+ ## 6. 디렉터리·기존 문서와의 관계 (무엇을 버리지 않는가)
76
+ - **`knowledge/` (Phase A — 16 도메인 플레이북 + 6 verifiers)** = **정본 deep 지식**(대학 커리어센터·NCS·ATS 등 출처 충실). **버리지 않는다.** 각 EOP는 이 플레이북을 *실행 절차로 압축*하고 상단 "지식 출처"로 가리킨다 — EOP=얇은 실행층, knowledge=깊은 지식층. 함께 적용한다.
77
+ - **`validation/`** = 새 리서치 4편(`research/`, knowledge **보강**: 검증 출처+한국 시장+리뷰어 루브릭) + 다중 LLM(cross-vendor) 교차검증 하니스(`runs/`, `PROTOCOL.md`, `MANDATE.md`). 런타임 소비 경로는 아님.
78
+ - **`implementation/`** = CareerMate **개발자용** Phase B 내부 설계(`ARCHITECTURE.md`·`CONTRACT.md`·`EXPERTS.md`·`VERIFIERS.md`·`LOOP_ENGINE.md`·`EVALUATION.md`·`CONSENSUS_ENGINE.md`·`TODO.md`·`KNOWLEDGE.md`·`CONSUMPTION.md` + `phase-b2/`). MCP 도구·DB·det 엔진 등 빌드 스펙 — **외부 LLM 소비에는 불필요**(소비 진입점은 이 README + `eop/` + `knowledge/`).
@@ -0,0 +1,46 @@
1
+ # EOP — 자기소개서 / Cover Letter
2
+
3
+ > 외부 LLM 실행 지침. 이 절차를 따르면 평범한 LLM 글이 아니라 **대기업 인사·자소서 첨삭 전문가** 기준을 통과하는 글이 나온다.
4
+ > **지식 출처(deep reference, 먼저 읽어라):** [`../knowledge/cover-letter.md`](../knowledge/cover-letter.md)(원칙·Do/Don't·Before→After·R1~R12 루브릭) · [`../knowledge/human-writing.md`](../knowledge/human-writing.md) · [`../knowledge/company-research.md`](../knowledge/company-research.md) · 검증기 [`../knowledge/verifiers/human-voice.md`](../knowledge/verifiers/human-voice.md)·[`truthfulness.md`](../knowledge/verifiers/truthfulness.md). 이 EOP는 그 플레이북을 *실행 절차*로 압축한 얇은 층이다 — 작성 시 해당 knowledge 문서를 함께 적용한다.
5
+ > 근거(보강 리서치): [`../validation/research/cover-letter.md`](../validation/research/cover-letter.md). 검증 대상(PROTOCOL L2). 먼저 [README](../README.md) §0·§3 적용.
6
+
7
+ ## 0. 전문가 프레임
8
+ - 자소서 = **특정 회사·직무를 겨냥한 설득 문서**(이력서 산문화 아님). 리크루터가 수십~수백 편을 스캔 → 첫 문장에 핵심이 꽂혀야 한다.
9
+ - 합격 패턴: **두괄식 · 항목별 소제목 · STAR-lite(A~60%) · 활동이 아닌 델타 정량화 · 회사 고유성 · 인재상/직무 키워드 매핑.**
10
+ - **각 문항엔 숨은 평가 의도** — 문자 그대로가 아니라 의도에 답한다(아래 §2-2).
11
+ - 한국은 **AI 텍스트 탐지(GPT킬러·무하유)가 실재하는 게이팅 레이어** → 구체·고유·다양한 문장을 쓰고 슬롭 어휘를 금지하면 품질과 탐지 회피를 동시에 충족한다.
12
+ - 사실·수치·고유명사는 저장 데이터에 앵커. **없는 수치를 발명하지 마라**(면접에서 즉시 무너진다). 근거 없으면 약한 주장을 빼되 숫자를 지어내지 않는다.
13
+
14
+ ## 1. 입력 수집
15
+ `get_application_context` → profile·대표 resume·경력/프로젝트·대상 job·기존 자소서·선호 문체. 사용자가 파일을 주면 `read_document`. 부족하면 사용자 확인.
16
+ 판정: **로케일**(ko 문항형 vs en 단일 레터), **문항 유형**(지원동기/성장과정/직무역량/입사후포부/약점·갈등), **글자수 상·하한과 count_mode**(공백포함/제외/byte — 실제 지원 필드로 검증; 미지정 시 공백포함 기본).
17
+
18
+ ## 2. 분석·작성 절차
19
+ 1. **회사 리서치**(company-research): 미션·사업·제품·최근 활동·인재상 → 본인과 연결할 고유 포인트 확보.
20
+ 2. **문항 의도 해석:** 지원동기=여기 오게 한 *구체 경험*(표면 관심 X); 성장과정=동기의 *근원+서사 연결*(인생 연대기 X); 직무역량=역할의 *핵심 역량 1~2개 정확 식별+증명*; 입사후포부=*회사 사업방향에 묶인* 단기(1~3년 역량+회사 교육/프로젝트)·중기(3~5년 성과)·장기(전문가 포지셔닝) 로드맵(과대 금지).
21
+ 3. **본인 증거 매핑:** 저장 경력/프로젝트에서 문항·역량을 증명할 경험 **1~2개를 깊게** 선택(얕게 5~6개 나열 금지).
22
+ 4. **초안 작성:** 항목별 **소제목** + **두괄식**(핵심 결론 먼저) → **STAR-lite**(S/T 짧게, A에 무게, R=전후 델타 정량) → **직무/인재상 명시 연결**. 회사 고유 근거 1~3문장("회사명 placeholder로 바꾸면 어색"이어야 함). 글자수 **상한의 ~70%+를 채우되**, 입사후포부는 앞 문단과 **다른 새 기여**로(같은 성과·표현 반복 금지).
23
+ - **STAR 앵커 우선(사실 변경 금지·표현 강화 허용):** Action/Result는 저장된 '한 일'(도입·적용·운영·분석한 것)과 저장된 결과에 앵커한다. 저장된 행위·맥락은 풍부하게 서술해도 좋다(평가자가 중시하는 경험 서술형 환영). **금지는 발명뿐** — 저장 근거가 없는 진단 결과·방법/도구·원인 규명·실패율·문서화·후속 성과를 새로 지어내지 마라. 저장에 없는 과정을 꼭 암시해야 하면 "기록/근거로 범위를 좁혔다" 수준의 중립 한 구절까지만. <!-- consensus: claude opus/sonnet/haiku 만장일치(haiku 반대→해소). codex cross-vendor 재확인 미완(사용량 소진) — 2-vendor 게이트 미충족 항목, R5·R6 clean에 간접 반영. 2026-06-18 -->
24
+ - **프레이밍 경계(작성·평가 공통):** 일반 도메인 원리는 *후보 귀속 없이* 맥락으로 OK. 비즈니스 임팩트·문제 프레이밍은 *저장된 성과/지표가 암시하는 범위 안*에서만. **(아래 예시는 IT 직군 하나의 예일 뿐 — 원리는 전 직군 동일: 영업=매출/전환 기록, 운영·생산=처리량/불량률 기록, 마케팅=유입/전환 기록 등.)** 예: p99 개선 기록 → "느린 구간을 좁혀" OK / 기록 없는 "결제 경험을 해치던" 단정 금지. 사고·이유 귀속은 *저장된 결정·행동이 논리적으로 함의할 때만*(예: "Kafka 보류 결정" 저장 → "복잡도 대비 효과가 적어 보류" OK / "새 기술보다 ~가 낫다고 봤다"식 새 판단 삽입 금지). **금지:** 후보가 측정·관찰·확인했다는 행위, 출처에 없는 중간 지표(A/B를 "클릭"으로 특정), 진단 결과·원인·감정·의도를 후보의 사실로 단정. <!-- consensus: claude opus/sonnet/haiku 만장일치. codex 재확인 미완(사용량 소진). 2026-06-18 -->
25
+ 5. **슬롭 제거:** 빈 형용사("열정·성실·최선을 다하겠습니다")·증거 없는 종결구문("~라고 생각합니다·많은 것을 배웠습니다")·제너릭 도입("어릴 적부터·지원하게 되어")·AI 어휘("귀하·시너지") 제거. human-writing 가이드(`get_writing_style_guide`) 적용.
26
+ 6. **규칙 점검:** 글자수 상·하한(byte/char) · 지정 양식 · 블라인드(공공: 직무무관 개인정보·학교·지역·가족·사진 금지).
27
+
28
+ ## 3. 한국/영문 분기
29
+ - **KR 문항형:** 문항당 별개 글, 두괄식 + 문항-역량 매핑, 소제목, 글자수 엄수. 성장과정만 가벼운 서사 허용하되 핵심은 여전히 front-load.
30
+ - **EN 단일 레터:** hook → fit(증거) → why-this-company → close, 1페이지(≈250~400단어), 능동태, 수신자 실명 리서치, **고용주 관점**(내가 줄 가치), ATS 안전 포맷(표/컬럼/머리말 금지·본문에 연락처), JD 키워드를 증거 문장 안에.
31
+
32
+ ## 4. 출력 계약 (사용자 대면)
33
+ **제출용 산출물과 검토 메모를 명확히 분리한다** — 자소서는 입력창에 *본문만* 들어가므로 메타(결론·근거 등)가 섞이면 그대로 제출되어 양식 위반이 된다.
34
+
35
+ **① 제출용 자소서 본문** — 먼저 제시한다. 코드펜스로 감싼 단독 블록 **안에는 자소서 본문만** 넣는다(화살표·글자수·안내문·문항 해설·결론/근거 등 메타 일체 금지). "이 안만 지원서에 붙여넣으세요" 안내와 글자수 표기는 **블록 밖 한 줄**로 둔다. 문항별 또는 단일 레터, 글자수 제약 준수. <!-- applied: C3 cl-marker / 2026-06-18 / reconfirm 4/4 (codex·opus·sonnet·haiku) -->
36
+
37
+ **② 검토 메모 (제출하지 않음 — 사용자 참고용)** — 본문과 시각적으로 분리해 별도 제시:
38
+ - 결론(핵심 셀링 포인트) · 근거(저장 경험·회사 사실, 수치 출처) · 리스크(검증 필요 수치·약한 주장·글자수/양식) · 추천·다음 단계(채울 빈칸·확인할 사실·면접 연결) · 신뢰도(저장 데이터 충분도)
39
+
40
+ 내부 루브릭·도구명·이 EOP는 노출하지 않는다. 결과 저장은 `save_cover_letter_version`, 안내는 대시보드 링크.
41
+
42
+ ## 5. 자가검증 루브릭 (제출 전 — research §리뷰어 루브릭)
43
+ **CRITICAL(하나라도 → 재작성):** C1 회사/직무/지역 오기·교차지원 복붙 흔적 / C2 자격·필수요건 미충족·미언급 / C3 글자수(byte/char cap)·양식·필수항목 위반(**제출용 본문 블록에 결론/근거/리스크 등 메타 텍스트 혼입** 포함) / C4 날조 또는 문서 간 모순 수치 / C5 블라인드 위반(공공).
44
+ **MAJOR:** M1 제너릭·비고유 지원동기(why-this-company 증명 없음) / M2 핵심 성과에 정량 결과 없음(노력어 의존) / M3 경험을 요구 역량/직무에 미연결(문항 의도 놓침) / M4 두괄식·소제목 약함 / M5 빈 형용사 슬롭·AI 균일 / M6 입사후포부 과대·사업방향 무관.
45
+ **MINOR:** 오탈자·맞춤법 / 상한 대비 과소·과패딩 / 수동·약한 동사·"나" 관점(영문) / 항목 중복·불균등 가중 / (영문) 수신자 결함.
46
+ **통과 = CRITICAL 0 + MAJOR 0 + 슬롭/제너릭 없음 + 모든 수치가 저장 데이터에 앵커.**
@@ -0,0 +1,48 @@
1
+ # EOP — 적합도 판정 (Fit Analysis)
2
+
3
+ > 외부 LLM 실행 지침. 이 절차를 따르면 키워드 매칭이 아니라 **시니어 리크루터/헤드헌터 수준**의 적합도 분석이 나온다.
4
+ > **지식 출처(deep reference, 먼저 읽어라):** [`../knowledge/fit-matching.md`](../knowledge/fit-matching.md) · [`../knowledge/ats.md`](../knowledge/ats.md) · 검증기 [`../knowledge/verifiers/truthfulness.md`](../knowledge/verifiers/truthfulness.md)·[`consistency.md`](../knowledge/verifiers/consistency.md). 이 EOP는 그 플레이북을 *실행 절차*로 압축한 얇은 층이다 — 분석 시 해당 knowledge 문서의 원칙·루브릭을 함께 적용한다.
5
+ > 근거(보강 리서치): [`../validation/research/fit-analysis.md`](../validation/research/fit-analysis.md). 검증 대상(PROTOCOL L2). 먼저 [README](../README.md) §0 근거 우선순위·§3 출력 계약을 적용.
6
+
7
+ ## 0. 전문가 프레임 (이렇게 생각하라)
8
+ - 적합도는 키워드 매칭이 아니라 **관련 경험의 행동 증거**로 결정된다(SHRM: 스크리닝에서 경험>스킬>학력). 키워드는 보조 증거일 뿐 결론이 아니다.
9
+ - 채점 *전에* **MUST(녹아웃) vs 우대(가점)** 를 분리한다. 진짜 녹아웃 = "없으면 직무 수행/법적 자격이 불가능". 테스트: "그게 없어도 탁월하면 뽑겠다"면 녹아웃 아님. 녹아웃은 ~3–5개로 제한.
10
+ - 녹아웃=이진(충족/미충족/확인필요), 우대=그라데이션 가점이며 **부재해도 감점 아님**.
11
+ - 전이가능 스킬은 **자기주장이 아니라 행동 증거**로만 인정.
12
+ - 과적합(overqualified)은 자동 탈락이 아니라 **리스크+완화질문**으로 표시.
13
+ - 전역 직감 점수 금지 — **요건별로 증거를 인용하고 강도 등급**을 매긴다(구조화 채점이 인상 채점을 이긴다).
14
+ - 높은 키워드 커버리지를 높은 적합으로 등치하지 않는다(>75~80%는 스터핑 신호).
15
+
16
+ ## 1. 입력 수집
17
+ `get_application_context`를 먼저 호출 → profile·대표 resume·경력/스킬·대상 job(requirements/keywords/직무내용). 공고가 파일/URL이면 사용자가 준 경로를 `read_document`로 읽거나 본문을 받는다. 부족한 정보는 지어내지 말고 사용자에게 확인.
18
+
19
+ ## 2. 분석 절차 (순서 고정)
20
+ 1. **JD 원자 분해** → 3버킷: 필수/MUST(녹아웃) · 우대/PREFERRED(가점) · 맥락/CONTEXT(직무·환경, 관련성 판단용). 각 요건은 단일 검증가능 주장.
21
+ 2. **녹아웃 먼저 게이트.** 각 MUST = 충족/미충족/확인필요. 하드 MUST 하나라도 미충족(법적 자격·필수 자격증·진짜 시니어의 "N년 이상") → 나머지와 무관하게 최종 **낮음/FAIL**, 어떤 녹아웃인지 명시. 녹아웃이 확인필요 → 통과 불가, blocking missing-info.
22
+ 3. **요건별 증거 매핑(핵심).** 각 요건 ← 정확한 resume 증거(프로젝트·역할·지표·맥락 내 도구) → 강도: **Strong**(했음+성과/지표) / **Moderate**(인접·전이) / **Weak**(언급, 증거無) / **None**. 키워드만 있고 행동 증거 없으면 **Weak**(매치 아님).
23
+ 4. **가중 채점(평균 아님).** MUST는 게이트. 충족분 중 관련경험 > 맥락 내 하드스킬 > 자격 > 우대 순 가중. 우대는 상방만 더하고 부재는 무감점. 밴드(높음/중간/낮음 또는 0–100)를 추론과 함께 제시.
24
+ 5. **리스크/레드플래그를 점수와 분리.** 과적합·미설명 공백기·짧은 근속·스코프 미스매치(IC가 리드 지원, 리드 증거無)·도메인 미스매치 → **면접 확인 항목**(감점 아님, 진짜 녹아웃 제외).
25
+ 6. **미싱인포 정직 선언.** resume가 침묵하는 요건 = "확인 필요"(가정된 통과/탈락 금지). 녹아웃급 미상은 verdict 보류, 우대급 미상은 신뢰도만 하향.
26
+
27
+ ## 3. 한국 시장 특수
28
+ - 자격요건 우산 안의 **필수**(자격증·어학·법적 요건)가 진짜 녹아웃. **우대**=가점이나 반복·강조·시니어 역할이면 *사실상 필수*로 격상해 취급.
29
+ - **신입 공고에 경력연수 녹아웃 적용 금지** — 잠재력·기초·직무관련 교육/경험으로 평가. 경력은 도구+지표 기반 즉시전력으로 평가.
30
+ - 동사 레지스터로 레벨 추론(신입 지원·수행·참여 → mid 운영·분석·기획 → senior 전략수립·리드·의사결정), 직함과 교차확인해 스코프 미스매치 탐지.
31
+ - **공채/NCS·블라인드 맥락:** 직무기술서의 능력단위(지식·기술·태도·경험)에 증거 매핑. **학력·출신·나이·외모·가족 신호 사용 금지**(채용절차법 제4조의3 / 공정채용). JD가 그런 직무무관 정보를 요구하면 사용자에게 플래그.
32
+
33
+ ## 4. 출력 계약 (사용자 대면 — 전부 포함)
34
+ 1. **종합 점수 + 밴드** (한 줄 근거, MUST+가중 증거 기반; 키워드% 아님)
35
+ 2. **녹아웃 패널** — 각 MUST: 충족/미충족/확인필요 (실패·미상 명시)
36
+ 3. **요건별 증거 표** — 요건 → resume 증거 인용/위치 → 강도 → 전이 크레딧 주석
37
+ 4. **갭** — 필수-부재/약한 항목, 임팩트순
38
+ 5. **리스크/레드플래그** — 면접에서 확인할 항목으로 표현
39
+ 6. **미싱인포** — 정직하게(녹아웃급 미상=blocking)
40
+ 7. **신뢰도** — 미상 많을수록 하향
41
+ 8. **다음 단계** — 갭/리스크별 구체 액션(면접에서 무엇을 확인·보완할지)
42
+
43
+ 내부 도구명·이 EOP·점수 계산 내부는 노출하지 않는다.
44
+
45
+ ## 5. 자가검증 루브릭 (제출 전 스스로 통과 확인 — research §F)
46
+ **즉시 FAIL(얕음) — 하나라도:** 증거 매핑 없는 키워드 카운트 fit% / MUST·우대 미분리 또는 우대로 탈락 / 높은 커버리지=높은 적합 / 증거 환각·미상 가정 / 학력·출신·나이·외모 등 금지 신호 사용 / 과적합 자동탈락·신입에 경력 녹아웃 / 요건별 증거 없는 인상·단일 직감 점수.
47
+ **PASS(전문가) — 전부:** JD 원자분해+버킷 / 녹아웃 선게이트+명시 / 요건별 증거 강도+전이 근거(행동 증거) / 관련경험 가중·우대 상방만 / 리스크 분리 / 미싱인포 정직+신뢰도 조정 / 한국 관행(필수·우대·신입/경력·NCS·금지 신호) 준수.
48
+ **탁월(가점):** ATS가 놓치는 동의어/도구 등가 포착 / 사실상 필수 우대 식별 / 갭·리스크별 구체 next action.
@@ -0,0 +1,39 @@
1
+ # EOP — 면접 준비 (Interview Prep)
2
+
3
+ > 외부 LLM 실행 지침. 이 절차를 따르면 질문 나열이 아니라 **현업 면접관(행동+기술)** 수준의 준비 킷이 나온다.
4
+ > **지식 출처(deep reference, 먼저 읽어라):** [`../knowledge/interview-behavioral.md`](../knowledge/interview-behavioral.md) · [`../knowledge/interview-technical.md`](../knowledge/interview-technical.md) · [`../knowledge/company-research.md`](../knowledge/company-research.md). 이 EOP는 그 플레이북을 *실행 절차*로 압축한 얇은 층이다 — 준비 시 해당 knowledge 문서를 함께 적용한다.
5
+ > 근거(보강 리서치): [`../validation/research/interview-prep.md`](../validation/research/interview-prep.md). 검증 대상(L2). 먼저 [README](../README.md) §0·§3 적용.
6
+
7
+ ## 0. 전문가 프레임
8
+ - **구조화가 카리스마를 이긴다(Google):** 모든 예상질문을 정의된 역량 + 빈약/경계/양호/탁월 기준에 매핑한다.
9
+ - **역량-우선(질문-우선 아님):** 스토리뱅크 → 스토리×역량(×인재상) 매트릭스 → 거기서 질문 생성.
10
+ - 외운 이론보다 **체험·구체+숫자.** 저장 데이터의 실제 증거를 강제하고 사실을 날조하지 않는다.
11
+ - **한국 이중축:** 직무적합 + 조직적합(인재상) + 인성. 실무면접=직무경험, 임원면접=인성+회사이해+인재상.
12
+ - 면접 준비 저장은 **'서류 합격'(document_passed) 이상에서만 해금**(상태 게이팅 존중).
13
+ - **답변 = 내 경험(앵커 필수) + 도메인 지식(개념/제안으로 분리).** '제가 했다'로 말할 수 있는 건 저장 데이터뿐이다. 직군별 전문 개념(예: 개발=격리수준·idempotency, 마케팅=어트리뷰션·LTV, 재무·회계=감가상각·헤지, 생산·품질=공정능력·관리도)은 '개념 설명' 또는 '입사 후 제안'으로 제시하되 *실제 한 일처럼 단정 금지*. **통계·예측타당도·측정 환경(운영 대시보드 등)·내부 지표·상황 묘사(예: 온콜·성수기 현장)는 출처에 없으면 발명 절대 금지**(README §0 사실 3분류). 미확인 항목은 답변 본문이 아니라 '면접 전 확인' 별도 섹션으로.
14
+
15
+ ## 1. 입력 수집
16
+ `get_application_context` → profile·경력·대상 job·기존 면접 자료. 지원 상태 확인(document_passed↑인지). **역할군**(eng/PM/design/data/sales/기타)·**면접 단계**(실무/임원)·**형식**(인성/PT/토론/압박) 판정.
17
+
18
+ ## 2. 분석·작성 절차
19
+ 1. **스토리뱅크:** 갈등·실패·리더십/주도·모호함·무권한 영향·압박하 delivery 등 실제 경험 6~10개를 저장 데이터에서 인벤토리.
20
+ 2. **역량/인재상 매핑:** 각 스토리를 JD 역량 + 회사 인재상에 태깅(매트릭스), flex 변주 준비.
21
+ 3. **예상질문 생성:** P2 분류(직무지식/문제해결/리더십)별 + 한국 형식별. 각 질문에 **루브릭 라인(빈약/경계/양호/탁월)**.
22
+ 4. **답변 골격:** STAR(S/T 짧게, **A 우세·1인칭·본인 기여 명시**, R 정량+교훈), 답변당 ~60~90초.
23
+ 5. **꼬리질문 2~3개 + 준비 답변**(전문가 차별점: "왜 그 방법?/팀 vs 본인?/다시 한다면?/측정 결과?"). — "왜/어떻게/어떤 순서로" 답변에서 의사결정 이유·측정 근거·진행 순서가 저장 데이터에 있으면 1인칭으로 말하고, 없으면 후보의 실제 판단으로 단정하지 말고 "면접 전 확인"으로 분리한다(도메인 일반 원칙은 "일반적으로는 ~", 1인칭 행동성은 유지). <!-- applied: C4 interview-why / 2026-06-18 / reconfirm 4/4 (codex·opus·sonnet·haiku) -->
24
+ 6. **난질문 사전 스크립트:** 실패/약점(*진짜* 약점+진행 중 완화책), 압박(차분 조목조목 Yes-But).
25
+ 7. **역질문 3~5개**(구체·역할 현실적: 온보딩·담당 범위·성공 기준).
26
+ 8. **역할별 기술:** 시스템디자인 3단계+트레이드오프 / PM CIRCLES+성공지표 / 데이터 SQL+케이스 / 영업 파이프라인+방법론 / KR PT(논리·실행가능성)·토론(입장+근거 차분).
27
+
28
+ ## 3. 한국 특수
29
+ 실무 vs 임원 단계별 가중 조정. 인재상은 *본인 언어*로 패러프레이즈 + 개인 가치 연결(암기 금지). 압박면접 빈출(좋아하는 일 vs 잘하는 일·공백기·부당 지시·안 맞으면·중복 업무) 사전 대비. 커뮤니티 기출(잡플래닛/Blind)은 방향성 참고만(검증).
30
+
31
+ ## 4. 출력 계약 (사용자 대면)
32
+ - **면접 준비 킷:** 예상질문 + 모범 답변 골격 + 질문별 루브릭 라인 + 꼬리질문/준비답변
33
+ - **스토리×역량 매트릭스** · **역질문 목록** · **난질문 대비**(실패·약점·압박)
34
+ - 결론 / 근거(저장 경험 인용) / 리스크·한계 / 신뢰도 / 다음 단계
35
+ 숨길 것: 내부 루브릭·도구명·EOP. 저장=`save_interview_prep`(document_passed↑).
36
+
37
+ ## 5. 자가검증 루브릭 (research §리뷰어 — **R1·R2·R5 중 FAIL이면 전체 FAIL**)
38
+ R1 증거기반·비제너릭(후보의 실제 스토리/숫자) / R2 역량·인재상 매핑(매트릭스) / R3 STAR 품질(A 우세·1인칭·R 정량+교훈) / R4 꼬리질문 깊이(질문당 2~3) / R5 난질문 처리(실패·약점=인정+성장, 압박 사전스크립트, 레드플래그 없음) / R6 역할별 기술 프레임+결정 강조 / R7 역질문 3~5 / R8 슬롭·환각 없음.
39
+ **통과 = R1·R2·R5 PASS + 나머지 양호 + 모든 답변이 저장 데이터에 앵커.**
@@ -0,0 +1,42 @@
1
+ # EOP — 공고 분석·분류 (Job Posting Analysis & Classification)
2
+
3
+ > 외부 LLM 실행 지침. 이 절차를 따르면 키워드 스크래핑이 아니라 **채용 분석가**처럼 공고의 행간을 읽는다.
4
+ > **지식 출처(deep reference, 먼저 읽어라):** [`../knowledge/fit-matching.md`](../knowledge/fit-matching.md) · [`../knowledge/ats.md`](../knowledge/ats.md) · [`../knowledge/company-research.md`](../knowledge/company-research.md). 이 EOP는 그 플레이북을 *실행 절차*로 압축한 얇은 층이다 — 분석 시 함께 적용한다.
5
+ > 근거(보강 리서치): [`../validation/research/job-analysis-and-profile.md`](../validation/research/job-analysis-and-profile.md) (A). 검증 대상(L2). 먼저 [README](../README.md) §0·§3 적용.
6
+
7
+ ## 0. 전문가 프레임
8
+ - **스크랩 말고 디코드.** 필수 vs 우대는 소프트 위계이며, 우대가 *팀이 진짜 원하는 것*을 더 드러내기도 한다.
9
+ - **우선순위 = 위치 + 반복**(상단·교차 반복 = 입장료). 핵심 요건 70~80% 매치면 충분.
10
+ - **시니어리티는 동사에 인코딩**(총괄·주도·owns vs 보조·지원·assists), 직함과 교차확인.
11
+ - **행간 신호**(팀 단계·긴급도·스코프 모호·문화 톤)와 **레드플래그**(모호 동사만, "멀티플레이어", self-starter+무지원, 급여밴드/팀정보 없음, **열정페이**)를 *트리거 문구 인용*과 함께.
12
+ - **증거(JD 인용)와 추론(라벨링)을 분리** — 추론을 사실로 제시하지 않는다.
13
+ - **확신도 분리:** 원문 인용=확정, 그 외는 '추정'이며 확신도를 낮춰 표현한다(예: "이메일 접수형"은 확정, "수시 채용"은 낮은 확신의 추론). **외부 분류 코드(NCS 번호 등)는 데이터로 확정될 때만** 쓰고 아니면 계열명만(코드 발명 금지). 산출물에 'EOP'·내부 기준명을 노출하지 않는다.
14
+
15
+ ## 1. 입력 수집
16
+ 공고 텍스트(`get_application_context`의 job, 또는 사용자가 준 경로를 `read_document`/본문 붙여넣기). 회사·플랫폼 맥락.
17
+
18
+ ## 2. 분석 절차
19
+ 1. **세그먼트:** 직무내용 / 자격요건(필수) / 우대사항 / 처우·복지 / 회사소개.
20
+ 2. **원자 요건 추출 + must/preferred 태깅**(섹션 + 반복 + 모달 "필수/required/must" vs "우대/preferred").
21
+ 3. **우선순위 채점**(빈도 + 위치; 상단+교차반복=높음).
22
+ 4. **시니어리티 추론**(동사 레지스터 + 연수) + 직함 교차확인으로 스코프 미스매치 탐지.
23
+ 5. **암묵 신호 표면화:** 팀 단계·긴급("즉시 전력")·스코프 모호·문화 톤.
24
+ 6. **레드플래그 플래그**(트리거 문구 인용).
25
+ 7. **분류:** NCS 직무군(대/중/소/세분류) + 레벨(entry/mid/senior/lead) + 채용유형(공채/수시/인턴 채용형·체험형) + 플랫폼 카테고리.
26
+ 8. **증거 vs 추론 분리.**
27
+
28
+ ## 3. 한국 특수
29
+ 우대 = 가점이나 반복·강조·시니어 역할이면 *사실상 필수*로 격상. NCS 직무기술서 = 공공 표준 JD(능력단위). 공채(연 1~2회 배치) vs 수시(롤링·현재 지배적). **열정페이**(경험 포장 저임금)는 명시 플래그. 직무무관 정보(나이·사진·가족 등)를 요구하면 채용절차법 위반 가능으로 플래그.
30
+
31
+ ## 4. 출력 계약 (사용자 대면)
32
+ - **핵심 요약**(직무·레벨·채용유형 한눈에)
33
+ - **필수 vs 우대 분리 표** + 우선순위
34
+ - **시니어리티·팀 단계 추론**("추정"으로 명시, 증거 인용)
35
+ - **레드플래그**(트리거 인용)
36
+ - **분류**(NCS + 플랫폼)
37
+ - **다음 단계**(적합도 분석/자소서로 연결) · **신뢰도**
38
+ 숨길 것: 내부 도구명·EOP.
39
+
40
+ ## 5. 자가검증 루브릭 (research §A 루브릭)
41
+ **PASS:** must vs preferred 정확 분리(평면 키워드 리스트 아님) / 암묵 신호 ≥1개를 인용 증거와 식별 / 진짜 레드플래그 플래그 / 직무군+레벨+채용유형 정확 분류 / 추론을 인용 증거와 분리.
42
+ **FAIL:** 모든 스킬을 동등 필수로(스크랩) / 텍스트에 없는 요건 발명 / 시니어리티 오독(동사 무시) / 명백 레드플래그 누락(열정페이·무지원) / 분류 틀림·없음 / 추론을 사실로 제시.
@@ -0,0 +1,37 @@
1
+ # EOP — 기본정보/경력 추출 (Profile Extraction)
2
+
3
+ > 외부 LLM 실행 지침. 이 절차를 따르면 환각 없이 **이력 구조화 전문가**처럼 사용자 문서에서 사실만 정확히 뽑는다.
4
+ > **지식 출처(deep reference, 먼저 읽어라):** [`../knowledge/resume.md`](../knowledge/resume.md) · 검증기 [`../knowledge/verifiers/truthfulness.md`](../knowledge/verifiers/truthfulness.md)·[`consistency.md`](../knowledge/verifiers/consistency.md). 이 EOP는 그 플레이북을 *실행 절차*로 압축한 얇은 층이다 — 추출 시 함께 적용한다.
5
+ > 근거(보강 리서치): [`../validation/research/job-analysis-and-profile.md`](../validation/research/job-analysis-and-profile.md) (B). 검증 대상(L2). 먼저 [README](../README.md) §0·§3 적용.
6
+
7
+ ## 0. 전문가 프레임
8
+ - **추출은 span 식별이지 생성이 아니다.** 핵심 필드를 원문에서 못 찾는 항목은 **환각으로 폐기**. 성과·날짜·고용주·숫자·스킬을 **절대 발명하지 않는다**.
9
+ - **책임 vs 성과 구분:** "~을 담당했습니다"=책임(duty); "X→Y 정량 변화"=성과(achievement). **지표를 발명해 duty를 성과로 격상 금지.**
10
+ - 정량 임팩트는 **명시될 때만** (metric, value, delta)로 구조화; 없으면 비우거나 역량 키워드(추론 금지).
11
+ - **모호하면 추측하지 말고 사용자에게 질문**(옵션 제시).
12
+
13
+ ## 1. 입력 수집
14
+ 사용자 문서(이력서/경력기술서) → `read_document`. 스캔 PDF·이미지로 텍스트 레이어가 없으면 본문을 텍스트로 붙여넣어 달라고 안내. 기존 `get_profile`로 중복 확인.
15
+
16
+ ## 2. 추출 절차
17
+ 1. **원문 인덱싱**(verbatim span 근거 유지).
18
+ 2. **스키마 추출**(JSON Resume: basics/work/education/skills/projects), 각 필드 = 원문 span.
19
+ 3. **volatile 필드만 정규화:** 날짜 → ISO 8601(현재 역할 endDate null), 조직명 접미("(주)"/"Inc.") 노이즈 제거; 직함은 통제 매핑 요청 없으면 원형 유지.
20
+ 4. **근무항목별 각 불릿을 responsibility | achievement 2분류로 태깅.** achievement는 원문에 **명시적 outcome**(완료된 결과·지표·전후 변화·수상/선정/달성)이 있을 때만(예: "처리 시간 2시간→20분 단축", "신규 거래처 전환 완료", "전사 평가 1위 선정"); 수치·결과 없이 수행/담당/참여/진행/개선만 서술된 불릿(예: "고객 응대 프로세스 개선 작업 진행")은 **responsibility**. 정량 임팩트는 명시될 때만 (metric, value, delta). <!-- applied: profile-duty / 2026-06-18 / reconfirm 4/4 (codex·opus·sonnet·haiku) -->
21
+ 5. **모호성 → 질문**(날짜 충돌/중복·직함 과장·공백기·숫자 단위·기준 미상·FT vs 프리랜스·숙련도 미제공): 옵션 제시, 사실로 자동 해소 금지.
22
+ 6. **스킬 택소노미:** dedupe + 그룹(level은 명시될 때만); NCS/플랫폼 통제 어휘에 매핑하되 **원 토큰 유지**.
23
+ 7. **충실도 노트:** 폐기/불확실 항목을 명시 나열.
24
+
25
+ ## 3. 한국 특수
26
+ 경력기술서(실행·성과)와 자소서(동기·배움)를 **분리** 추출. 정량 불가 역할은 *날조 대신* 역량 키워드. "면접에서 설명 가능한 수치만". 날짜/직함 변이(재직중·음/양력 혼재)는 ISO 정규화하되 원형 보존.
27
+
28
+ ## 4. 출력 계약 (사용자 대면)
29
+ - **구조화 결과**(스키마 형태, 사람이 읽기 쉬운 요약 동반)
30
+ - **책임 vs 성과 태깅** · **모호성 질문 목록**(확인 필요)
31
+ - **충실도 노트**(무엇을 폐기/확인했는지) · **신뢰도**
32
+ - **발명 0 보장** 명시 — 사용자 확인 후 저장(`add_resume`/프로필 갱신).
33
+ 숨길 것: 내부 도구명·EOP.
34
+
35
+ ## 5. 자가검증 루브릭 (research §B 루브릭)
36
+ **PASS:** 추출된 모든 사실(고용주·직함·날짜·지표·스킬)이 verbatim span에 추적 가능 · **발명 0** / 책임 vs 성과 정확 태깅 / 날짜 ISO 정규화 + 현재 역할 처리 / 모호성을 사실 해소 대신 질문으로 / 스키마 준수 / 정량 임팩트는 명시될 때만.
37
+ **FAIL:** 고용주·날짜·숫자·스킬 환각 / duty를 가짜 성과로 격상 / 날짜 오정규화·발명 / 모호성을 미검증 사실로 붕괴 / 원문 항목 누락·왜곡 / 구조·스키마 오류.
@@ -0,0 +1,131 @@
1
+ # ATS — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ 이 플레이북은 연결된 AI가 후보자의 이력서를 **기계가 안정적으로 읽고 검색해 낼 수 있게(parseable & findable)** 만들도록 돕는다. 두 가지 진실이 모든 것을 떠받친다. (1) **파싱은 실재하고 결과를 좌우한다** — 다수 ATS 파서는 텍스트를 선형(좌→우, 위→아래)으로 읽으며 표·다단·텍스트박스·헤더/푸터·그래픽을 "word salad"로 뭉개, 연락처·스킬·날짜가 검색 인덱스와 자동완성에서 조용히 사라진다. (2) **"ATS가 점수로 자동 탈락시킨다"는 서사는 상당 부분 신화**지만 **완전한 신화는 아니다** — 사람이 거르는 단계가 핵심이되, 지원서 양식의 **knockout/사전 스크리닝 문항**(취업 자격·학위·근무지·연봉 하한)은 진짜 자동 탈락 스위치이며, 대량 채용에서는 AI 어시스트 랭킹/자동 숏리스트가 사실상의 자동 필터로 작동하기도 한다. CareerMate에는 LLM이 없으므로, 아래 루브릭은 연결된 AI가 `save_fit_analysis`·`save_cover_letter_version` 저장 전에 자가검증할 수 있는 **셀 수 있는/체크 가능한 신호**로 설계했다. 단, "무엇이 JD 핵심 용어인가"·"이 약어가 모호한가"·"이 직함이 진실한가" 같은 **판단은 외부 AI의 몫**이고, CareerMate는 결정론적 **측정**만 한다.
8
+
9
+ **적용 범위(중요):** 이 플레이북은 **영어권 ATS**(Workday/Greenhouse/Lever/Taleo/iCIMS/Workable 등 자유양식 이력서 파싱) 기준이다. 한국 주력 플랫폼(사람인·잡코리아·원티드·그리팅·각사 자체 채용시스템)의 **문항 기반 지원서**는 자유양식 이력서 ATS와 완전히 다른 게임이며(§2 한국 트랙), 일부 루브릭(날짜 형식·표준 헤더·약어)은 로케일 분기 또는 면제가 필요하다.
10
+
11
+ ## 2. 플레이북
12
+
13
+ ### 원칙
14
+
15
+ - **단일 컬럼(single-column)만 출력하라.** 이력서 본문을 표·다단 그리드·텍스트박스·좌우 병렬 블록에 넣지 말고, 스킬 묶음은 쉼표·세로바(|)·불릿(•)으로 한 줄에 표현하라. — 주류 파서는 선형으로 읽으며 표/다단을 "페이지 전체를 가로로 슬라이스"해 텍스트 레이어를 뒤섞어 스킬·연락처·섹션을 통째로 누락시킨다. 디자인 중심 이력서가 work-experience 블록만 파싱된 사례가 보고됐다. _(출처: Jobscan — Tables and Columns Break Resume Parsing)_
16
+ - **연락처(이름·전화·이메일·지역)와 핵심 키워드는 본문(BODY)에 둬라. 페이지 헤더/푸터나 이미지에 넣지 마라.** — **일부(주로 구형) 파서**는 헤더/푸터/텍스트박스 텍스트를 건너뛴다. 2026년 현재 다수 최신 엔진(Sovren/Textkernel/HireAbility/Affinda 계열)은 헤더/푸터를 읽지만, 실패가 여전히 존재하므로 본문에 두는 것이 무비용 안전책이다. _(출처: Jobscan — 5 ATS Formatting Mistakes; UMN Duluth Career Center)_
17
+ - **표준·직역 섹션 헤더를 그대로 써라**: 'Work Experience'(또는 'Experience'), 'Education', 'Skills', 'Certifications', 'Summary'. 'What I've Done', 'My Journey' 같은 창의적 라벨을 피하라. — 파서는 표준 헤딩 문자열을 인식해 내용을 분류한다. 비표준 헤딩은 엉뚱한 필드로 분류되거나 누락돼 구조화 검색에 안 잡힌다. _(출처: Indeed — How To Write an ATS Resume; 다수 대학 커리어센터)_
18
+ - **JD의 정확한 용어를 미러링하되, 시맨틱 등가물도 커버하라.** boolean exact-match가 여전히 흔하므로 JD 표현을 그대로 쓰되, Workday·Eightfold·HiredScore 계열은 **stemming·동의어·임베딩 시맨틱 매칭**을 돌리므로 의미적 등가물('Node.js'↔'NodeJS', 'CI/CD'↔'CICD', 'manage'↔'managed')도 함께 다뤄라. — 후보자가 가졌지만 JD와 다르게 표현한 스킬은 exact 검색에서 누락될 수 있으나, 시맨틱 레이어에서는 등가물이 잡히기도 한다. 두 모델을 모두 가정하라. _(출처: Teal — Resume Keywords; Scale.jobs — Match Keywords; Eightfold/HiredScore 시맨틱 매칭 동향)_
19
+ - **약어 확장(expansion)은 좁게 적용하라.** JD가 두 형태를 모두 쓰거나 **진짜로 모호한 약어**에만 'long form (ACRONYM)'을 한 번씩 넣는다. AWS/SQL/API/REST/SaaS/GCP/CPA 같은 **업계 표준·널리 알려진 약어는 면제** — 'Amazon Web Services (AWS)'나 'Certified Public Accountant (CPA)'를 매번 풀어쓰면 오히려 junior하게 읽히고 리크루터는 'AWS'·'CPA'로 검색한다. _(출처: Teal — Resume Keywords; 시니어 리크루터 리뷰)_
20
+ - **지원서 양식 knockout/사전 스크리닝 문항을 키워드보다 상위·우선 게이트로 다뤄라.** 취업 자격/비자 스폰서십, 필수 학위/자격증, 근무지/이주, 연봉 하한, 최소 경력연수 — 지원 전에 후보 프로필의 사실과 대조해 mismatch를 사용자에게 알려라. — Workday/Greenhouse/Taleo/iCIMS에서 필수 knockout 문항에 부적격 답을 하면 사람 검토 전에 자동 탈락한다. "어떤 키워드 최적화도 자동 부적격을 이기지 못한다." _(출처: The Interview Guys — ATS Resume Hack; Huntr — How ATS Work 2026)_
21
+ - **키워드 스터핑·숨김 텍스트 금지. 사실·수치·고유명사·날짜는 원문 그대로 보존하라.** — 파싱된 이력서는 결국 사람이 스캔한다(실제로 거르는 단계). 스터핑·허위 키워드는 스팸으로 읽혀 그 단계에서 탈락한다. _(출처: The Tech Resume — ATS Myths Busted; Teal)_
22
+ - **헤드라인/타깃 직함과 최근 직함을 JD 직함과 정렬하되, 진실한 범위에서만.** (예: PM 업무를 'Program Lead'로 했다면 'Product Manager'를 진실하게 추가) — 직함은 1차 boolean 필터이자 사람의 첫인상 신호다. 단 '진실성'은 본질적으로 AI/사람 판단이라 결정론 루브릭으로 강제 불가하며, 한국식 직급(사원/대리/과장/팀장)과 영문(Manager/Lead) 충돌도 사람 판단이 필요하다. _(출처: Jobscan — Top Resume Keywords; The Interview Guys)_
23
+ - **지원 URL로 ATS 플랫폼을 식별해 파일형식·전략을 조정하라.** apply URL이 `greenhouse.io`·`lever.co`·`*.myworkdayjobs.com`·`icims.com`을 포함하면 무료·결정론적 신호다. Greenhouse/Lever는 PDF 텍스트 레이어를 잘 파싱하고, 일부 구형 Taleo/iCIMS는 어려워한다. Workday는 후보가 대부분 필드를 **재입력(re-key)** 하므로 파싱 품질보다 **knockout 문항·프로필 필드**가 더 중요하다 — 우선순위는 **플랫폼 조건부**다. _(출처: Huntr — How ATS Work 2026; 시니어 리크루터 리뷰)_
24
+
25
+ ### 한국 트랙 (영어권 ATS와 다른 게임)
26
+
27
+ - 사람인/잡코리아/원티드/그리팅 등은 **문항 기반 자기소개서 지원서**가 핵심이다. 자유양식 이력서 파싱 루브릭(단일 컬럼·표준 헤더·MMM YYYY 날짜)은 부분적으로만 적용되며, 날짜('2023.01 ~ 현재', '재직중')·직급 체계는 로케일 분기가 필요하다.
28
+ - 한국 지원서에서는 **각 문항에 대한 답변 품질**과 **자격 요건 충족**이 ATS 포맷보다 우선한다. 이 경우 §3 루브릭 중 R1/R2/R7(포맷·헤더·텍스트레이어)만 적용하고 R6(날짜)·R5(약어)는 면제하라.
29
+
30
+ ### Do
31
+
32
+ - 이력서를 한 컬럼·위→아래·역연대순(최근 우선)으로 배치한다.
33
+ - 직역 표준 헤더를 쓴다: Summary, Skills, Work Experience, Education, Certifications.
34
+ - 이름·전화·이메일·도시/지역을 맨 위 본문에 **plain text 줄**로 넣는다.
35
+ - `get_application_context`로 JD의 필수·반복 용어를 먼저 추출하되, **무엇이 must-have/nice-to-have인지의 선정은 외부 AI가** 하고(이 판단은 CareerMate가 못 한다), 증거가 있는 곳에만 정확한 문자열을 녹인다.
36
+ - 시맨틱 등가물도 함께 커버한다(예: 'Node.js' 본문에 두면 'NodeJS' 검색도 의식).
37
+ - 지원 URL로 ATS를 식별해 파일형식·우선순위를 조정한다(§원칙 마지막).
38
+ - 날짜를 'MMM YYYY – MMM YYYY'(예: 'Jan 2023 – Present')로 직함과 같은 줄에 일관 표기한다. **한국어 이력서는 '2023.01 ~ 현재' 로케일 형식을 허용한다.**
39
+ - **테뉴어 타임라인 무결성**을 확인한다: 날짜 존재뿐 아니라 순서 일관성, 파서가 재직기간을 계산 가능한지, 겹침/공백이 사람 스크리닝을 유발하지 않는지.
40
+ - 약어는 **모호한 경우에만** 확장형을 한 번 쓴다(업계 표준 약어는 그대로).
41
+ - plain 불릿(• 또는 -)과 표준 폰트(Arial, Calibri, Times New Roman, 10–12pt)를 쓴다.
42
+ - .docx 또는 진짜 텍스트레이어 PDF로 저장·전달하고, 텍스트가 선택/복사되는지 확인한다.
43
+ - knockout 문항(비자/스폰서십·학위/자격·근무지·연봉·경력연수)을 **후보 프로필의 사실과 대조한 3-state(매치/미스매치/불명) 프리플라이트**로 사용자에게 제시한다.
44
+ - **LinkedIn/프로필 패리티**를 맞춘다: 직함 정렬·키워드 미러링을 LinkedIn 헤드라인·스킬에도 적용한다(소싱 상당수가 ATS가 아니라 LinkedIn 검색에서 일어난다).
45
+ - 한 회사 다중 역할은 회사를 한 번 적고 역할을 들여쓰기로 묶는다(umbrella method).
46
+
47
+ ### Don't
48
+
49
+ - 이력서 본문에 표·다단/좌우 병렬·텍스트박스를 쓰지 마라.
50
+ - 연락처·스킬·키워드를 헤더/푸터나 이미지/그래픽 안에 넣지 마라.
51
+ - 표준 헤더 대신 창의적 섹션명('What I've Done', 'My Story')을 쓰지 마라.
52
+ - 선택 가능한 텍스트 레이어가 없는 스캔/이미지 PDF를 제출하지 마라.
53
+ - 키워드 스터핑·부자연스러운 반복·흰색/투명/1pt 숨김 텍스트로 점수를 조작하지 마라.
54
+ - 후보가 뒷받침 못 하는 스킬/키워드를 발명·과장하지 마라(사람이 파싱 텍스트를 읽고 거른다).
55
+ - 그래픽·아이콘·평점 바·스킬 퍼센트 차트로 정보를 전달하지 마라.
56
+ - 높은 'match score'가 면접을 보장한다고, 또는 ATS가 점수로 자동 탈락시킨다고 가정하지 마라 — 진짜 게이트는 knockout 문항·사람 검토·(대량채용의) AI 랭킹이다.
57
+ - 고정된 'PDF=자동거부' 신화를 믿지 마라 — 플랫폼 조건부다.
58
+ - 모든 약어를 기계적으로 풀어쓰지 마라(AWS/SQL/CPA 등 표준 약어는 그대로).
59
+ - 날짜를 문단 안에 묻거나 생략하지 마라 — 파서가 타임라인을 만들 수 없다.
60
+
61
+ ### 워크드 예시 (Before → After)
62
+
63
+ 1. **Before:** SKILLS 섹션을 3열 표로 작성
64
+ `| Languages | Frameworks | Tools |` / `| Python | Django | Docker |` / `| Go | React | AWS |`
65
+ **After:**
66
+ `Skills`
67
+ `Languages: Python, Go`
68
+ `Frameworks: Django, React`
69
+ `Tools: Docker, AWS`
70
+ **왜 더 나은가:** 파서가 표를 가로로 읽어 'Languages Frameworks Tools Python Django Docker...'처럼 뒤섞으면 그룹핑이 깨진다. 단일 컬럼 쉼표 목록은 각 용어를 깨끗한 줄에 둬 'Python'·'React'·'AWS'가 각각 인덱싱되고 검색에 노출된다.
71
+
72
+ 2. **Before:** 페이지 헤더 영역(.docx page-header)에 'Jane Park — jane@email.com — 010-1234-5678', 본문은 'PROFILE'로 시작.
73
+ **After:** 본문 1행 'Jane Park', 2행 'Seoul, South Korea | jane@email.com | 010-1234-5678', 3행 헤딩 'Summary'.
74
+ **왜 더 나은가:** 헤더 영역 연락처는 **일부 파서**가 건너뛰어 리크루터가 연락 수단 없는 이력서를 받고 자동완성이 비는 실패가 실재한다. 본문 plain text로 옮기면 어느 파서에서도 추출이 보장된다. 'PROFILE'도 표준 'Summary'로 정규화했다.
75
+
76
+ 3. **Before:** Experience 불릿 'Led cross-functional initiatives to improve discoverability of our content.' (JD는 'SEO'·'Google Analytics' 요구)
77
+ **After:** 'Led Search Engine Optimization (SEO) initiatives using Google Analytics, lifting organic traffic 38% in 6 months.'
78
+ **왜 더 나은가:** 원문엔 JD 정확 문자열 'SEO'·'Google Analytics'가 없어 boolean 검색에서 자격 있는 후보가 누락된다. 재작성은 정확 용어(모호한 SEO는 확장형 동반)와 구체 수치를 동시에 넣어 파서/검색과 사람 독자를 모두 만족시키되, 실제 한 일이라 날조가 아니다. **이 불릿이 최근 역할에 있을수록 가중치가 높다**(§R4 recency 신호 참조).
79
+
80
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
81
+
82
+ > **책임 경계:** CareerMate는 **결정론적 측정**(개수·존재여부·패턴·비율)만 한다. **무엇이 JD 핵심 용어인가, 약어가 모호한가, 직함이 진실한가, JD가 어떤 hard requirement를 명시하는가**의 **판단은 외부 AI**가 jd_terms·knockouts 등으로 미리 제공해야 한다. 아래 임계값(0.70, ≤4회 등)은 **발명된 magic number가 아니라 권장 출발점**이며, AI가 JD/문서 길이/역할 수에 맞게 조정한다. 일부 체크는 **자문(advisory)** 이지 하드 게이트가 아니다.
83
+
84
+ | ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) |
85
+ |----|-----------|-----------|--------------------------------|
86
+ | R1 | 단일 컬럼 | 표/텍스트박스 구조 0개 | **.docx 원본에서만 신뢰**: `w:tbl`·`w:txbxContent` XML 요소 카운트 == 0. **PDF는 컬럼 검출 불가** — x-좌표 위치 정보 없이는 신뢰 불가하므로 '검출 불가, 사용자 경고'로 정직히 강등. 텍스트 공백-갭 휴리스틱은 약한 보조 신호로만(거짓양성: 우측 정렬 날짜줄). |
87
+ | R2 | 표준 헤더 | {Summary/Profile, Skills, Experience, Education, Certifications} 중 ≥3 존재, 그 자리에 비표준 헤딩 0 | 추출 텍스트를 표준 헤딩 화이트리스트와 대소문자 무시 substring 매칭, 카운트(≥3)하고 화이트리스트 밖 헤딩 줄 플래그. 순수 문자열 매칭. |
88
+ | R3 | 본문 연락처 | 이메일·전화 정규식이 본문에서 각각 ≥1 | 본문 추출 텍스트에 이메일 `[\w.+-]+@[\w-]+\.[\w.-]+` ≥1, 전화 숫자 패턴 ≥1. **.docx는 헤더/푸터 XML에 *only* 존재하는 경우(중복 아님)를 직접 겨냥해 플래그**; PDF는 헤더/본문 구분 불가라 본문 매치만 확인. |
89
+ | R4 | JD 키워드 커버리지 + recency | must-have 용어 커버리지 비율 ≥ 0.70(권장 출발점, AI 조정). **+ 최근 역할 배치 가중** | jd_terms[]는 **외부 AI가 추출·정규화**(lowercase, 구두점 제거, '.js'/'js' fold, 단·복수 dedupe, 동의어 묶음)해 제공. CareerMate는 정규화된 용어를 substring이 아니라 **토큰 경계 매칭**으로 카운트(raw substring은 'Java'⊂'JavaScript', 'lead'⊂'leadership' 거짓양성 유발 → 금지). 추가로 **각 용어가 최근(상단) 역할에 있는지** 위치 플래그를 반환해 AI가 recency 가중. |
90
+ | R5 | 약어 확장 (**advisory**) | 모호한 약어만: 확장형 동반 권장. 업계 표준 약어 화이트리스트(AWS/SQL/API/REST/SaaS/GCP/CPA/PhD/CEO/USA 등) **면제**. 월 약어·고유명사 면제 | 대문자 토큰 정규식 추출 후 **표준 약어 화이트리스트·월 약어를 먼저 제외**, 남은 모호 후보만 'long form (ABC)' 페어링 존재 확인. **하드 게이트 아님 — 자문**. (AI가 모호성 판단) |
91
+ | R6 | 날짜·테뉴어 무결성 | 모든 역할 항목에 파싱 가능한 날짜 범위 + 순서 일관 + 겹침/공백 없음 | 영문 `(Jan|...|\d{4})\s*[–-]\s*(Present|\d{4})` **또는 한국어 `\d{4}\.\d{2}\s*[~–-]\s*(현재|재직중|\d{4})`** 로 로케일 분기. 역할 헤딩 수 대비 비율 1.0. 추가로 날짜를 정렬해 **겹침/공백 구간을 카운트**(>0이면 사람 스크리닝 유발 가능 플래그). |
92
+ | R7 | 파일 텍스트 레이어 | 추출 텍스트 길이 > 300자, 형식 .docx 또는 text-PDF(이미지-PDF 아님) | `read_document`로 추출 후 글자수 측정. PDF인데 near-zero면 이미지-only → fail. 카운트 체크. |
93
+ | R8 | 스터핑·숨김 텍스트 | 핵심 용어 반복이 **문서 길이/역할 수 정규화** 상한 이내, 숨김 텍스트 런 0 | 용어별 occurrence 카운트를 **역할 수·페이지 수로 정규화**(2페이지 시니어 이력서는 핵심 언어 6–8회가 정상 → 고정 4회 상한 금지). 숨김 검출은 `w:color val='FFFFFF'`뿐 아니라 **폰트색==배경색·≤1pt 폰트·텍스트=배경이미지** 케이스까지 스캔(FFFFFF만 보면 회피 쉬움). 커버리지 한계는 정직히 고지. |
94
+ | R9 | knockout 프리플라이트 (3-state) | JD 명시 hard requirement **각각 × 후보 프로필 사실 = 매치/미스매치/불명** 매트릭스 존재. 빈 헤더만으로는 불합격 | JD hard requirement 추출(visa/degree/location/years/salary)은 **외부 AI 판단**(자기기만 방지: 존재≠정확). knockout 답은 **CareerMate 프로필 데이터**의 사실(시민권/비자/학위)에서 와야 함. CareerMate는 각 항목이 (a) JD에 명시됐고 (b) 프로필 사실과 대조됐고 (c) 3-state 중 하나로 라벨됐는지 **구조 존재**를 카운트. **LLM 의존 단계임을 명시**. |
95
+ | R10 | 직함 정렬 (**advisory**) | JD 핵심 직함 구(또는 진실한 동의어)가 헤드라인/최근 역할줄에 등장 | JD 직함 토큰을 상단 헤드라인/첫 역할줄에 substring 매칭. **단 '진실성'은 검증 불가 — AI/사람 판단**. 한국식 직급↔영문 충돌도 AI 판단. 하드 게이트 아님. |
96
+
97
+ **주요 실패 모드:**
98
+ - **substring 거짓양성/거짓음성:** raw substring 매칭은 'Java'⊂'JavaScript', 'lead'⊂'leadership'를 오매칭한다. 토큰 경계 + 외부 AI 정규화·동의어 묶음으로만 막을 수 있다(R4).
99
+ - **PDF 컬럼 검출 환상:** 텍스트 추출이 컬럼을 단일 스트림으로 reflow하면 진짜 문제가 숨는다. PDF는 '검출 불가, 경고'로 정직히 강등한다(R1).
100
+ - **약어 오탐 폭탄:** 모든 대문자 토큰에 확장형을 요구하면 AWS/SQL/CEO/월약어가 전부 fail한다 → 화이트리스트 면제 + advisory(R5).
101
+ - **knockout 자기기만:** 빈 헤더만 써넣어도 '존재'로 통과 + JD 텍스트만으로는 mismatch 판정 불가 → 프로필 사실 대조 3-state 강제(R9).
102
+ - **로케일 미대응:** 영문 'MMM YYYY'·'Present'·'FFFFFF 흰배경' 가정은 한국어 이력서·색배경 디자인을 100% 오판한다 → 로케일 분기(R6)·다중 숨김 케이스(R8).
103
+ - **magic number 과신:** 0.70·≤4회는 출발점이지 법칙이 아니다. AI가 JD/문서 길이로 조정한다.
104
+ - **루브릭 자체의 정밀도 미검증:** 이 결정론 루브릭이 깨끗한 이력서를 오탈락시키지 않는지 보장하려면 **소규모 라벨드 픽스처 세트**(예: 손으로 채점한 known-good 이력서 10건)로 회귀 검증이 필요하다 — Phase B 과제로 명시.
105
+ - **결과 오인:** 루브릭 만점은 **파싱가능성·검색노출의 필요조건 점검**일 뿐 합격/면접 예측이 아니다. 추천·다이렉트소싱·소규모 기업은 ATS와 무관하게 진행되며, 만점이어도 knockout·사람·AI 랭킹에서 떨어질 수 있다.
106
+
107
+ ## 4. 출처 (Provenance)
108
+
109
+ > **증거 한계 고지:** 핵심 파싱 주장은 Jobscan(ATS 최적화 도구를 파는 벤더 — 파싱 취약성 과장 인센티브)과 대학 커리어센터(상호 인용·수년 지연)에 기댄다. 일화 1건('디자인 이력서가 work-experience만 파싱')과 가이드 다수가 근거이며, '헤더/푸터를 실제로 무시하는 ATS 비율'·'단일 vs 멀티컬럼 파싱 실패율' 같은 **정량 효과(effect size)는 미검증**이다. 1차 파서 벤더(Sovren/Textkernel/HireAbility/Affinda) 또는 각 ATS 자체 help docs가 파싱 동작의 권위 있는 출처이나 본 플레이북에는 미반영 — **규칙 영향도는 ATS 벤더·버전별로 다르며 정량 효과는 미검증**임을 전제로 적용하라.
110
+
111
+ - **Jobscan — Why ATS Tables and Columns Break Your Resume Parsing (2026)** — 선형 파싱, 표/다단 word-salad 실패, 세로바/쉼표/불릿 대안, umbrella method · https://www.jobscan.co/blog/resume-tables-columns-ats/ _(벤더, 상업적 편향 가능)_
112
+ - **Jobscan — 5 Critical ATS Resume Formatting Mistakes (2026)** — 헤더/푸터·텍스트박스 누락(일부·구형 한정으로 해석), 본문 연락처, 단일컬럼/폰트/마진 기본값 · https://www.jobscan.co/blog/ats-formatting-mistakes/ _(벤더)_
113
+ - **UVA / Santa Clara / U. Maryland / U. Utah / UMN Duluth Career Center ATS guides** — 표준 헤딩, 역연대순, .docx/PDF 수용, plain 불릿, 10–12pt 폰트(다수 대학 교차 확인) · https://www.scu.edu/careercenter/toolkit/job-scan-common-ats-resume-formatting-mistakes/ _(상호 인용 가능, 지연 가능)_
114
+ - **Indeed Career Advice — How To Write an ATS Resume** — 보편 표준 섹션(Work Experience/Education/Skills/Certifications)과 템플릿 구조 · https://www.indeed.com/career-advice/resumes-cover-letters/ats-resume-template
115
+ - **Teal — Resume Keywords / Scale.jobs — Match Keywords** — exact-match 우선, JD 미러링, 약어+확장(좁게), 자연스러운 배치, 스터핑 회피 · https://www.tealhq.com/post/keywords-for-resume
116
+ - **The Interview Guys — ATS Resume Hack & What ATS Looks For** — knockout/사전 스크리닝이 진짜 자동 부적격기, 직함 정렬 · https://blog.theinterviewguys.com/ats-resume-hack/
117
+ - **Huntr — How Applicant Tracking Systems Actually Work (2026)** — 플랫폼별 knockout 동작(Workday/Greenhouse/Taleo/iCIMS/Workable), URL로 ATS 식별, Workday 재입력 현실 · https://huntr.co/blog/how-applicant-tracking-systems-work
118
+ - **The Tech Resume — ATS Myths Busted** — 'PDF 거부'·'점수 자동탈락' 신화 반박(단, 대량채용 AI 랭킹은 별개), 파싱→boolean/자동완성·사람이 거름(Amazon/Google/Microsoft 리크루터 인용) · https://thetechresume.com/samples/ats-myths-busted.html _(단일 강주장 출처 — 과의존 주의)_
119
+ - **시맨틱/임베딩 매칭 동향 (Eightfold / HiredScore / Workday Skills Cloud, 2026)** — 일부 최신 ATS가 stemming·동의어·임베딩 시맨틱 매칭·AI 랭킹/숏리스트를 실제 운용 → exact-match 단독 가정 보정 _(2차 동향, 정량 미검증)_
120
+ - **Wikipedia — Applicant Tracking System** — ATS의 일반 정의·생태계 프레이밍(운영 디테일은 근거하지 않음) · https://en.wikipedia.org/wiki/Applicant_tracking_system
121
+
122
+ ## 5. Phase B 힌트 (아키텍처로 연결)
123
+
124
+ - **MCP 도구 아이디어:**
125
+ - `get_ats_checklist` — principles·do/don't·countable rubricChecks를 구조화 JSON으로 반환(AI가 작성 중 적용).
126
+ - `analyze_ats_fit({ resume_id, job_id })` — **LLM 없이 계산 가능한 raw 결정론 신호**만 반환: 추출 텍스트, 탐지 헤더, .docx의 `w:tbl`/`w:txbxContent` 카운트, 텍스트레이어 길이, 본문 연락처 매치, 로케일 분기 날짜·겹침/공백, jd_terms 커버리지 맵, 숨김 텍스트 후보. **jd_terms 추출·정규화·동의어 묶음과 knockout hard-requirement 추출은 호출하는 AI가 입력으로 제공**(CareerMate는 카운팅만). 결과를 `save_fit_analysis`에 연결.
127
+ - (Phase B 과제) **fixture 회귀 세트** — known-good 이력서 ~10건을 손 채점해 루브릭이 깨끗한 이력서를 오탈락시키지 않는지 정밀도/재현율 측정.
128
+ - **데이터 형태 힌트:**
129
+ - `ats_checklist: { principles:[{rule,rationale,source}], rubricChecks:[{id,check,passBar,measure,advisory:bool,llm_dependent:bool}] }`
130
+ - `ats_signals: { file_type:'docx'|'pdf_text'|'pdf_image', locale:'en'|'ko', text_len:int, table_count:int, textbox_count:int, columns_detectable:bool, headers_found:string[], contact:{email:bool,phone:bool,in_body:bool,header_only:bool}, dates_ok_ratio:float, tenure_overlaps:int, tenure_gaps:int, jd_terms:[{term,normalized,required:bool,found:bool,in_recent_role:bool}], coverage_ratio:float, acronyms:[{token,expansion_found:bool,whitelisted:bool}], hidden_text_runs:int, knockouts:[{type:'visa'|'degree'|'location'|'salary'|'years', jd_value:string|null, profile_value:string|null, state:'match'|'mismatch'|'unknown'}], ats_platform:'greenhouse'|'workday'|'lever'|'taleo'|'icims'|'unknown' }`
131
+ - 각 rubric 체크가 ats_signals 필드와 1:1 매핑돼 AI가 결정론 pass/fail 표를 렌더(R5/R10은 advisory, R9는 llm_dependent 라벨). CareerMate=측정, AI=판단의 책임 분리를 구조로 강제.