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,132 @@
1
+ # 면접 — 행동 / Behavioral Interview — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ 행동 면접은 "과거 행동이 미래 성과를 예측한다"는 행동 일관성(behavioral consistency) 원리에 기반한 구조화 면접이다. 면접관은 지원자의 과거 사례를 STAR(Situation·Task·Action·Result) 형태로 듣고, 직무 관련 역량(competency)·회사 가치에 매핑해 채점한다. CareerMate는 LLM이 없으므로, 연결된 외부 AI가 사용자의 실제 경험을 STAR로 재구성하고, 역량에 매핑하며, 실측 정량 결과를 분리해내고, **후속 질문(probing)에 견디는 스토리 뱅크**를 만들도록 돕는 지식·루브릭을 제공한다. 핵심은 ① 개인 기여를 1인칭으로 분리, ② Result를 **검증 가능한** 실측 수치로, ③ 각 스토리를 controlled vocabulary 역량 태그에 매핑, ④ 사례마다 probing 답(왜·대안·되돌아보면)을 미리 준비하는 것이다. 아래 루브릭은 어느 체크가 **결정론적으로 셀 수 있고(D)**, 어느 체크가 **외부 AI의 의미 판단을 전제로 한 보조 휴리스틱(H)**인지를 등급으로 명시 구분한다 — 전부 동급의 기계 검증인 척하지 않는다.
8
+
9
+ ## 2. 플레이북
10
+
11
+ ### 원칙
12
+
13
+ - **(STAR 4요소를 빠짐없이 채우되, Action에 가장 많은 분량과 '결정의 밀도'를 둔다.)** — 면접관이 평가하는 것은 Situation의 장황함이 아니라 지원자가 내린 구체적 결정·행동이다. Result가 빠지면 임팩트 평가가 불가능하다. **단, 'Action 50% / Result 25% / Situation 15% / Task 10%'라는 비율은 1차 채점 연구가 아니라 대학 커리어센터의 코칭 휴리스틱일 뿐이므로, 합격 게이트가 아니라 soft 가이드로만 쓴다.** 길이가 아니라 '구체 결정 동사 개수'가 Action 품질의 진짜 신호다. _(출처: Northwestern Career Advancement STAR Approach — 휴리스틱, 4절 신뢰도 주석 참조)_
14
+ - **(Action·Result는 'we'가 아니라 'I/제가'로 개인 기여를 분리해 쓴다.)** — 면접관은 팀이 아니라 지원자 개인의 역량을 채점한다. 팀 맥락은 Situation에서 한 줄로 깔고, Action에서 '제가 ~을 결정/제안/구현했다'로 본인 행동을 드러낸다. **한국어는 주어 생략이 자연스러우므로('~을 제안했습니다') 'I' 토큰 카운트가 아니라 '제가/내가' 명시 빈도 + 집단대명사(저희/우리) 대비로 측정한다.** _(출처: UVA Career Center, Bauer College STAR guide)_
15
+ - **(Result는 실측 수치로 정량화하되, 검증 가능성과 짝지어 쓴다.)** — 가능하면 숫자+단위(%, 시간, 금액, 인원, 순위, 기간)로 표현한다. **단, "만족도 100%"·"효율 200% 개선" 같은 분모·기간·출처 없는 숫자는 probing에서 즉시 무너진다.** 각 수치에는 측정 범위(label)와 원자료 링크(sourceRef)를 붙여 진위를 보장한다. 정량화가 불가능하면 검증 가능한 정성 결과(채택됨/재현됨/재계약)와 학습을 명시한다. _(출처: Amazon STAR guidance, UVA Career Center)_
16
+ - **(답변 전, 질문이 겨냥하는 역량/회사가치를 controlled vocabulary로 먼저 식별하고 매핑한다.)** — 구조화 면접의 변별력은 표준화·동일 질문·앵커드 채점표(BARS)에서 나오며, 역량 매핑은 그 일부다(역량 매핑 단독이 우수성의 원인이라는 단정은 과도 단순화). 채용공고 요구 역량에서 역으로 스토리를 고른다. **태그 인플레이션을 막기 위해 역량은 고정 enum을 쓴다(아래 택소노미).** _(출처: U.S. OPM Structured Interviews; Northwestern)_
17
+ - **(스토리 뱅크를 미리 8~12개 구축하고, 각 사례에 probing 답 3종을 함께 준비한다.)** — 한 사례를 여러 질문에 변주해 즉석 누락을 막는다. **Amazon 루프 등에서 후보가 떨어지는 1순위는 첫 답변이 아니라 probing 붕괴이므로, 각 사례에 '왜 그 결정을 했나 / 대안은 무엇이었나 / 되돌아보면 무엇을 바꾸겠나' 답을 미리 채운다.** _(출처: Amazon Behavioral Interview 가이드, UVA·Wisconsin 등)_
18
+ - **(사례는 최신성·직무관련성을 갖춰야 한다.)** — 시니어/경력직에게 8년 전 인턴·학부 프로젝트만 가득한 뱅크는 반려 사유다. 각 사례에 연도·역할단계를 기록하고, 경력직은 최근 N년 내 사례 비율을 확보한다. _(출처: 채용 실무 — recency/relevance, hiring manager review)_
19
+ - **(사실·수치·고유명사는 절대 지어내지 않는다. 실패 사례는 조건부로만 쓴다.)** — 면접관은 probing으로 꾸민 이야기를 검증한다. 실패 사례는 회복·재발방지 행동이 Result보다 길고 구체적일 때만 강점이 되며, 일부 문화권 면접관은 부정 신호로 받을 수 있으므로 '학습·후속 개선'이 핵심이 아닐 거면 쓰지 않는다. _(출처: CareerMate AGENTS.md, Amazon probing follow-ups, UVA)_
20
+ - **(키워드 스터핑을 경계한다.)** — 회사 가치에 '단어 수준으로 맞추라'는 조언은 과하면 '준비된 앵무새'로 보인다. LP/가치 키워드는 실제 사례의 행동이 그 가치를 **입증**할 때만 쓰고, 키워드를 라벨처럼 나열하지 않는다. 구조화 면접은 adverse impact를 줄이고 법적 방어가능성을 높이는 공정성 도구라는 점도 기억한다. _(출처: U.S. OPM Structured Interviews)_
21
+
22
+ ### Do
23
+
24
+ - 질문을 받으면 먼저 '이 질문이 겨냥하는 역량/회사가치'를 controlled vocabulary 태그로 한 줄 명시하고 스토리를 매핑하라.
25
+ - STAR 4요소를 모두 채우고, Action에 '구체 결정 동사(결정/제안/설계/구현/협상/분석)' 3개 이상을 1인칭으로 담아라. Situation·Task는 각각 1~2문장으로 압축하라.
26
+ - Action·Result는 '제가/내가 ~했다'로 본인 기여를 분리하라(한국어는 '저희/우리' 습관을 의식적으로 '제가'로 전환).
27
+ - Result에 **사용자 실측** 숫자+단위를 최소 1개 넣고, 각 수치에 label(무엇을 잰 것인지)과 sourceRef(원자료)를 붙여라. 불가능하면 검증 가능한 정성 결과+학습을 명시하라.
28
+ - 8~12개 핵심 사례로 스토리 뱅크를 만들고, 각 사례를 여러 역량 enum에 다중 태깅하며, **사례마다 probing 답 3종을 채워라.**
29
+ - 각 사례에 연도·역할단계를 기록하고, 경력직은 최근 사례를 우선 배치하라.
30
+ - 채용공고 요구 역량에서 역으로 어떤 사례를 쓸지 고르고, 회사 고유 가치를 '키워드'가 아니라 '행동으로 입증'하는 방식으로 맞춰라.
31
+ - 실패/약한 결과 사례는 회복·재발방지 행동이 충분할 때만 쓰고, '내 판단의 오류'와 '배운 점·후속 개선'으로 프레이밍하라.
32
+ - 답변을 소리 내어 리허설해 30초~2분(영어 약 130~330단어 / 한국어 약 90~230어절)로 다듬어라.
33
+
34
+ ### Don't
35
+
36
+ - Situation/배경을 장황하게 늘어놓아 Action이 묻히게 하지 마라(Situation이 답변의 25%를 넘기면 경고 신호).
37
+ - 팀 성과를 'we/저희'로만 서술해 본인 기여를 흐리지 마라.
38
+ - Result를 생략하거나 '잘 끝났다' 같은 모호한 표현으로 뭉뚱그리지 마라.
39
+ - **검증 불가능한 가짜 숫자('만족도 100%', '효율 200%')를 채워 넣지 마라** — probing에서 분모·기간을 묻는 순간 무너진다.
40
+ - 수치·날짜·고유명사를 지어내거나 과장하지 마라.
41
+ - 하나의 만능 사례를 모든 질문에 우겨넣지 마라(같은 스토리를 3개 이상 다른 질문에 재탕 금지).
42
+ - '저는 열정적이고 성실합니다' 같은 형용사 나열로 답하지 마라 — 행동·증거로 보여라.
43
+ - 회사 가치/LP 키워드를 행동 입증 없이 라벨처럼 나열하지 마라('준비된 앵무새' 신호).
44
+ - 미래 가정형('저라면 ~할 것입니다')으로만 답하지 마라 — 실제 과거 사례를 들어라.
45
+ - 5년 전 학부 프로젝트만으로 시니어 직무에 답하지 마라(최신성·직무관련성 결여).
46
+
47
+ ### 워크드 예시 (Before → After)
48
+
49
+ > 아래 after의 모든 수치는 **사용자가 제공한 실측 데이터**이며 각 수치에 label·sourceRef가 연결되어 있다는 전제다.
50
+
51
+ 1. **Before:** 질문: '갈등을 해결한 경험을 말해보세요.' 답변: "저희 팀은 의견 차이가 있었지만 서로 소통하며 잘 협력해서 결국 프로젝트를 성공적으로 마쳤습니다. 저는 항상 팀워크를 중요하게 생각하고 갈등 상황에서도 긍정적으로 대처하는 편입니다."
52
+ **After:** `[역량: conflict, ownership]` **S:** 작년 출시 2주 전, 디자이너와 개발자가 핵심 화면 구현 범위로 충돌해 일정이 멈췄습니다(1문장). **T:** PM이던 제가 양쪽 합의안을 도출해 일정을 지키는 것이 목표였습니다. **A:** 저는 두 사람을 따로 인터뷰해 진짜 우려(디자인 완성도 vs 공수)를 분리한 뒤, 화면을 'MVP 필수/후속' 두 단계로 쪼개는 안을 직접 와이어프레임으로 제안했고, 후속 항목의 사용 빈도가 낮음을 데이터로 보여 합의를 끌어냈습니다. **R:** 일정 지연 0일로 정시 출시했고, 분리한 후속 기능은 다음 스프린트에 반영, 해당 출시의 D+7 리텐션이 기존 대비 12%p 높았습니다(label: D+7 retention, source: 사내 대시보드). **Probing 준비:** (왜) 데이터로 설득한 이유 / (대안) 일정 연기 vs 범위 축소 비교 / (되돌아보면) 충돌 초기에 데이터를 먼저 꺼냈으면 더 빨랐을 것.
53
+ **왜 더 나은가:** Before는 'we'·형용사 나열·결과 무수치·미래형 혼재로 채점 불가. After는 역량 매핑 명시, S/T 압축, Action을 1인칭 구체 결정 동사로 채움, Result를 label·source 붙은 실측 수치(0일·12%p)로 정량화하고 probing 3종을 갖춰 후속 질문에 견딘다.
54
+
55
+ 2. **Before:** 질문: "Tell me about a time you took ownership." 답변: "We had a production bug and we worked together to fix it. It was stressful but we managed to resolve it and customers were happy in the end."
56
+ **After:** `[역량: ownership, customer-focus]` **S:** 결제 API에서 0.8% 거래가 실패하는 버그가 새벽에 발생했습니다. **T:** 온콜이 아니었지만 제가 영향 범위를 끝까지 책임지기로 했습니다. **A:** I triaged logs, isolated a race condition in the retry handler, shipped a hotfix within 70 minutes, then wrote a postmortem and added a regression test + an alert so it couldn't silently recur. **R:** 영향 거래의 100%를 수동 재처리해 매출 손실 0원, 동일 클래스 장애 재발 0건(6개월 추적), 알람 덕에 평균 탐지시간을 ~40분에서 ~3분으로 단축(label: MTTD, source: 모니터링 로그). **Probing 준비:** (왜) 온콜이 아닌데 책임진 이유 / (대안) 롤백 vs 핫픽스 트레이드오프 / (되돌아보면) 알람을 사전에 뒀어야 함.
57
+ **왜 더 나은가:** Before는 전부 'we'·정량 결과 없음·역량 무매핑. After는 ownership/customer-focus 매핑, 1인칭 결정 동사, label·source 붙은 실측 수치(0.8%·70분·0원·40→3분)로 임팩트를 증명하고 probing 3종으로 Amazon 루프식 깊이 질문에 대응한다.
58
+
59
+ 3. **Before:** 질문: '실패한 경험을 말해보세요.' 답변: "저는 큰 실패는 없었던 것 같습니다. 굳이 꼽자면 시간 관리가 조금 아쉬웠는데, 지금은 잘 관리하고 있습니다."
60
+ **After:** `[역량: growth-learning]` **S:** 첫 사이드프로젝트에서 사용자 검증 없이 4개월간 기능부터 만들었습니다. **T:** 출시 후 사용자를 모으는 것이 목표였습니다. **A:** 저는 가설 검증을 건너뛴 채 개발에 몰입했고, 출시 후에야 핵심 가정이 틀렸음을 알았습니다. 이후 저는 즉시 10명 인터뷰를 돌려 문제를 재정의하고, 2주짜리 프로토타입으로 다시 검증하는 방식으로 프로세스를 바꿨습니다(재발방지 행동이 Result보다 김). **R:** 원래 제품은 가입 9명에 그쳤지만, 재검증 후 만든 버전은 4주 만에 활성 사용자 120명을 모았습니다(label: WAU, source: 가입 로그). '만들기 전에 검증한다'를 이후 모든 프로젝트의 기본 규칙으로 삼았습니다. **Probing 준비:** (왜) 검증을 건너뛴 이유 / (대안) MVP를 먼저 냈다면 / (되돌아보면) 4개월→2주로 단축한 학습.
61
+ **왜 더 나은가:** Before는 실패를 회피해 자기인식·성장성을 증명하지 못한다. After는 진짜 실패를 정직하게 인정하고, **재발방지 행동을 Result보다 길게** 써 학습을 증명하며(조건부 실패 사례 원칙 충족), 정량 대비(9명→120명)로 회복을 보인다.
62
+
63
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
64
+
65
+ > **전제(중요):** 루브릭은 자유 텍스트가 아니라 **`StoryBankEntry` 구조화 레코드 배열**을 입력으로 받는다. S/T/A/R 경계는 자유 텍스트를 LLM이 의미로 갈라야 하므로, CareerMate는 먼저 `save_interview_prep`으로 STAR를 **필드 분리 저장**하게 한다. 그러면 다수 체크가 필드 non-empty / 패턴 카운트로 결정론적이 된다.
66
+ >
67
+ > **등급 표기:** `D` = LLM 없이 결정론적으로 셀 수 있음(필드 존재·정규식·카운트). `H` = 외부 AI(또는 사람)의 의미 판단을 전제로 한 보조 휴리스틱 — 자동 합격 판정 금지, `warn`/`needs_review`로만 반환. 이 구분을 흐려 전부 기계 검증인 척하지 않는다.
68
+
69
+ | ID | 등급 | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게 / H는 전제 명시) |
70
+ |----|------|-----------|-----------|--------------------------------|
71
+ | R1 BI-STAR-FIELDS | **D** | STAR 4필드가 모두 채워졌는가 | 각 entry의 `star.situation/task/action/result` 4필드 모두 non-empty (특히 result 누락 0) | 4필드 `len(trim)>0` 카운트 ==4. **필드 분리 저장 전제이므로 의미 라벨링 불필요.** result 필드 boolean 별도 체크. |
72
+ | R2 BI-SITUATION-CAP | **D** | Situation이 과도하게 길지 않은가 (anti-pattern) | `wordCounts.s / wordCounts.total <= 0.25` | 필드별 단어/어절 수 비율 계산. **Action 비율을 합격 게이트로 강제하지 않음**(50/25/15/10은 휴리스틱) — 대신 Situation 비대만 경고. |
73
+ | R3 BI-ACTION-DECISIONS | **H** | Action에 구체 결정 행동이 충분한가 | Action에 결정 동사 ≥3 (길이가 아닌 밀도) | 결정 동사 사전 매칭(한: 결정/제안/설계/구현/협상/분석/주도; 영: decided/proposed/designed/built/negotiated/analyzed/led) 카운트 ≥3. 사전 밖 동의어는 외부 AI 판정(H). |
74
+ | R4 BI-FIRST-PERSON | **D**(언어 분기) | Action에서 개인 기여가 1인칭으로 우세한가 | 1인칭 ≥ 집단대명사 AND 1인칭 ≥1 | **영어:** `I/my/me` 토큰 수 vs `we/our/us`. **한국어:** 주어 생략이 자연스러우므로 `제가/내가` 명시 빈도 vs `저희/우리` 빈도 비교(주어 토큰 부재≠fail). `lang` 필드로 분기. |
75
+ | R5 BI-QUANT-RESULT | **D** | Result에 정량 수치가 있는가 | `star.result`에 단위 부착 숫자 ≥1 또는 검증 가능 정성결과 플래그 | result 텍스트에서 `\d+%`, `\d+\s*→\s*\d+`, `[+\-]\d+`, `\d+(ms|초|분|시간|원|명|건|일|위|배)` 매칭 ≥1. 연도/버전 단독은 배제. 수치 없으면 `qualitative_verified` 플래그 확인. |
76
+ | R6 BI-METRIC-CREDIBLE | **D** | 각 수치가 검증 가능 메타를 갖췄는가 | `metrics[]`의 각 항목에 `label` AND `sourceRef` 모두 non-empty | over-coaching/가짜수치 가드. `metrics[]` 순회하며 둘 다 채워졌는지 카운트. 비면 "검증 불가 수치" 경고 — R5와 결합해야 '숫자만 있으면 통과'를 막는다. |
77
+ | R7 BI-COMPETENCY-TAG | **D**(존재) / **H**(적합) | 역량 태그가 controlled vocab에서 부여됐는가 | `competencies[]` ≥1 AND 모두 고정 enum에 속함 | 태그 존재·enum 소속은 D(set 검사). **태그가 '질문 의도와 실제로 일치'하는지는 H**(의미 판단) — needs_review로 분리. |
78
+ | R8 BI-PROBING-READY | **D** | 사례에 probing 답 3종이 준비됐는가 | `probing.why` / `probing.alternatives` / `probing.whatIdChange` 모두 non-empty | 3필드 존재 카운트 ==3. **probing 붕괴가 탈락 1순위이므로 핵심 게이트.** 셀 수 있는 존재 검사. |
79
+ | R9 BI-ANSWER-LENGTH | **D**(언어 분기) | 구두 전달에 적합한 길이인가 (soft) | 영어 130~330단어 / 한국어 90~230어절 | `lang`별 분기 카운트. 한국어 어절은 영어 word보다 정보밀도가 높아 동일 발화시간에 어절 수가 적다 — **'유사 범위' 금지, 언어별 임계 분리.** 범위 밖은 warn. |
80
+ | R10 BI-RECENCY | **D**(soft) | 사례가 충분히 최신인가 | 경력직: 최근 5년 내 사례 비율 ≥50% | 각 entry `year`/`careerStage` 파싱 후 `현재연도(2026) - year <= 5` 비율. 학부/인턴만 가득하면 경고(하드 실패 아님, 신입은 면제). |
81
+ | R11 BI-BANK-COVERAGE | **D** | 뱅크가 역량 카테고리를 충분히 커버하는가 | 서로 다른 entry ≥8 AND distinct 역량(enum) ≥6 | entry 개수 + `competencies[]` 합집합 distinct 카운트. **고정 enum 전제라 태그 인플레이션 없이 distinct가 유의미.** |
82
+ | R12 BI-REUSE-GUARD | **D** | 한 사례를 과도하게 재탕하지 않는가 | 같은 entry를 서로 다른 질문 유형에 매핑한 횟수 ≤2 | `questionMappings[entryId]` 카운트가 entry당 ≤2인지. 만능 사례 우겨넣기 가드. |
83
+ | R13 BI-NO-FABRICATION | **needs_review (H)** | 수치·고유명사가 지어내지 않았는가 | **자동 합격 판정 없음 — 확인 플래그만.** | **순수 set-diff 금지**(70분≈'약 1시간', 40→3분 같은 파생값, 단위변환, NER로 거짓양성/음성 폭발). 좁힌 D 검사: 답변의 숫자 리터럴이 `metrics[].value`(사용자 입력)에 매칭되는지 literal-match. 그 외 신규 수치·고유명사는 "검토 필요" 목록으로 모아 외부 AI/사람에게 토스. |
84
+
85
+ **Controlled vocabulary (역량 enum, 태그 인플레이션 방지 — distinct 카운트의 전제):**
86
+ `leadership`, `ownership`, `conflict`, `failure-learning`(=growth-learning), `initiative`, `data-driven`, `customer-focus`, `collaboration`, `deadline-pressure`, `ambiguity`, `influence`, `mentoring`. 회사 고유 가치는 `companyValueTags`(예: `Amazon:Ownership`)로 별도 부여하되, 반드시 위 enum 중 하나에 연결한다.
87
+
88
+ **주요 실패 모드:**
89
+ - **probing 붕괴(탈락 1순위):** 첫 답변만 다듬고 '왜·대안·되돌아보면'을 준비 안 함 → R8 존재 게이트로 강제.
90
+ - **가짜 수치 보상:** R5가 '숫자 존재'만 보면 조작 수치도 통과 → 반드시 R6(label+sourceRef)·R13(검토)과 결합.
91
+ - **등급 사칭(루브릭 과대광고):** S/T/A/R 라벨링·역량 적합·고유명사 진위를 'D'인 척 자동 판정 → R13은 needs_review, R3·R7(적합)은 H로 고정.
92
+ - **한국어 깨짐:** 영어 'I' 카운트를 한국어에 적용해 정상 답을 fail → R4·R9는 `lang` 분기 필수.
93
+ - **휴리스틱의 게이트화:** 50/25/15/10 비율을 합격 기준으로 강제 → R2(Situation 상한)만 게이트, Action 비율은 비게이트.
94
+ - **태그 인플레이션:** enum 없이 distinct 카운트 → R11이 무의미. 고정 vocabulary 전제.
95
+ - **노후/만능 사례:** 8년 전 사례·재탕 → R10·R12로 카운트.
96
+
97
+ ## 4. 출처 (Provenance)
98
+
99
+ > **신뢰도 주석(중요):** **예측타당도 '.51'은 Schmidt & Hunter(1998)의 수치이며, Sackett, Zhang, Berry & Lievens(2022)가 range-restriction 과대보정 오류를 지적해 사실상 하향됐다.** 보정 관행이 타당도를 과대추정했음이 드러나, 구조화 면접의 현재 최선 추정치는 **약 .42(80% credibility interval 약 .18~.66, 즉 ±.24 수준의 넓은 폭)**이고, 인지능력검사(GMA) 등 다른 도구와의 순위도 재배열됐다. **따라서 '.51로 채용 도구 중 최상위권'이라 단정하지 않는다** — 절대값은 신뢰구간으로 보고하고, 유지되는 것은 '구조화 > 비구조화'라는 **순서**뿐이다. 두 출처는 '상호 보강'이 아니라 **충돌**(후자가 전자를 보정)임을 명시한다. 또한 STAR 50/25/15/10 비율은 어느 1차 연구에도 없는 **코칭 휴리스틱**이며, 대학 커리어센터 자료는 학부생 코칭 콘텐츠이지 채용 타당도의 1차 근거가 아니다(방향성 참고용).
100
+
101
+ - **Schmidt & Hunter (1998) "The Validity and Utility of Selection Methods"** — 구조화 면접 .51 / 비구조화 .38의 **원출처(현재는 과대추정으로 간주)**. 1998년 메타분석을 2026년 정설로 인용하지 않는다.
102
+ - **Sackett, Zhang, Berry & Lievens (2022)** — range-restriction 보정 재분석. 구조화 면접 ~.42(80% CI 약 .18~.66), GMA ~.31로 하향, 신뢰구간 보고 관행. **본 문서의 헤드라인 수치는 이 보정치를 따른다.**
103
+ - **U.S. OPM — Structured Interviews** — 행동 일관성 원리, 구조화의 핵심 동인(표준화·동일 질문·앵커드 채점표 BARS), 직무관련 역량 차원 채점, adverse impact 감소·법적 방어가능성 · https://www.opm.gov/policy-data-oversight/assessment-and-selection/other-assessment-methods/structured-interviews/
104
+ - **Amazon Leadership Principles / STAR 면접 가이드** — Situation 압축·Result 정량화·Action 시간 집중, 인터뷰어가 가치 2~3개씩 배정 채점, probing follow-up(깊이 질문). **단, 한국 지원자 다수의 실제 타깃(국내 대기업 인성면접·스타트업 컬처핏)과는 거리가 있어 '대표 예시'가 아닌 '한 사례'로만 사용** · https://www.amazon.jobs/en/landing_pages/in-person-interview
105
+ - **Northwestern Career Advancement — STAR Approach** — STAR 4요소 정의, 직무기술서 기반 사례 선택 · STAR 분량 비율은 **휴리스틱**으로만 인용 · https://www.northwestern.edu/careers/jobs-internships/interviewing/the-star-approach.html _(학부 코칭 콘텐츠)_
106
+ - **UVA Career Center — STAR Method** — 'we 대신 I', Result 강조(학생 자주 누락), 부정적 결과를 회복탄력성으로 전환 · https://career.virginia.edu/Students/Launch/Interviews/STAR _(학부 코칭 콘텐츠)_
107
+ - **Bauer College (University of Houston) — STAR Behavioral Interview Technique** — 1인칭 개인 기여 강조, STAR 실무 적용 · https://careercenter.bauer.uh.edu/resources/star-behavioral-interview-technique/ _(학부 코칭 콘텐츠)_
108
+ - **AGENTS.md (CareerMate 프라임 디렉티브)** — 사실·수치·고유명사 보존, 과장·날조 금지 · 저장소 내부
109
+
110
+ ## 5. Phase B 힌트 (아키텍처로 연결)
111
+
112
+ - **MCP 도구 아이디어:**
113
+ - `get_behavioral_interview_kit({ job_id?, competency?, count? })` — `get_application_context`의 프로필·경력·스킬·대상 공고를 받아 (1) 저장된 스토리 뱅크에서 요청 역량/회사가치에 매핑되는 STAR 사례를 서빙, (2) 비어 있는 역량 카테고리·probing 누락·노후 사례를 `gap`으로 알려주고, (3) 본 루브릭(R1~R13, 등급 D/H 표기)을 함께 반환해 외부 AI가 자가검증하게 한다. read-only 지식 도구.
114
+ - `save_interview_prep({ job_id, stories[] })` — STAR를 **필드 분리(situation/task/action/result)** 로 강제 저장(자유 텍스트 금지 → S/T/A/R 경계 문제 해소, 루브릭 결정성 확보). `metrics[]`에 label·sourceRef를 강제해 R6/R13 가드를 데이터 구조 차원에서 건다.
115
+ - `lint_interview_kit(job_id?)` — R1~R13을 등급별로 실행. **D 항목은 pass/fail, H 항목(R3 적합·R7 적합·R13)은 `warn`/`needs_review`만 반환**(자동 합격 금지). `lang` 필드로 R4·R9 분기. 8단계 게이팅상 **면접 준비는 `document_passed` 이상에서만 해금.**
116
+ - **데이터 형태 힌트:**
117
+ ```
118
+ StoryBankEntry {
119
+ id, title,
120
+ lang: 'ko' | 'en', // R4·R9 언어 분기
121
+ competencies: string[], // 고정 enum만 (R7·R11)
122
+ companyValueTags?: string[], // 예: ['Amazon:Ownership'] — enum에 연결
123
+ star: { situation, task, action, result }, // 필드 분리 저장 (R1·R2)
124
+ metrics: [{ value:number, unit, label, sourceRef }], // label+sourceRef 필수 (R6·R13)
125
+ probing: { why, alternatives, whatIdChange }, // 3종 필수 (R8)
126
+ year: number, careerStage: 'student'|'intern'|'junior'|'senior', // R10
127
+ questionMappings: string[], // 이 사례가 매핑된 질문 유형 (R12 재탕 가드)
128
+ wordCounts: { s, t, a, r, total }, // R2·R9
129
+ sourceRefs: string[] // 프로필/경력 항목 id — fabrication 방지 원자료 링크
130
+ }
131
+ ```
132
+ 도구 응답에는 `entries[]`, `coverage: { distinctCompetencies, count, missingCategories, recentRatio }`, `rubric: RubricCheck[]`(각 항목에 `grade: 'D'|'H'`, `status: 'pass'|'fail'|'warn'|'needs_review'`)를 함께 포함해 외부 AI가 등급을 구분해 자가검증하도록 한다.
@@ -0,0 +1,126 @@
1
+ # 면접 — 기술/시스템 디자인 / Technical & System Design Interview — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ 기술/시스템 디자인 면접에서 평가자는 "정답 도달"이 아니라 **구조화된 사고 + 소통 + 트레이드오프 추론**을 본다. 이 플레이북은 연결된 AI가 (a) 후보의 직무·레벨·면접 포맷에 맞는 준비 자료를 만들고 (b) 그 자료를 자가검증하도록 트랙별 프레임·체크리스트·루브릭을 제공한다.
8
+
9
+ 핵심 제약 — **CareerMate에는 LLM이 없으므로 이 문서의 루브릭은 "내용의 정확성"이 아니라 "준비 자료에 기대 구조가 존재하는가"라는 형식만 LLM 없이 측정한다.** 따라서 루브릭 통과는 **합격 신호가 아니라 최소 형식 충족(format floor)** 이며, 추론의 옳고 그름·복잡도의 정확성·소통의 실제 품질은 **연결된 AI가 별도로 판정**해야 한다. 이 한계를 사용자에게 숨기지 마라.
10
+
11
+ ## 2. 플레이북
12
+
13
+ > **트랙 분리가 먼저다.** 기술 면접은 단일 포맷이 아니다. 최소 다섯 갈래로 나뉘고 평가 축이 서로 다르다: ① 온라인 코딩테스트(자동채점, 소통 0점) ② 라이브 코딩(소통 중심) ③ 백엔드 시스템 디자인 ④ FE/ML/데이터/모바일 시스템 디자인(축이 다름) ⑤ 디버깅/기존 코드 확장형. 아래 원칙은 트랙·세션 길이·레벨에 따라 **강도를 조절**해 적용한다(획일 적용 금지).
14
+
15
+ ### 원칙
16
+
17
+ - **(온라인 코딩테스트는 UMPIRE를 버린다)** — 백준/프로그래머스류 1차 자동채점은 정답률·시간초과·메모리만 본다. 소통·명확화·트레이드오프가 0점이므로, 여기서는 **문제 정확 이해 → 제약(N, 시간/메모리 한계)에서 목표 복잡도 역산 → 엣지(빈입력·오버플로·경계) 처리 → 제출 전 반례 자가생성**만 한다. _(출처: 한국 채용 현실 / 실무 관찰)_
18
+ - **(라이브 코딩은 세션 길이로 프레임 강도를 정한다)** — 30~45분 세션에서는 **라이트 UMPIRE**(명확화 1~2개 + 접근법 1문장 합의 + 구현 + 끝나고 dry-run 1회). 60~120분(한국 라이브 코딩·페어프로그래밍)에서는 **풀 UMPIRE**(명확화 다수 + 평균/엣지 케이스 손추적 + 의사코드). 형식에 시간을 과배분해 구현 미완으로 탈락하는 것이 명확화 누락보다 더 흔한 실패다. _(출처: Tech Interview Handbook; CodePath UMPIRE — 단, 세션별 조절은 본 플레이북의 보정)_
19
+ - **(코딩 전 명확화·접근법 합의)** — 잘못된 가정으로 바로 코딩하면 틀린 문제를 푼다. 명확화(입력 범위·형식, 중복/음수/빈입력 허용, 반환 형식)와 접근법 합의는 빅테크 라이브 코딩에서 일관된 hire 신호다. _(출처: Tech Interview Handbook — Coding Interview Rubrics)_
20
+ - **(코드 작성 후 Review + Evaluate를 입으로)** — 버그가 있다고 가정하고 변수 워치리스트로 한 줄씩 추적(해피패스 → 엣지), 그다음 시간·공간 복잡도를 Big-O로 명시하고 대안 트레이드오프를 한 문장 언급한다. Testing은 4대 평가 축 중 하나다. _(출처: CodePath UMPIRE — Review/Evaluate; Tech Interview Handbook — Testing 축)_
21
+ - **(시스템 디자인은 다이어그램이 아니라 요구사항부터)** — FR 3개 이상 + NFR(확장성/가용성/지연/일관성) + 규모 추정을 먼저 글머리표로 적고 합의한다. "명확화 없이 아키텍처부터"는 1순위 탈락 원인이다. _(출처: Exponent System Design Guide; GeeksforGeeks — Common Mistakes)_
22
+ - **(45분은 기본값이며 포맷별로 재배분한다)** — Google/Meta형 45분은 *기본 타임박스*일 뿐이다. Amazon은 60분+행동결합, 한국 라이브는 60~120분, 스타트업 페어는 2~3시간이다. **세션 길이를 먼저 확인**하고, 어떤 길이든 "상위 설계에 시간을 다 쓰고 심층을 못 들어가는 것"을 피한다(심층이 변별 구간). _(출처: Exponent — time allocation; 회사별 포맷은 본 플레이북 보정)_
23
+ - **(모든 기술 선택에 구조적 트레이드오프)** — "X를 쓰면 A를 얻고 B를 잃는다 + 대안 1개" 형식. "무조건 좋다"식 단정은 감점. 면접관이 "10x/100x로 늘리면?"이라 밀 때 **병목이 어디로 이동하는지**(DB → 캐시 → 큐 → 샤딩) 설명한다. 최근 면접은 비용(가능하면 달러)·장애복구·운영성숙도까지 본다. _(출처: Exponent; DesignGurus — Anti-Patterns; interviewing.io 계열 기준)_
24
+ - **(면접은 모놀로그가 아니라 대화)** — 막히면 침묵하지 말고 현재 가설·막힌 지점을 소리 내어 말하고 힌트를 활용한다. 침묵이 가장 큰 감점이다. _(출처: Tech Interview Handbook — Communication 축)_
25
+ - **(과설계 금지: 단순하게 시작해 점진 확장)** — 요구사항이 정당화하지 않는 MSA/Kafka/k8s를 넣지 않는다. 정당화 사슬이 끊기면 mid-level 신호. _(출처: DesignGurus — 7 Anti-Patterns)_
26
+ - **(레벨로 기대치가 다르다)** — 같은 문제라도 주니어(L3/L4)는 "동작하는 설계"·"명확화 1~2개", 시니어(L5)는 "트레이드오프·실패모드·비용", 스태프(L6+)는 "요구사항 자체를 협상/축소·조직/운영 경계 설계"가 변별점이다. 준비 자료는 후보 레벨에 맞춰 기대치를 적는다. _(출처: DesignGurus — Google SD Rubric 차원; 레벨 차등은 본 플레이북 보정)_
27
+
28
+ ### Do
29
+
30
+ - 코딩(라이브): 입력 형식·범위·중복/음수/빈입력·반환 형식 중 **세션 길이에 맞는 수**의 명확화 질문을 한다(짧으면 1~2개, 길면 더).
31
+ - 코딩(라이브): 평균 케이스 1개 + 엣지(빈입력/단일원소/최대 크기) 1개 이상을 **구체 값**으로 적고 손으로 추적한다.
32
+ - 코딩: 접근법을 의사코드/말로 설명하고 시간·공간 복잡도를 **미리** 말한 뒤 동의를 받고 코딩한다.
33
+ - 코딩(자동채점): 제출 전 N 제약에서 목표 복잡도를 역산하고, 오버플로·경계·빈입력 반례를 스스로 만들어 통과시킨다.
34
+ - 시스템: FR 3개+ / NFR(확장성·가용성·지연·일관성) / 규모(DAU·QPS·저장량)를 **설계 다이어그램보다 앞에** 글머리표로 합의한다.
35
+ - 시스템: API 시그니처와 데이터 모델(엔티티·주요 필드·인덱스/샤드 키)을 상위 설계 전에 정의한다.
36
+ - 시스템: **세션 길이를 먼저 확인**하고 단계별 분 배분을 명시하며, 합이 세션 길이에 맞고 심층 구간이 가장 크게 남도록 한다.
37
+ - 시스템: 각 컴포넌트 선택에 "얻는 것 vs 잃는 것 + 대안 1개" 트레이드오프 문장을 붙인다.
38
+ - 공통: 막히면 침묵하지 말고 현재 가설·막힌 지점을 소리 내어 말하고 힌트를 활용한다.
39
+ - 공통(가상 면접): CoderPad/공유에디터에서 화면공유 중 think-aloud를 유지하고, 시간이 부족하면 "여기까지 동작하고, 남은 부분은 이렇게 마무리할 계획"이라고 **우아하게 마무리**한다. AI 보조 도구가 허용되면 "왜 이 코드인지"를 직접 설명할 수 있어야 한다.
40
+ - 한국 맥락: CS 구술(자료구조·네트워크·OS·DB 인덱스/트랜잭션) 예상 질문과 답을 한국어로 준비한다. 경력직은 시스템 설계 대신 **트러블슈팅 경험 구술**이 나올 수 있으니 STAR로 정리한다.
41
+
42
+ ### Don't
43
+
44
+ - 명확화 없이 곧바로 코딩하거나 다이어그램부터 그리지 않는다(가장 흔한 탈락 원인).
45
+ - 반대로, **짧은 세션에서 형식(명확화·손추적)에 시간을 과배분**해 구현 미완으로 끝내지 않는다.
46
+ - 접근법 설명 없이 정답 코드만 빠르게 타이핑하지 않는다.
47
+ - 복잡도 분석(Big-O)을 생략하거나 면접관이 물을 때까지 미루지 않는다.
48
+ - 테스트/dry-run 없이 "됐습니다"라고 선언하지 않는다.
49
+ - 시스템: 규모 추정 없이 SQL/NoSQL·캐시·큐를 선택하지 않는다.
50
+ - 시스템: 상위 설계에 시간을 다 써서 심층·트레이드오프 시간을 날리지 않는다.
51
+ - 시스템: 요구사항이 정당화하지 않는 MSA·Kafka·k8s로 과설계하지 않는다.
52
+ - 공통: 막혔을 때 오래 침묵하거나 혼자 머릿속으로만 풀지 않는다.
53
+ - 트레이드오프를 "무조건 좋다"식 단정으로 말하지 않는다(모든 선택에는 비용이 있다).
54
+
55
+ ### 워크드 예시 (Before → After)
56
+
57
+ 1. **Before:** 문제 "정렬된 배열에서 두 수의 합이 target이 되는 인덱스를 찾아라." 후보가 바로 "for 이중 루프로 모든 쌍 확인" O(n²) 코드를 타이핑.
58
+ **After (45분 라이브, 라이트 UMPIRE):** "명확화 먼저요 — 오름차순 맞나요? 정답이 항상 존재하나요? 중복 값 있나요?" (답 듣고) "정렬돼 있으니 투 포인터로 양 끝에서 좁히면 시간 O(n), 공간 O(1)입니다. 예: [2,7,11,15], target=9 → left=0,right=3 합 18>9 → right--… 이 접근으로 코딩할게요." (동의 후 구현, 끝나면 빈 배열·단일 원소 엣지 dry-run + Big-O 재확인.)
59
+ **왜 더 나은가:** Before는 명확화·접근설명·복잡도·테스트를 모두 놓치고 'sorted' 단서를 버려 차선 알고리즘을 택한다. After는 단서를 활용한 최적해와 강한 소통 신호를 짧은 세션 안에 동시에 보여준다.
60
+
61
+ 2. **Before:** "URL 단축기를 설계하세요." 후보가 즉시 "LB → 웹서버 → MySQL → 캐시"를 그리고 "이렇게 하면 됩니다." 규모·읽기쓰기 비율·키 길이 언급 없음.
62
+ **After:** "요구사항부터요. 기능: 긴 URL→짧은 코드, 코드→리다이렉트, (선택)만료/커스텀 별칭. 비기능: 리다이렉트 p99 <100ms(캐시 히트 가정), 고가용성, 읽기:쓰기 ≈ 100:1. 규모: 쓰기 100M/월 ≈ **39 writes/s**, 읽기 ≈ **3,860 reads/s**, 5년 누적 ≈ **6B개**. 키 공간: base62 **6자 = 56.8B** 로 6B를 충분히 덮으므로 6자로 시작(여유 보려면 7자=3.5조). API: POST /shorten, GET /{code}. 데이터모델: code(PK)→long_url, 샤드키=code 해시. 읽기가 압도적이라 앞단에 캐시를 두고, 캐시 미스 시 DB. 트레이드오프: 카운터 기반 ID는 순차적이라 예측 가능 **대신** 조정 필요 ↔ 해시는 충돌 처리 필요."
63
+ **왜 더 나은가:** Before는 1순위 안티패턴(명확화 없이 다이어그램). After는 요구사항→추정→API→데이터모델→트레이드오프 순으로 진행하고 **숫자가 재검산되어 정확**하며(39/3,860/6B/56.8B), "읽기쓰기 비율"이 캐시 결정으로 이어지고 키 길이를 공간 계산으로 정당화한다. (이전 초안의 '4000 reads/s'·'7자가 빠듯한 듯'한 서술을 수정함.)
64
+
65
+ 3. **Before:** 심층 "쓰기가 10배로 늘면요?" 후보: "서버를 늘리면 됩니다."
66
+ **After:** "쓰기 ≈ 390/s가 되면 병목은 단일 DB의 쓰기 처리량입니다. 순서대로 (1) code 해시 기준 수평 샤딩으로 쓰기 분산, (2) ID 충돌 회피를 위해 사전할당된 키 범위를 각 앱서버에 배분, (3) 강한 순서 보장이 필요 없는 분석 로그는 비동기 큐로 분리. 트레이드오프: 샤딩하면 쓰기는 확장되지만 범위 쿼리·재샤딩 운영 비용이 늘고, 큐는 처리량을 늘리되 최종 일관성·운영 복잡도를 더합니다."
67
+ **왜 더 나은가:** Before는 병목이 'DB 쓰기'임을 못 짚는다. After는 "10x 밀기"에서 평가자가 보려는 병목 식별 → 구체 전략 → 각 전략의 트레이드오프·운영 비용을 정확히 제공한다.
68
+
69
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
70
+
71
+ > **이 루브릭은 "형식 floor 검사(format lint)"다 — 합격 점수가 아니다.** 모든 검사는 키워드·개수·정규식·위치 비교로 LLM 없이 측정하므로 **구조의 존재만** 본다(예: 'O(n)'이 *맞는지*는 못 본다, 'vs'가 든 문장이 *공허한지*는 못 본다). 따라서 self_check 결과는 `passedCount/totalCount`가 아니라 **"형식 최소 요건 충족/미충족"** 으로 라벨링하고, "정확성·추론 품질은 연결된 AI가 별도 판정"이라는 경고를 반드시 함께 반환한다. 아래 임계값(≥2, ≥3 등)은 **휴리스틱 컷이며 회사/레벨/문제 난이도에 따라 조정 대상**이다(절대선 아님). R10~R11은 안티패턴을 **역검출**하는 negative-check다.
72
+
73
+ | ID | 검사 항목 | 합격 기준 (형식 floor) | 측정 방법(LLM 없이 셀 수 있게) |
74
+ |----|-----------|-----------|--------------------------------|
75
+ | R1 | 명확화 질문 존재 | 명확화 질문 ≥ 2개 (라이브 트랙 한정; 자동채점 트랙은 면제). 휴리스틱 컷 — junior 문제는 1개로 충분할 수 있음 | '?'로 끝나는 질문 문장 수 ≥ 2 **그리고** '명확화/Clarify' 섹션 헤더 존재. 트랙이 `online_coding_test`면 본 검사 skip |
76
+ | R2 | 테스트 케이스 구체성 | 구체 입력값 케이스 ≥ 2개, 그중 엣지 ≥ 1개 | '입력→출력' 형태 예시 수 ≥ 2 **그리고** 엣지 키워드('빈'/'empty'/'단일'/'[]'/'null'/'경계'/'오버플로') ≥ 1개 케이스에 매칭 |
77
+ | R3 | 복잡도 명시 (정확성 아님) | 시간·공간 각각 O(...) 표기 ≥ 1개 | 정규식 `O\([^)]+\)` 매칭 ≥ 2 **그리고** '시간/time'·'공간/space' 두 키워드 모두 등장. ※ **표기의 정확성은 미측정** — 경고 플래그 함께 반환 |
78
+ | R4 | 요구사항 우선 배치 | FR ≥ 3 글머리표 + NFR 키워드 ≥ 2, 그리고 요구사항 섹션이 아키텍처 섹션보다 **앞에** 위치 | '요구사항/requirements' 섹션 글머리표 수 ≥ 3; NFR 키워드(확장성·가용성·지연·일관성/scalability·availability·latency·consistency) ≥ 2; 문서 내 요구사항 섹션 시작 오프셋 < 아키텍처/설계 섹션 시작 오프셋 |
79
+ | R5 | 규모 추정(숫자+단위) | DAU/QPS/저장량 중 ≥ 2종에 구체 숫자+단위 | **단위가 붙은** 숫자만 카운트: 정규식 `\d+\s*(M\|K\|B\|GB\|TB\|/s\|QPS\|DAU)` **또는** 한글 수사 `(천만\|백만\|억\|만)\s*(명\|건\|개)?` / `초당\s*\d+` 매칭 ≥ 2. **단위 없는 숫자·`base62 7자`·`O(1)`·`HTTP 2` 류는 제외**(앞뒤 토큰으로 단위 검증). '추정/estimation' 섹션 헤더 동시 존재 요구 |
80
+ | R6 | 구조적 트레이드오프 | "얻고/잃는" 구조 트레이드오프 문장 ≥ 3개 + 대안 ≥ 1 | **좁힌 패턴만**: 한 문장에 (트레이드오프 신호 '대신'/'트레이드오프'/'↔'/'tradeoff' **또는** '얻'+'잃'/'gain'+'lose') **그리고** 기술명/명사 2개 이상 동시 출현 ≥ 3. ※ 일반 '하지만/반면'만으로는 카운트 안 함(위양성 차단) |
81
+ | R7 | 타임박싱이 심층을 보호 + 합이 세션 길이에 맞음 | 분 배분 단계 ≥ 4개; 분 합이 (세션 길이 ±10%) 범위; 심층 단계 분 ≥ 상위설계 단계 분 | '분/min' 숫자 붙은 단계 수 ≥ 4; **모든 단계 분의 합이 [세션×0.9, 세션×1.0] 범위에 드는지 합산 검증**(기본 세션=45, 입력으로 60/90/120 등 지정 가능); '심층/deep dive' 분 ≥ '상위/high-level' 분 |
82
+ | R8 | 소통/막힘 대응 가이드 존재 (자료 완비성, 후보 역량 아님) | 막힘 대응 항목 ≥ 1 | '막히면/소리 내어/think aloud/힌트/대화' 키워드 ≥ 1. ※ 이는 **준비 자료에 문장이 들어갔는지**일 뿐 실제 소통 능력이 아님 — 경고 플래그 함께 반환 |
83
+ | R9 | 과설계 경고 존재 | '단순하게 시작'/'요구사항 정당화' 취지 ≥ 1 | '과설계/over-engineer/단순하게 시작/점진/정당화' 키워드 ≥ 1 |
84
+ | R10 | **(negative)** 트레이드오프 단정 안티패턴 미검출 | "무조건/항상 좋다/best/언제나 우월" 식 단정 문장 = 0 | '무조건'/'항상 좋'/'언제나'/'always better'/'best choice' 패턴 매칭 = 0 이면 통과(존재하면 **실패 플래그**) |
85
+ | R11 | **(negative)** "명확화 없이 코드/다이어그램" 흔적 미검출 | 문서 첫 섹션이 코드블록/다이어그램이 아니라 요구사항·명확화 | 첫 비공백 콘텐츠 블록이 코드펜스(```)/아키텍처 키워드가 아니라 '요구사항'/'명확화' 섹션인지 위치 검사. 아니면 **실패 플래그** |
86
+
87
+ **주요 실패 모드 (게이밍·위양성 정직 고지):**
88
+ - **게이밍**: 의미 없는 명확화 질문 2개, 틀린 'O(n)' 2개, '대신'이 든 공허한 문장 3개만 붙여도 R1·R3·R6은 PASS한다. 루브릭은 **구조의 존재**만 보장하지 **질·정확성을 0% 보장하지 않는다.** self_check가 '전부 PASS'여도 연결된 AI는 (a) 복잡도가 실제로 맞는지 (b) 트레이드오프가 공허하지 않은지 (c) 추정 숫자가 재검산되는지를 **반드시 별도 검토**해야 한다.
89
+ - **proxy 한계**: 이 형식 충족도는 실제 면접 통과율과 상관관계가 **입증되지 않은 대리지표**다. "self_check 통과 = 합격"으로 사용자에게 제시하면 가짜 자신감을 준다.
90
+ - **위양성 예시(자료에 박제 금지)**: "캐시는 빠르지만 좋다 vs 나쁘다"(R6 통과하나 공허), "O(n)으로 정렬"(R3 통과하나 정렬은 O(n log n)) — 이런 건 연결된 AI가 잡아야 한다.
91
+
92
+ ## 4. 출처 (Provenance)
93
+
94
+ - **Tech Interview Handbook — Coding Interview Rubrics** — 코딩 라이브 면접 4대 평가 축(Communication/Problem-solving/Technical competency/Testing)과 '코딩 전 명확화·접근법 설명'이 hire 신호라는 근거 · https://www.techinterviewhandbook.org/coding-interview-rubrics/
95
+ - **Tech Interview Handbook — Coding Interview Cheatsheet** — before/during/after 체크리스트(green light 후 코딩, 코딩하며 설명, 의미있는 변수명·함수 추출) · https://www.techinterviewhandbook.org/coding-interview-cheatsheet/
96
+ - **CodePath — UMPIRE Interview Strategy** — UMPIRE 6단계 구체 행동(Understand/Plan/Review/Evaluate). **단, UMPIRE는 CodePath의 교육용 니모닉이지 Google/Meta 공식 채점 루브릭이 아니다 — 빅테크는 'UMPIRE 준수'가 아니라 코드 정확성·테스트 통과·복잡도를 hidden rubric으로 채점한다.** · https://guides.codepath.org/compsci/UMPIRE-Interview-Strategy
97
+ - **DesignGurus — System Design Rubric 차원 / 7 Anti-Patterns** — 평가 차원(요구사항·아키텍처·기술깊이·트레이드오프), 과설계 등 안티패턴. **2차(블로그) 출처이며 실제 회사 1차 루브릭이 아님에 주의.** · https://www.designgurus.io/blog/
98
+ - **Exponent — System Design Interview Guide** — 45분 단계별 시간 배분의 *기본값*, 10x/100x 밀어붙이기, 심층에서 차별화. **회사별 세션 길이(Amazon 60분·한국 60~120분·스타트업 2~3h)와 레벨 차등은 본 플레이북의 보정이며 이 단일 소스에 과의존하지 말 것.** · https://www.tryexponent.com/blog/system-design-interview-guide
99
+ - **GeeksforGeeks / SystemDesignHandbook — Common Mistakes** — 핵심 안티패턴(명확화 없이 다이어그램, 모놀로그, 한꺼번에 다루기). 2차 출처 · https://www.geeksforgeeks.org/system-design/common-mistakes-to-avoid-in-a-system-design-interview/
100
+ - **본 플레이북 보정(1차 자료 없음, 실무 관찰 기반)** — 온라인 코딩테스트 vs 라이브 코딩 분리, 세션 길이별 프레임 강도(라이트/풀 UMPIRE), 레벨(L3~L6+) 차등 기대치, FE/ML/데이터/모바일·디버깅 트랙 존재, AI 보조도구 정책, 한국 채용 루프(자동채점 1차 → 라이브 2차, 경력직 트러블슈팅 구술). 이 항목들은 위 2차 출처가 직접 뒷받침하지 않으므로 회사/연도별로 재확인 대상이다.
101
+
102
+ ## 5. Phase B 힌트 (아키텍처로 연결)
103
+
104
+ - **MCP 도구 아이디어:**
105
+ - `get_interview_prep_playbook({ track, role?, company?, level?, session_minutes?, locale? })` — `track`은 `online_coding_test | live_coding | system_design_backend | system_design_frontend | system_design_ml | debugging | behavioral` 로 확장. 트랙별 (a) 프레임(자동채점 체크 / 라이트·풀 UMPIRE / SD 타임박스), (b) do/dont, (c) 막힘·시간초과 마무리 스크립트, (d) 형식 루브릭을 반환. `level`로 passBar 분기, `session_minutes`로 R7 합산 기준 설정, `locale:'ko'`면 CS 구술 세트 + 한국어 스크립트 + 경력직 트러블슈팅 STAR 템플릿 포함.
106
+ - `self_format_lint_interview_prep({ artifact_text, track, session_minutes?, level? })` — **이름을 `self_check`에서 `self_format_lint`로 변경**(정직성). LLM 없이 R1~R11 패턴/개수/위치/negative만 측정. 반환에 **경고 플래그 강제 포함**: 형식 충족 여부일 뿐 합격·정확성 보장 아님.
107
+ - `generate_mock_questions({ track, topic })` — `get_application_context`에 **기술 스택 필드가 실제 있는지 먼저 검증**하고, 없으면 role/company로 폴백. 컨텍스트 기반 예상 질문 세트 serve.
108
+ - `save_interview_prep` — 기존 8단계 게이팅(**document_passed 이상에서만 해금**)을 그대로 존중. 단 **track/framework/rubric_result 필드 추가가 필요하면 스키마 확장 + 기존 데이터 마이그레이션 영향(현 스키마는 questions/star_guides/self_introduction/notes만 받음)을 Phase B에서 명시 설계**할 것.
109
+ - **데이터 형태 힌트:**
110
+ ```
111
+ playbook = {
112
+ track, level, session_minutes,
113
+ framework: { steps: [{ name, minutes, actions: [...] }], total_minutes, frame_intensity: 'light'|'full'|'autograder' },
114
+ doList: [...], dontList: [...],
115
+ communication_scripts: [{ situation: '막힘'|'시간초과', say: '...' }],
116
+ rubric: [{ id, check, passBar, measure: { type: 'count'|'exists'|'ratio'|'regex'|'order'|'sum_in_range'|'negative', pattern, threshold, session_aware? } }],
117
+ disclaimer: '루브릭은 형식 floor — 정확성·추론 품질은 연결된 AI가 판정'
118
+ }
119
+ self_format_lint 반환 = {
120
+ track,
121
+ checks: [{ id, passed: bool, observed: number, required: number, kind: 'positive'|'negative', accuracy_unverified: bool }],
122
+ format_floor_met: bool, // passedCount/totalCount 대신 — '점수' 오독 방지
123
+ warning: 'PASS는 형식 충족일 뿐 정답·합격 보장 아님'
124
+ }
125
+ ```
126
+ rubric의 measure는 정규식/키워드/개수/위치/합산/역검출 기반이라 외부 AI 없이 CareerMate가 산출물 텍스트에 직접 적용 가능. `session_aware`·`level` 분기로 R7 합산 기준과 R1 임계값을 조정한다.
@@ -0,0 +1,152 @@
1
+ # LinkedIn 프로필 / LinkedIn Profile — CareerMate 지식 (Phase A)
2
+
3
+ > 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
4
+
5
+ ## 1. 무엇을 하는가
6
+
7
+ LinkedIn 프로필을 **(1) 리크루터 검색에 노출되고(키워드·완성도), (2) 5~10초 스캔에서 클릭을 유발하며(헤드라인·About 첫 문장), (3) 신뢰를 증명하는(추천서·정량 성과·Featured)** 세 축으로 최적화하기 위한 플레이북과, **LLM 없이 셀 수 있는 자가검증 루브릭**이다. CareerMate에는 LLM이 없으므로, 연결된 외부 AI(Claude/GPT/Gemini)가 이 규칙으로 프로필 초안을 작성·진단하고, `validate_linkedin_profile`이 루브릭을 기계적으로(개수·존재·비율·정규식) 실행한다.
8
+
9
+ **책임 경계(매우 중요):** 키워드 기반 검사는 모두 **타깃 키워드 사전**을 전제한다. 이 사전(동의어·한영 매핑·약어 확장 포함)을 만드는 일은 **의미 판단이라 외부 AI의 몫**이다 — AI가 `get_application_context`(타깃 공고 JD)로 사전을 채워 넘기면, validate는 그 사전을 받아 **기계적 부분문자열 매칭**만 한다. 사전이 비었거나 부실하면 키워드 체크는 `INSUFFICIENT_INPUT`을 반환하고 통과/실패를 판정하지 않는다. 즉 "LLM 없이 측정"은 *사전이 주어진 뒤*의 매칭에 한정된다.
10
+
11
+ ## 2. 플레이북
12
+
13
+ ### 원칙
14
+
15
+ - **헤드라인 하드 상한은 220자다. '핵심 키워드·가치제안을 앞 120자 안에 front-load'는 *권장*이지 상한이 아니다.** — LinkedIn은 2020년부터 헤드라인 220자를 허용한다. 모바일·검색 미리보기는 앞부분을 잘라 보여주므로 가장 중요한 직무 키워드와 1개 가치제안을 앞쪽에 둔다. 120을 한도처럼 강제하면 220자까지의 키워드 공간 절반을 버린다. _(출처: LinkedIn 헤드라인 사양(220자) — 권장 임계와 하드 상한을 분리)_
16
+ - **헤드라인은 '직무 타이틀 + 핵심 스택/전문성 + 정량 결과 또는 도메인'을 담고, 가장 중요한 키워드를 맨 앞에 둔다. 단, 검색용 키워드와 *사람이 읽는 가치제안*을 모두 만족시키되 구분자(`|`·`·`) 남발로 가독성을 죽이지 않는다.** — 헤드라인은 검색·연결요청·댓글 등 모든 노출 지점에 따라붙고 키워드 가중치가 가장 크다. 그러나 키워드 떡칠은 검색엔 잡혀도 클릭을 잃는다. 구분자 3~4개 이내로 묶고 사람이 읽는 1개 핵심 메시지를 보장한다. _(출처: LinkedIn 공식 키워드 가이드 · 리크루터 검색의 키워드 관련성 신호[업계 SEO 분석, 추정])_
17
+ - **About 첫 2~3문장에 타깃 직무 키워드 + 정량 성과 1개 이상을 넣고, 1인칭 내러티브로 쓴다.** — About은 '더 보기' 펼침 전 앞부분만 기본 노출되며 검색 키워드 스캔 대상이다. *About은 서사형(narrative)이 잘 먹히는 매체*이므로 이력서식 불릿 규칙(XYZ 70%)을 그대로 이식하지 않는다 — 톤 우선, 키워드·수치는 자연스럽게. _(출처: LinkedIn 공식 키워드 가이드 · LinkedIn 프로필 최적화 가이드[블로그, 2차])_
18
+ - **Experience 불릿은 Google XYZ('무엇을 X / 얼마만큼 Y / 어떻게 Z')로 쓴다 — 단, 정량이 본질적으로 어려운 직군(디자인·PM 초기·연구·법무·공공·신입)은 *규모/범위*(사용자 수·팀 규모·처리량)로 대체하고, 그래도 불가하면 결과 동사 + 범위 서술로 충족한다.** — XYZ는 '담당했다'식 책임 나열 대신 측정 가능한 임팩트를 강제한다. 그러나 단일 '수치 70%' 바는 절반의 직군에 비현실적이므로 fallback을 둔다. _(출처: Bill Murphy Jr.(Inc.com)가 정리한 Google 리크루터 XYZ 공식 — Laszlo Bock 'Work Rules!'에 영감을 둔 2차 해석본; UT Austin Law 배포 PDF는 그 Inc 기사 재배포)_
19
+ - **프로필 강도를 위해 핵심 섹션을 폭넓게 채운다: 사진·위치·산업·학력·현재 직책·스킬·About(요약), 그리고 Featured(포트폴리오·글·링크).** — LinkedIn Help는 이 섹션 완성이 발견성·검색 노출을 높인다고 본다. 다만 LinkedIn은 2022년경부터 'All-Star/profile strength meter'를 공개 UI에서 상당히 약화·제거했으므로 "공식 7개 배지"로 단정하지 않는다 — *대략 이 섹션들을 채우면 강함* 수준으로 본다. Featured는 클릭·신뢰에 크다. _(출처: LinkedIn 공식 Help: Your Profile level meter(a594698) — 현행 UI 변동 가능성 라벨링)_
20
+ - **스킬은 타깃 직무 핵심 하드스킬로 채우고(최소 5개), 핵심 스킬을 상단 고정(pin)하며, 가능하면 각 스킬을 Experience/Education 항목에 *연결(skill associations)* 한다. 무관 스킬로 상한(50)까지 채우지 않는다 — 관련성 신호가 희석된다.** — 2026년 LinkedIn은 단순 나열보다 스킬-경력 연결을 검색·신뢰에 반영한다. 헤드라인·About·Experience의 키워드와 스킬을 일치시켜 관련성 신호를 중복 강화한다. _(출처: LinkedIn 공식 키워드 가이드 · 스킬 연결 기능[2026 현행])_
21
+ - **사회적 증거는 추천서(Recommendations) 중심이다. 다른 관계(상사/동료/고객)에서 1~2개 이상 받는다. 엔도스먼트는 *보조 신호*로 격하한다 — 가중치가 크게 줄었고 품앗이가 가능해 리크루터 다수가 거의 무시한다.** — 추천서는 자기서술을 제3자가 검증하는 신뢰 레이어이고 별도 섹션으로 노출된다. skill assessment 배지도 엔도스먼트보다 강하다. _(출처: 리크루터 대상 LinkedIn 최적화 가이드[블로그, 2025–2026, 2차] — 엔도스먼트 가중치 재조정 반영)_
22
+ - **네트워크와 활동성도 노출을 좌우한다(통제 가능한 부분만): 연결 200+/500+ 확보, 타깃 업계 종사자와 연결, 주기적 활동(주 1회 글/댓글).** — LinkedIn Recruiter 검색에서 네트워크 거리(1/2/3촌)·활동성은 키워드 매칭만큼, 종종 그 이상으로 노출을 좌우한다. 키워드만 완벽해도 네트워크가 빈약하면 검색 하단이다. *네트워크 '거리' 자체는 후보가 통제 불가(검증 제외)*, 연결 수·활동 존재는 통제 가능(검증 포함). _(출처: 리크루터 검색 신호 분석[업계 SEO, 추정] — '추정된 알고리즘'이며 LinkedIn 공식 확정 사실 아님)_
23
+ - **신선도(freshness)를 유지한다: 직책·About·스킬을 주기적으로 갱신하고, 채용 시즌엔 'Open to Work'를 켠다.** — 검색 알고리즘은 최근 갱신 정도를 신호에 포함한다(추정). 정체된 프로필은 강도가 높아도 내부 랭킹을 잃는다. _(출처: 리크루터 검색 신호 분석[추정] · LinkedIn SEO 분석[블로그])_
24
+ - **한국 사용자는 핵심 필드를 국문/영문 병기하거나 다국어 프로필을 쓰되, 글로벌·외국계 타깃이면 영문을 1차로 둔다. 회사명·고유명사·수치는 원문 그대로 보존한다.** — 외국계·헤드헌팅·스타트업은 영문 LinkedIn 검색을 쓴다. 병기는 양쪽 검색에 잡히게 하고, 고유명사·수치 보존은 할루시네이션을 막는다. *병기 시 글자수·키워드가 두 배로 잡히므로 density 상한 적용은 단일 언어 기준으로 분리한다.* _(출처: AGENTS.md 사실·수치·고유명사 보존 원칙 · LinkedIn 다국어 프로필 기능)_
25
+
26
+ ### Do
27
+
28
+ - 헤드라인: 타깃 직무 + 핵심 스택/전문성 + 정량 결과/도메인을 앞 120자에 front-load(하드 상한 220자), 구분자 3~4개 이내.
29
+ - About 첫 2~3문장에 타깃 직무 키워드 + 정량 성과 1개 이상, 1인칭 서사로.
30
+ - About 전체에 직무 관련 키워드를 자연스럽게 분산(과밀·반복 금지).
31
+ - Experience 불릿을 XYZ로; 정량이 어려우면 규모/범위로 대체.
32
+ - 핵심 섹션(사진·위치·산업·학력·직책·스킬·About) + Featured 채우기.
33
+ - 스킬 ≥5개, 핵심 스킬 상단 고정 + Experience/Education에 연결, 키워드 일치.
34
+ - 추천서 1~2개를 *다른 관계*에서 확보(엔도스먼트는 보조).
35
+ - 연결 200+ 확보 + 주기적 활동(주 1회), 채용 시즌 Open to Work 활성화.
36
+ - 직책·About·스킬 주기적 갱신(신선도).
37
+ - 국문/영문 병기 또는 다국어 프로필; 회사명·날짜·수치·고유명사 원문 보존.
38
+
39
+ ### Don't
40
+
41
+ - 'Experienced Professional', '열정적인 OO', '문제 해결사', 'results-driven' 같은 추상어만으로 헤드라인 채우기.
42
+ - 헤드라인을 '직책 @ 회사명'만으로 채워 키워드/결과 누락.
43
+ - 키워드 떡칠(같은 키워드 반복 나열, 구분자 범벅)로 검색·가독성 모두 손해.
44
+ - Experience를 '담당/책임/수행/진행/관리/지원/대응/처리/운영'(영문: Responsible for/Worked on/Helped/Assisted/Involved in)식 책임 나열로만 쓰고 수치/규모 누락.
45
+ - About을 3인칭 보도자료체·버즈워드(synergy, results-driven)·인사말/잡담으로 낭비.
46
+ - 무관 스킬을 상한까지 채워 관련성 희석; 스킬을 5개 미만 방치.
47
+ - 엔도스먼트를 추천서와 동급으로 과대평가.
48
+ - 검증되지 않은 수치·직함·성과 지어내기(사실 왜곡).
49
+ - 프로필을 한 번 만들고 수개월 방치(신선도 하락).
50
+ - Featured·다국어 병기를 빼서 클릭·국제 노출 기회를 버리기.
51
+
52
+ ### 워크드 예시 (Before → After)
53
+
54
+ 1. **Before:** 헤드라인 — `개발자 @ ABC테크 | 열정적인 문제 해결사`
55
+ **After:** 헤드라인 — `Backend Engineer · Java/Spring·MSA | 주문 트래픽 5배 처리 결제 시스템 구축 @ ABC테크`
56
+ **왜 더 나은가:** 타깃 직무(Backend Engineer)와 검색되는 하드스킬(Java/Spring·MSA)을 맨 앞에 front-load해 키워드 검색에 잡히고, '주문 트래픽 5배 처리'라는 정량 결과로 클릭을 유발한다. '열정적인 문제 해결사' 같은 검색 불가 추상어를 제거했고, 구분자는 3개로 가독성을 지켰다.
57
+
58
+ 2. **Before:** Experience 불릿 — `백엔드 API 개발 및 운영 담당, 성능 개선 작업 수행`
59
+ **After:** Experience 불릿 — `p99 응답시간을 1,200ms→180ms로 85% 단축(X·Y) — N+1 쿼리 제거와 Redis 캐시 레이어 도입으로(Z), 동시접속 3만 트래픽 안정화`
60
+ **왜 더 나은가:** XYZ(무엇을/얼마만큼/어떻게)로 '담당·수행'식 책임 나열을 측정 가능한 임팩트로 바꿨다. 구체 수치(85%, 3만)와 방법(N+1, Redis)이 신뢰와 검색 키워드(Redis)를 동시에 준다.
61
+
62
+ 3. **Before:** About 첫 문장 — `안녕하세요, 저는 다양한 경험을 가진 마케터입니다. 항상 새로운 것을 배우는 것을 좋아합니다.`
63
+ **After:** About 첫 문장 — `B2B SaaS 퍼포먼스 마케터 · 6년. 유료 전환율을 2.1%→4.8%로 끌어올린 풀퍼널 그로스 실험가입니다. 핵심: 퍼포먼스 광고(Google/Meta Ads), SEO, 마케팅 자동화(HubSpot).`
64
+ **왜 더 나은가:** 노출 앞영역에 타깃 키워드(B2B SaaS, 퍼포먼스 마케터, SEO, HubSpot)와 정량 성과(전환율 2.1%→4.8%)를 모두 넣고, 인사말·잡담을 제거해 핵심을 상단으로 끌어올렸다. About은 서사형이라 불릿이 아닌 1인칭 문장으로 유지했다.
65
+
66
+ ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
67
+
68
+ > **공통 가드:** 키워드 의존 체크(R2, R4, R5, R6, R10, R15)는 외부 AI가 `get_application_context`로 채운 `target_keywords[]`를 입력으로 받는다. 사전이 비었거나 N개(예: 5) 미만이면 해당 체크는 pass/fail 대신 **`INSUFFICIENT_INPUT`** 을 반환한다. 길이·존재·정규식 체크(R1, R7, R8, R11, R12, R13, R14)는 사전 없이 진짜로 기계 측정 가능하다.
69
+ > **정량 정규식(quantRegex):** `\d+([.,]\d+)?\s*(%|배|원|명|ms|x|k|만|억|점|개|위|명|시간|일|주|개월|년)`
70
+
71
+ | ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) |
72
+ |----|-----------|-----------|--------------------------------|
73
+ | R1 | 헤드라인 하드 상한 + front-load 권장 | 길이 ≤ 220자(hard fail) **및** 앞 120자 내 타깃 키워드 ≥1(soft warn) | 헤드라인 길이 ≤220 → fail/pass; `헤드라인[0:120]`에 사전 키워드 매칭 = 0이면 warn(fail 아님) |
74
+ | R2 | 헤드라인 키워드 front-load | 사전 키워드가 앞 120자 내 ≥1 | `헤드라인[0:120]` ∩ target_keywords 매칭 ≥1 (사전 없으면 INSUFFICIENT_INPUT) |
75
+ | R3 | 헤드라인이 추상어만이 아님 | 금지어 제거 후 잔여 토큰 ≥3 | 금지어 사전(Experienced Professional/열정적인/문제 해결사/results-driven/synergy…) 제거 후 토큰 수 ≥3 |
76
+ | R3b | 헤드라인 구분자 남발 방지 | 구분자(`|`·`·`/`,`) 합 ≤4(soft) | 구분자 문자 카운트 ≤4 |
77
+ | R4 | About 앞부분 키워드 | 첫 2~3문장(언어별 분기) 내 사전 키워드 ≥1 | 문장 경계로 분할 후 앞 2~3문장 ∩ target_keywords ≥1. *char 절대 임계 대신 문장 단위*(한/영 글자수 차 보정) |
78
+ | R5 | About 키워드 커버리지 | 고유 사전 키워드 ≥ N(권장 하한, soft) | About ∩ target_keywords의 *고유* 매칭 수 ≥ 하한. 상한(8~12)은 **soft warn**으로만(근거가 블로그라 hard fail 금지; 병기 시 단일 언어 기준으로 카운트) |
79
+ | R6 | JD 커버리지(핵심 신규 항목) | (공고 JD 키워드 ∩ 프로필 키워드) / JD 키워드 ≥ 0.4 | get_application_context의 JD 키워드 집합과 프로필 전체 텍스트 매칭 비율 ≥0.4 (사전 없으면 INSUFFICIENT_INPUT) |
80
+ | R7 | 키워드 스터핑 방지 | 동일 키워드 반복 ≤3회 | 각 사전 키워드 등장 횟수 카운트, 최대 반복 ≤3 |
81
+ | R8 | About 앞부분 정량 성과 | 앞 2~3문장에 quantRegex ≥1 | 앞 2~3문장에 정량 정규식 매칭 ≥1 |
82
+ | R9 | Experience 정량/범위 비율 | 수치 또는 규모 표현 포함 불릿 ≥ 60%(직군 fallback 허용) | 각 불릿에 quantRegex **또는** 규모 토큰(사용자/팀/처리량/명/개) 매칭 여부 → 매칭 불릿/전체 ≥0.6. *About 제외, Experience만 적용* |
83
+ | R10 | Experience 책임-나열 회피(언어 분기) | 금지 서술어 불릿 ≤ 20% | **한국어**: 문말 서술어 패턴(담당/책임/수행/진행/관리/지원/대응/처리/운영 + 했/함/음) 스캔. **영문**: 불릿 첫 동사(Responsible for/Worked on/Helped/Assisted/Involved in) 스캔 → 비율 ≤0.2 |
84
+ | R11 | 핵심 섹션 충족 | 사진·위치·산업·학력·직책·스킬·About 7/7 non-empty + Featured ≥1(soft) | 각 필드 non-empty 카운트 = 7; Featured 0이면 warn |
85
+ | R12 | 스킬 최소 개수 | 5 ≤ 스킬 수 ≤ 50 | 스킬 배열 length ≥5 이고 ≤50(상한 초과 시 관련성 희석 warn) |
86
+ | R13 | 추천서 존재 + 관계 다양성 | Recommendations ≥1, 서로 다른 관계 ≥2(soft) | 추천서 카운트 ≥1; relationship 필드 고유값 ≥2이면 가산(없으면 warn, 엔도스먼트는 미집계) |
87
+ | R14 | 신선도 | last_updated ≤ 180일 **또는** open_to_work=true | 날짜 차 ≤180 또는 플래그 존재(둘 중 하나 충족) |
88
+ | R15 | 스킬-키워드 정렬 | 스킬 ≥3개가 헤드라인+About에도 등장 | 각 스킬을 (헤드라인+About) 텍스트와 부분문자열 매칭 → 일치 ≥3 |
89
+ | R16 | 길이 하드 상한 안전 체크 | 헤드라인 ≤220 **및** About ≤2,600자 | 두 필드 글자수 측정 → 초과 시 fail(키워드 손실/잘림 방지) |
90
+ | R17 | 국제화(병기) | 영문 1차 타깃이면 영문 필드 ASCII 비율 ≥ 0.6; 병기 타깃이면 한/영 둘 다 non-empty | 헤드라인/About의 ASCII 문자 비율 계산; 병기 모드면 두 언어 필드 존재 여부 |
91
+ | R18 | 사실 보존(보수적) | 산출물의 **숫자 토큰**이 입력 수치 집합 ∪ 파생수치(증감률) 화이트리스트에 포함; 고유명사는 화이트리스트 대조만 | 숫자만 정규화(3만↔30,000↔30k, 1,200ms 등) 후 차집합 검사. 85% 같은 파생 증감률은 입력 두 수에서 계산 가능하면 허용. **고유명사는 입력 화이트리스트(회사/제품 배열) 대조로 한정** — NER 불가하므로 미일치는 'AI 작성 시 보존'에 위임하고 validate는 *미검증(advisory)* 표시 |
92
+
93
+ **주요 실패 모드:**
94
+ - **사전 없는 키워드 체크의 거짓 통과/실패** — `target_keywords[]`가 비면 R2/R4/R5/R6/R10/R15가 무의미. → `INSUFFICIENT_INPUT` 가드로 차단(절대 임의 pass 금지).
95
+ - **fact-preservation 오탐** — 단위 표기 변형(3만/30,000/30k), 한영 회사명 차(ABC테크/ABC Tech), 파생 증감률(85%)을 '입력에 없는 토큰=할루시네이션'으로 오탐. → R18처럼 숫자만 정규화 검사 + 파생수치 화이트리스트 + 고유명사는 명시 화이트리스트로 한정(나머지는 advisory).
96
+ - **한국어 어순 무시** — '...를 담당' 식 문말 동사를 '첫 토큰' 검사로 놓침. → R10 언어 분기(한국어=문말 서술어, 영문=첫 동사).
97
+ - **정량 강제의 직군 차별** — 단일 70% 바가 디자인·PM·연구·신입을 일괄 탈락. → R9를 60% + 규모/범위 fallback으로 완화하고 Experience에만 적용(About 제외).
98
+ - **120자 한도 오인** — 220자 키워드 공간 절반 손실. → R1에서 상한(220, hard)과 front-load(120, soft)를 분리.
99
+ - **density 상한의 사전 종속** — 사전 크기가 곧 상한을 결정해 측정이 무의미. → R5 상한은 soft warn, 하한도 근거 약하므로 권장값으로만.
100
+ - **엔도스먼트 과신** — 약한 신호를 추천서와 동급 집계. → R13은 추천서만 집계, 엔도스먼트 미반영.
101
+
102
+ ## 4. 출처 (Provenance)
103
+
104
+ > **신뢰등급 라벨:** [공식]=LinkedIn/1차 · [2차]=기자/대학 재배포 · [추정/블로그]=마케팅·SEO 분석(확정 사실 아님).
105
+
106
+ - **[공식] LinkedIn Help — Your Profile level meter** — 프로필 강도에 반영되는 핵심 섹션(사진·위치·산업·학력·직책·스킬·요약)과 발견성·검색 노출 효과. *단, 현행 UI는 'All-Star 배지'를 약화/제거했을 수 있어 '배지' 프레이밍은 advisory.* · https://www.linkedin.com/help/linkedin/answer/a594698
107
+ - **[공식] LinkedIn — How to Use Keywords on LinkedIn** — 키워드 배치 핵심 섹션(헤드라인·About·직무 타이틀·스킬)과 검색 관련성. · https://www.linkedin.com/top-content/recruitment-hr/maximizing-your-linkedin-presence/how-to-use-keywords-on-linkedin/
108
+ - **[2차] Bill Murphy Jr.(Inc.com) — Google XYZ 공식** — 'Accomplished X as measured by Y by doing Z' 정량 성과 공식. *Laszlo Bock 'Work Rules!'에 영감을 둔 기자의 재해석이며 Bock의 원문 문구가 아님.* · https://www.linkedin.com/pulse/google-recruiters-say-using-x-y-z-formula-your-resume-bill-murphy-jr-
109
+ - **[2차] UT Austin School of Law 배포 PDF** — 위 Inc 기사의 대학 커리어 재배포본(1차 아님). · https://law.utexas.edu/wp-content/uploads/sites/44/2020/09/Google-Recruiters-Say-Using-the-X-Y-Z-Formula-on-Your-Resume-Will-Improve-Your-Odds-of-Getting-Hired-at-Google-_-Inc.com_.pdf
110
+ - **[추정/블로그] LinkedIn 프로필 최적화 가이드 2026 (JobSprout/CareerBldr)** — 헤드라인 공식, About 앞부분·키워드 분산, 모바일 truncation front-load. *키워드 8~12 같은 구체 수치의 1차 근거 아님 → soft만.* · https://careerbldr.com/blog/linkedin-profile-optimization-guide/
111
+ - **[추정/블로그] 리크루터 대상 LinkedIn 최적화 (GDH/Bridgeview/mimusa)** — 추천 중심 사회적 증거, 완성도, 엔도스먼트 약화. · https://gdhinc.com/optimize-your-linkedin/
112
+ - **[추정/블로그] LinkedIn 검색 신호 분석 (W3era/powerin)** — 키워드 관련성·완성도·네트워크 근접성·신선도. *공식 문서가 아니라 추정된 알고리즘이므로 '4대 신호'를 확정 사실로 제시하지 않음.* · https://www.powerin.io/blog/how-linkedin-search-works-and-how-to-hack-it
113
+ - **[공식 내부] AGENTS.md** — 사실·수치·고유명사 보존 원칙(할루시네이션 방지).
114
+
115
+ ## 5. Phase B 힌트 (아키텍처로 연결)
116
+
117
+ - **MCP 도구 아이디어:**
118
+ - `get_linkedin_playbook(section?: 'headline'|'about'|'experience'|'skills'|'completeness'|'network'|'social_proof'|'i18n'|'all')` — 해당 섹션의 원칙·do/dont·워크드 예시·금지어 사전·타깃 키워드 슬롯을 반환.
119
+ - `validate_linkedin_profile(profile_draft, target_keywords[], jd_keywords[]?, fact_whitelist?: {numbers[], proper_nouns[]}, lang: 'ko'|'en'|'bilingual')` — 위 루브릭을 LLM 없이 실행해 항목별 pass/fail/warn/INSUFFICIENT_INPUT + 측정값(개수·비율) + score를 반환. `target_keywords`가 임계 미만이면 키워드 체크를 INSUFFICIENT_INPUT으로 격리. 고유명사 검증은 `fact_whitelist.proper_nouns`가 있을 때만, 없으면 advisory.
120
+ - 데이터 소스 결합: 타깃 키워드/JD = `get_application_context`, 보존할 사실·수치 화이트리스트 = `get_profile`/`get_resumes`.
121
+
122
+ - **데이터 형태 힌트:**
123
+ ```
124
+ {
125
+ principles: [{ id, rule, rationale, source, trust: 'official'|'secondary'|'estimated' }],
126
+ doList: string[], dontList: string[],
127
+ bannedTerms: {
128
+ headline: string[],
129
+ about: string[],
130
+ experienceLeadVerbsEn: string[], // Responsible for, Worked on, Helped...
131
+ experienceTailPredicatesKo: string[] // 담당/책임/수행/진행/관리/지원/대응/처리/운영 (+했/함/음)
132
+ },
133
+ allStarSections: ['photo','location','industry','education','position','skills','summary'],
134
+ optionalSections: ['featured'],
135
+ quantRegex: '\\d+([.,]\\d+)?\\s*(%|배|원|명|ms|x|k|만|억|점|개|위|시간|일|주|개월|년)',
136
+ limits: { headlineHard: 220, headlineFrontload: 120, aboutHard: 2600, skillsMin: 5, skillsMax: 50 },
137
+ rubricChecks: [{
138
+ id, check, passBar,
139
+ measure: { type: 'count'|'ratio'|'exists'|'regex'|'length'|'date', target, threshold,
140
+ regex?, lang?: 'ko'|'en'|'bilingual',
141
+ severity: 'hard'|'soft', requiresDictionary?: bool }
142
+ }],
143
+ workedExamples: [{ section, before, after, why }]
144
+ }
145
+
146
+ // validate 반환:
147
+ {
148
+ checks: [{ id, status: 'pass'|'fail'|'warn'|'insufficient_input'|'advisory',
149
+ measured: number|bool, threshold }],
150
+ score: 0..1 // hard fail만 score에 강하게 반영, soft/advisory는 가중 약하게
151
+ }
152
+ ```