careermate 0.0.7 → 0.0.9

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 (71) hide show
  1. package/AGENTS.md +2 -2
  2. package/LICENSE +1 -1
  3. package/README.md +108 -91
  4. package/THIRD_PARTY_NOTICES.md +2 -1
  5. package/bin/careermate.mjs +11 -2
  6. package/dist/career-os/eop/cover-letter.md +13 -6
  7. package/dist/career-os/eop/interview-prep.md +1 -0
  8. package/dist/career-os/knowledge/cover-letter.md +7 -3
  9. package/dist/career-os/knowledge/fit-matching.md +2 -0
  10. package/dist/career-os/knowledge/verifiers/ai-detection-risk.md +57 -0
  11. package/dist/career-os/knowledge/verifiers/human-voice.md +7 -2
  12. package/dist/career-os/knowledge/verifiers/truthfulness.md +1 -0
  13. package/dist/doctor.mjs +19760 -1018
  14. package/dist/mcp.mjs +19783 -1035
  15. package/dist/migrate.mjs +289 -20
  16. package/dist/public/i18n/en/applications.js +19 -0
  17. package/dist/public/i18n/en/common.js +10 -0
  18. package/dist/public/i18n/en/documents.js +0 -10
  19. package/dist/public/i18n/en/home.js +5 -0
  20. package/dist/public/i18n/en/jobs.js +18 -1
  21. package/dist/public/i18n/en/profile.js +0 -5
  22. package/dist/public/i18n/en/settings.js +5 -2
  23. package/dist/public/i18n/ko/applications.js +19 -0
  24. package/dist/public/i18n/ko/common.js +9 -0
  25. package/dist/public/i18n/ko/documents.js +0 -10
  26. package/dist/public/i18n/ko/home.js +5 -0
  27. package/dist/public/i18n/ko/jobs.js +18 -1
  28. package/dist/public/i18n/ko/profile.js +0 -5
  29. package/dist/public/i18n/ko/settings.js +5 -2
  30. package/dist/public/lib.js +101 -0
  31. package/dist/public/pages/applications.js +95 -15
  32. package/dist/public/pages/documents.js +20 -14
  33. package/dist/public/pages/home.js +38 -6
  34. package/dist/public/pages/interview.js +11 -4
  35. package/dist/public/pages/jobs.js +71 -1
  36. package/dist/public/pages/profile.js +2 -3
  37. package/dist/public/pages/settings.js +2 -2
  38. package/dist/public/styles.css +52 -4
  39. package/dist/web.mjs +19001 -758
  40. package/docs/FAQ.md +13 -3
  41. package/docs/MCP_TOOLS.md +32 -12
  42. package/docs/career-os/eop/cover-letter.md +13 -6
  43. package/docs/career-os/eop/interview-prep.md +1 -0
  44. package/docs/career-os/knowledge/cover-letter.md +7 -3
  45. package/docs/career-os/knowledge/fit-matching.md +2 -0
  46. package/docs/career-os/knowledge/verifiers/ai-detection-risk.md +57 -0
  47. package/docs/career-os/knowledge/verifiers/human-voice.md +7 -2
  48. package/docs/career-os/knowledge/verifiers/truthfulness.md +1 -0
  49. package/package.json +5 -2
  50. package/packages/core/src/index.ts +2 -0
  51. package/packages/core/src/jobsearch.ts +190 -0
  52. package/packages/core/src/offers.ts +41 -0
  53. package/packages/core/src/services.ts +29 -3
  54. package/packages/core/src/summary.ts +431 -9
  55. package/packages/core/src/verify/charcount.ts +87 -0
  56. package/packages/core/src/verify/index.ts +1 -0
  57. package/packages/core/src/verify/lint.ts +5 -0
  58. package/packages/db/src/connection.ts +70 -2
  59. package/packages/db/src/index.ts +1 -0
  60. package/packages/db/src/repositories.ts +179 -13
  61. package/packages/db/src/schema.ts +169 -8
  62. package/packages/exporters/src/docx.ts +165 -0
  63. package/packages/exporters/src/index.ts +142 -9
  64. package/packages/exporters/src/markdown.ts +16 -11
  65. package/packages/knowledge/src/index.ts +8 -3
  66. package/packages/mcp-tools/src/result.ts +9 -0
  67. package/packages/mcp-tools/src/tools.ts +303 -60
  68. package/packages/parsers/src/documents.ts +7 -1
  69. package/packages/prompts/src/humanize.ts +4 -0
  70. package/packages/shared/src/schemas.ts +198 -0
  71. package/scripts/init.ts +7 -0
package/AGENTS.md CHANGED
@@ -19,12 +19,12 @@ CareerMate는 사용자 PC에만 데이터를 두는 **로컬 커리어 작업
19
19
  - **도구 응답은 사람 말로 바꿔라.** 응답에 `user_message`가 있으면 그 내용을 우선 활용하되 **사용자의 언어로 옮겨** 전달하고(한국어 원문을 그대로 복사하지 않는다), `suggested_next_action`은 선택지로 제안한다. `id`, `job_id`, `cover_letter_id`, `workflow_id`, JSON 원문, 도구 이름은 내부 작업용으로만 쓰고 사용자에게 그대로 복사하지 않는다.
20
20
  - **공고 분석 뒤에는 자기소개서를 곧장 쓰지 말고 선택지를 보여줘라.** 적합도 분석을 저장하고 쉬운 말로 설명한 뒤 "이 공고에 맞춘 자기소개서를 써드릴까요?"라고 묻고, `1. 네, 이 공고에 맞춘 자기소개서를 써줘` / `2. 아니요, 분석만 저장해줘`처럼 고르게 한다. 사용자가 1번을 고른 경우에만 자소서 작성·저장 흐름으로 이어간다. **1번(쓰기)을 고르면 작성 전에, 회사가 지정한 문항·양식·글자수 제한이 있으면 먼저 달라고 요청하라** — 한국 자소서는 문항형(회사별 항목·글자수)이 많아 문항·양식이 결과 질을 좌우한다. 공고·맥락에 없으면 사용자에게 문항 텍스트·제출 양식·글자수(상·하한, 공백포함 여부)를 묻고, 끝내 없으면 일반 양식으로 진행한다고 알린다. 받은 문항·양식·글자수는 작성에 반영하고 가능하면 공고에 함께 저장한다.
21
21
  - **표준 워크플로우를 따르라(핵심 6 + 선택 1)**: onboarding, analyze_job, write_cover_letter, write_career_description, manage_application_status, prepare_interview — 그리고 사용자가 LinkedIn·포트폴리오 같은 자기표현 자산을 요청하면 `build_personal_brand`. 순서가 헷갈리면 `get_workflow_guide`를 호출한다.
22
- - **사용자 대면 결과는 전문가 절차로 만들고, 저장 전 자가검증하라.** 공고 분석·자소서·경력기술서·면접 자료 등을 만들기 전에는 `get_workflow_guide`로 그 작업의 실행 절차(EOP)와 적용할 전문가 플레이북·검증기 순서를 먼저 받고, `get_playbook`(도메인 깊은 지식)으로 작성한 뒤 저장 직전 `get_verifier`(검증 루브릭)로 **당신이** 자가검증한다(사람이 쓴 듯한 글은 작성 직전 `get_writing_style_guide`도 함께 적용). CareerMate는 셀 수 있는 항목만 돕고 의미 판단은 당신 몫이다. 사실·수치·고유명사는 그대로 보존한다.
22
+ - **사용자 대면 결과는 전문가 절차로 만들고, 저장 전 자가검증하라.** 공고 분석·자소서·경력기술서·면접 자료 등을 만들기 전에는 `get_workflow_guide`로 그 작업의 실행 절차(EOP)와 적용할 전문가 플레이북·검증기 순서를 먼저 받고, `get_playbook`(도메인 깊은 지식)으로 작성한 뒤 저장 직전 `get_verifier`(검증 루브릭)로 **당신이** 자가검증한다(사람이 쓴 듯한 글은 작성 직전 `get_writing_style_guide`도 함께 적용). CareerMate는 셀 수 있는 항목만 돕고 의미 판단은 당신 몫이다. 사실·수치·고유명사는 그대로 보존한다. **자동(하드) 차단은 자기소개서 저장 시의 "근거 없는 수치" 하나뿐**이다 — 적합도 분석·면접 자료·경력기술서에는 기계 게이트가 없으므로 `get_verifier` 자가검증이 유일한 품질 관문이다. 건너뛰지 말고 반드시 점검 후 저장하라. 또한 점검 엄격 모드를 끄는 것(`set_verify_mode`의 strict=false)은 안전장치를 약화시키므로 사용자가 명확히 끄겠다고 말할 때만 호출한다.
23
23
  - **8단계 지원 상태를 존중하라**: `draft`(작성 중) → `planned`(지원 예정) → `applied`(지원 완료) → `document_passed`(서류 합격) → `interview`(면접 진행) → `final_passed`(최종 합격) / `rejected`(불합격) / `on_hold`(보류). 면접 준비는 사용자가 요청하면 공고 기준으로 저장할 수 있고, `document_passed` 이상에서는 다음 행동으로 우선 제안한다. 상태 변경은 `update_application_status`.
24
24
  - **업데이트 요청은 구분해서 처리하라.** 사용자가 "최신이야?", "업데이트 있어?"처럼 확인만 요청하면 `check_for_update`로 확인한다. "업데이트해줘", "CareerMate 업데이트해줘", "최신으로 올려줘"처럼 적용을 명시하면 `update_careermate`를 바로 호출한다(이 도구가 최신 버전 확인도 함께 한다). 성공 후에는 AI 앱 또는 MCP 연결 재시작이 필요하다고 안내한다.
25
25
  - **결과를 낼 때마다 대시보드로 안내하라.** 공고 저장·적합도 분석·자소서 버전·상태 변경·면접 준비 등 무언가를 저장·완료할 때마다 대시보드(`http://127.0.0.1:4319`) 주소를 알려준다. 브라우저를 직접 여는 건 **첫 온보딩 때 한 번만**(`open_dashboard`) — 이후에는 자동으로 열지 말고 링크만 보여주고, 사용자가 "열어줘"라고 하면 그때 `open_application`(단건)·`open_dashboard`(전체)로 연다.
26
26
  - **지원·문의·버그 신고는 정해진 경로로 안내하라(연락처를 지어내지 마라).** 사용자가 문제 신고·기능 요청·일반 문의를 하면: **버그·기능 요청**은 GitHub Issues(`https://github.com/osntak/careermate/issues`), **일반 문의**는 공개 이메일(`osntak@gmail.com`)로 안내한다 — 같은 링크가 **대시보드 설정 화면의 '도움말·문제 신고' 카드**(영어 UI는 'Help & report a problem')와 **사이트 푸터(careermate.life)** 에도 모여 있으니 그쪽을 알려줘도 된다. **보안 취약점은 공개 이슈로 올리지 말고** 비공개 절차(`SECURITY.md`의 GitHub Security Advisories)로 안내한다. 어느 경로든 신고·문의에 **이름·이메일·연락처·자소서 본문 같은 개인정보를 붙여넣지 말라고 먼저 경고**한다(데이터는 로컬에만 있으니 신고에 개인정보가 필요 없다).
27
- - **절대 사용자 데이터를 외부로 업로드하지 마라.** 모든 데이터는 `~/.careermate`(Windows: `%USERPROFILE%\.careermate`)에만 있고, 대시보드는 `127.0.0.1`에만 바인딩된다. CareerMate는 (선택적 버전 확인 외) 네트워크로 사용자 데이터를 보내지 않는다.
27
+ - **절대 사용자 데이터를 외부로 업로드하지 마라.** 모든 데이터는 `~/.careermate`(Windows: `%USERPROFILE%\.careermate`)에만 있고, 대시보드는 `127.0.0.1`에만 바인딩된다. CareerMate가 외부로 보내는 것은 선택적 버전 확인 요청과 공고 검색 시 **검색 키워드**뿐이며, 저장된 개인 데이터(프로필·이력서·자소서 등)는 어떤 서버로도 보내지 않는다. 사용자가 프라이버시를 물으면 이 경계를 그대로 설명하되, CareerMate 도구 응답이 당신(연결된 AI)에게 전달되는 만큼 그 처리에는 당신 쪽 AI 서비스의 정책이 적용된다는 점도 정직하게 알려라.
28
28
  - 기술 용어(MCP, `job_id` 등)는 사용자에게 노출하지 말고, 매 단계 무엇을 하는지 **사용자의 언어로** 쉽게 설명하라. 확실하지 않으면 지어내지 말고 사용자에게 확인하라.
29
29
 
30
30
  ## 아직 연결되지 않았다면
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 CareerMate
3
+ Copyright (c) 2026 osntak (CareerMate, https://github.com/osntak/careermate)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -4,14 +4,16 @@
4
4
 
5
5
  **한국어** · [English](#careermate-english)
6
6
 
7
- **MCP 우선(MCP-first) 로컬 커리어 관리 도구.** 내 컴퓨터에서 동작하는 AI 에이전트(Claude Desktop·Claude Code·Codex 등)를 인터페이스로 쓰고, CareerMate는 당신의 커리어 데이터를 **이 컴퓨터에만** 저장한 뒤 MCP로 노출합니다.
7
+ **평소 쓰는 AI에게 말로 커리어를 정리시키세요.** 이력서 등록·공고 분석·자기소개서·지원 현황·면접 준비를 내 컴퓨터에서 동작하는 AI 에이전트(Claude Desktop·Claude Code·Codex 등)에게 대화로 시키면, CareerMate가 그 결과를 **이 컴퓨터에만** 구조화해 보관하고 MCP로 노출합니다. CareerMate 안에 AI는 없습니다 — 생각은 당신의 AI가, 저장은 CareerMate가 합니다.
8
+
9
+ ![CareerMate 대시보드 — 오퍼 비교와 지원 현황](https://raw.githubusercontent.com/osntak/careermate/main/offers-applications.jpeg)
8
10
 
9
11
  ---
10
12
 
11
13
  ## 핵심 철학
12
14
 
13
15
  - **MCP 우선** — 새 앱 사용법을 익힐 필요가 없습니다. 내 컴퓨터에서 동작하는 AI 에이전트(Claude Desktop·Claude Code·Codex 등 로컬 MCP 클라이언트)와 대화하면, 그 AI가 CareerMate의 로컬 MCP 도구를 호출해 당신의 커리어 DB를 읽고 씁니다.
14
- - **로컬 우선** — 모든 데이터는 당신의 컴퓨터에만 저장됩니다(`~/.careermate`). 외부 서버로 전송하지 않습니다. 대시보드 웹 서버는 `127.0.0.1`(이 컴퓨터)에만 연결됩니다.
16
+ - **로컬 우선** — 모든 데이터는 당신의 컴퓨터에만 저장됩니다(`~/.careermate`). 저장된 개인 데이터는 외부 서버로 전송하지 않습니다 — 외부로 나가는 것은 선택적 버전 확인과 공고 검색 시 **검색 키워드**뿐입니다(아래 [보안 / 프라이버시](#보안--프라이버시) 참고). 대시보드 웹 서버는 `127.0.0.1`(이 컴퓨터)에만 연결됩니다.
15
17
  - **LLM 비내장** — CareerMate 안에는 AI가 들어 있지 않습니다. 분석·글쓰기 같은 “생각하는 일”은 **당신의 AI**가 하고, CareerMate는 데이터를 **안전하게 보관·조회**하는 역할만 합니다.
16
18
 
17
19
  > 쉽게 말해: 당신의 AI가 “두뇌”, CareerMate는 그 두뇌가 꺼내 쓰는 “커리어 서랍장”입니다.
@@ -33,10 +35,22 @@
33
35
  - **AI와 대화로 모든 작업** — MCP 도구로 온보딩·프로필·이력서·자소서·공고·핏 분석·지원 상태·면접 준비·전문가 플레이북·AI 티 안 나는 글쓰기까지 처리.
34
36
  - **지원 상태 8단계 관리** — `draft`(작성 중) · `planned`(지원 예정) · `applied`(지원 완료) · `document_passed`(서류 합격) · `interview`(면접 진행) · `final_passed`(최종 합격) · `rejected`(불합격) · `on_hold`(보류). `document_passed` 이상에서는 면접 준비를 다음 행동으로 제안합니다.
35
37
  - **자기소개서 버전 관리** — 공고별로 자소서 버전을 쌓고 타임라인으로 비교, 파일로 내보내기.
36
- - **채용공고 파싱** — 붙여넣은 공고 텍스트를 구조화해 저장.
38
+ - **공고 검색·가져오기** — 키워드(직무·기술)로 원티드·점핏 같은 공개 채용 사이트에서 공고를 바로 가져와, 마음에 드는 것만 저장. 키 발급·설치 없이 동작하며, 공개 공고를 *가져오기만* 합니다(봇 차단 우회·자동 대량수집 없음, 보내는 건 검색어뿐).
39
+ - **채용공고 파싱** — 붙여넣거나 가져온 공고 텍스트를 구조화해 저장.
37
40
  - **로컬 대시보드** — 프레임워크·CDN 없는 바닐라 JS로 만든 7페이지 웹 화면(다크모드 지원).
38
41
  - **데이터 내보내기/삭제** — Settings 페이지에서 직접.
39
42
 
43
+ > **예: 공고 검색** — "백엔드 공고 찾아줘"라고 하면 AI가 공개 사이트에서 공고를 모아 이렇게 보여주고, 고른 것만 저장합니다:
44
+ >
45
+ > > "백엔드" 공고 6건을 찾았어요 (원티드·점핏):
46
+ > > 1. **미소(miso)** — 백엔드 개발자 (Node.js) · 서울 · 경력 5~11년
47
+ > > 2. **콕스웨이브** — [AX Workflow Builder] 백엔드 엔지니어 · 서울 · 경력 3~7년
48
+ > > 3. **다우기술** — HTS 채널 개발 · 서울 마포구 · `JavaScript` `Mfc` · ~7/7 마감
49
+ > >
50
+ > > 어떤 공고를 저장해서 적합도 분석·자소서로 이어갈까요? (예: "1번, 3번 저장")
51
+
52
+ ![공고 상세 — 회사 리서치·적합도 분석·타임라인](https://raw.githubusercontent.com/osntak/careermate/main/job-company-research.jpeg)
53
+
40
54
  ---
41
55
 
42
56
  ## 구성
@@ -52,45 +66,12 @@
52
66
 
53
67
  ## 빠른 시작
54
68
 
55
- ### 요구사항
56
-
57
- - **Node.js >= 22.5.0** — 내장 `node:sqlite`를 사용하므로 컴파일러나 네이티브 빌드가 **필요 없습니다**.
58
- - 버전 확인:
59
- ```bash
60
- node --version
61
- ```
62
- `v22.5.0` 미만이거나 명령을 찾지 못하면 설치하세요 — Windows: `winget install OpenJS.NodeJS.LTS`, macOS: `brew install node`, 그 외: https://nodejs.org 에서 최신 LTS.
63
-
64
- ### 1) 설치
65
-
66
- 빌드 단계가 없습니다. TypeScript는 `tsx`로 바로 실행됩니다. (소스를 직접 받으려면 `git clone https://github.com/osntak/careermate.git`, 클론 없이 바로 쓰려면 `npx -y careermate init`을 쓰세요.)
67
-
68
- ```bash
69
- npm install
70
- ```
71
-
72
- ### 2) 대시보드 실행
73
-
74
- ```bash
75
- npm start
76
- ```
77
-
78
- - 기본 주소는 `http://127.0.0.1:4319` 이며 브라우저가 자동으로 열립니다.
79
- - 포트가 사용 중이면 자동으로 다음 빈 포트로 폴백하니, 터미널에 출력된 실제 주소를 확인하세요.
80
- - 종료는 터미널에서 `Ctrl+C`.
81
-
82
- ### 3) 데모 데이터로 둘러보기(선택)
83
-
84
- 빈 화면이 낯설다면 예시 데이터를 넣어 기능을 미리 체험할 수 있습니다.
85
-
86
- ```bash
87
- npm run seed
88
- ```
89
-
90
- ### 4) AI(MCP)에 연결
69
+ **요구사항은 Node.js >= 22.5.0 하나입니다** — 내장 `node:sqlite`를 쓰므로 컴파일러·네이티브 빌드가 필요 없습니다. `node --version`으로 확인하고, 미만이거나 명령이 없으면 설치하세요(Windows: `winget install OpenJS.NodeJS.LTS` · macOS: `brew install node` · 그 외: https://nodejs.org 최신 LTS).
91
70
 
92
71
  CareerMate는 **내 컴퓨터에서 로컬 stdio MCP 서버를 띄울 수 있는 AI**에서 동작합니다. (ChatGPT·Gemini의 웹/앱은 클라우드에서 동작해 로컬 stdio MCP 서버에 직접 연결할 수 없습니다.)
93
72
 
73
+ ### A. 그냥 쓰려면 (권장 — 클론·빌드 없음)
74
+
94
75
  설치는 크게 **3가지 — "누가 설치하느냐"** 의 차이입니다. 아래 순서대로 골라 쓰세요.
95
76
 
96
77
  #### ① 에이전트가 대신 설치 (권장)
@@ -117,12 +98,39 @@ npx -y careermate init
117
98
 
118
99
  #### ③ `careermate.zip` (Claude Desktop "채팅" 앱 전용 · Node 불필요 폴백)
119
100
 
120
- 터미널·Node 없이 붙이는 **유일한 길**입니다. `dist/careermate.zip`(`npm run build:mcpb`로 생성)을 압축 해제한 뒤, Claude Desktop의 **Settings → Extensions → Advanced settings → Install extension…** 에서 압축을 푼 폴더를 추가하고 재시작합니다. 단 Claude Desktop **내장 Node 버전에 의존해 불안정할 수 있습니다**(Node<22.5면 동작 불가).
101
+ 터미널·Node 없이 붙이는 **유일한 길**입니다. [최신 GitHub Release](https://github.com/osntak/careermate/releases/latest)에서 `careermate.zip`을 내려받아 압축 해제한 뒤, Claude Desktop의 **Settings → Extensions → Advanced settings → Install extension…** 에서 압축을 푼 폴더를 추가하고 재시작합니다. (소스에서 직접 만들려면 `npm run build:mcpb` → `dist/careermate.zip`.) 단 Claude Desktop **내장 Node 버전에 의존해 불안정할 수 있습니다**(Node<22.5면 동작 불가).
121
102
 
122
103
  `.mcpb` 직접 추가는 일부 Claude Desktop 버전에서 실패하는 알려진 이슈가 있어, 현재는 ZIP 압축 해제 후 폴더 추가를 권장합니다. `.mcpb`와 `.zip`은 같은 번들입니다.
123
104
 
124
105
  연결 후 AI 클라이언트를 **완전히 재시작**하고, `get_onboarding_status`를 호출해 달라고 시켜 연결을 검증하세요. 자세한 절차는 AI용 런북 **[`INSTALL.md`](INSTALL.md)**, 사람용 설치 안내 **https://careermate.life**, 설치 후 사용법 **[`docs/START_WORKFLOW.md`](docs/START_WORKFLOW.md)**, 지원 앱 매트릭스 **[`docs/SUPPORTED_AI_APPS.md`](docs/SUPPORTED_AI_APPS.md)**를 참고하세요.
125
106
 
107
+ ### B. 소스로 개발/기여하려면
108
+
109
+ ```bash
110
+ git clone https://github.com/osntak/careermate.git && cd careermate
111
+ npm install # 빌드 단계 없음 — TypeScript를 tsx로 바로 실행
112
+ npm start # 대시보드 http://127.0.0.1:4319 (포트 사용 중이면 다음 빈 포트로 폴백, Ctrl+C 종료)
113
+ npm run seed # (선택) 데모 데이터로 둘러보기
114
+ npm run init # 이 폴더 기준으로 AI 클라이언트에 MCP 등록
115
+ ```
116
+
117
+ AI 클라이언트에 연결된 상태라면 "대시보드 열어줘"만으로도 서버가 백그라운드에서 시작되므로, 대시보드가 터미널 세션에 묶이지 않습니다.
118
+
119
+ ### 안 되면 여기부터 (Troubleshooting)
120
+
121
+ <details>
122
+ <summary><b>AI가 도구를 못 봐요 · 원인을 모르겠어요 · Node 오류 · zip 실패 · 포트 충돌</b> — 5문항</summary>
123
+
124
+ 1. **AI가 CareerMate를 못 봐요** — AI 앱을 **완전히 종료 후 재시작**하세요(백그라운드/트레이 포함). Claude Code는 폴더 "신뢰" 1회 승인이 필요하고, `/mcp` 명령으로 careermate가 보이는지 확인할 수 있습니다.
125
+ 2. **뭐가 문제인지 모르겠어요** — 터미널에서 `npx -y careermate doctor`(Node·데이터 폴더·DB·도구 등록·업데이트 점검). AI에게 "doctor 돌려서 뭐가 문제인지 봐줘"라고 해도 됩니다.
126
+ 3. **Node 버전 오류** — `node --version`이 22.5 미만이면 최신 LTS로 재설치하고 **터미널을 새로 연 뒤** 다시 시도하세요.
127
+ 4. **Claude 채팅앱에 zip이 안 붙어요** — 알려진 이슈입니다. 압축을 **푼 폴더**를 추가하세요. 그래도 안 되면 ②의 `npx -y careermate init` 경로를 권장합니다.
128
+ 5. **포트 충돌** — 자동으로 다음 빈 포트로 폴백합니다. 터미널에 출력된 실제 주소를 확인하세요.
129
+
130
+ 더 많은 항목은 [`docs/FAQ.md`](docs/FAQ.md)에 있습니다. **보안 문제**는 공개 이슈 대신 [`SECURITY.md`](SECURITY.md)의 비공개 절차로 알려주세요.
131
+
132
+ </details>
133
+
126
134
  ---
127
135
 
128
136
  ## 대시보드 7페이지
@@ -150,15 +158,16 @@ npx -y careermate init
150
158
  | 이력서 | `read_document` · `add_resume` · `get_resumes` · `export_resume` · `delete_resume` · `open_inbox` · `read_inbox` |
151
159
  | 경력·프로젝트·스킬 | `add_experience` · `get_experiences` · `delete_experience` · `add_project` · `get_projects` · `delete_project` · `add_skill` · `get_skills` · `delete_skill` |
152
160
  | 자기소개서 | `get_cover_letters` · `save_cover_letter_version` · `delete_cover_letter` · `export_cover_letter` |
153
- | 채용공고 | `save_job_posting` · `get_job_posting` · `list_jobs` · `delete_job_posting` |
161
+ | 채용공고 | `search_jobs` · `save_job_posting` · `get_job_posting` · `list_jobs` · `prescreen_job` · `delete_job_posting` |
162
+ | 오퍼(제안) | `save_offer` · `compare_offers` · `get_offer` |
154
163
  | 핵심 컨텍스트 | **`get_application_context`** (지원에 필요한 맥락을 한 번에 모아줌) |
155
164
  | 핏 분석 | `save_fit_analysis` |
156
165
  | 지원 상태 | `update_application_status` |
157
166
  | 면접 준비 | `save_interview_prep` |
158
167
  | 글쓰기 | `get_writing_style_guide` (AI 티 안 나는 한국어 글쓰기 규칙) |
159
- | 전문가 지식 (Career-OS) | `get_playbook` (도메인 플레이북 16종) · `get_verifier` (저장 전 검증 루브릭 6종) |
168
+ | 전문가 지식 (Career-OS) | `get_playbook` (도메인 플레이북 16종) · `get_verifier` (저장 전 검증 루브릭 7종) |
160
169
  | 저장 전 점검 | `validate_cover_letter` (자소서 저장 전 미리보기) · `set_verify_mode` (점검 엄격도 기본/엄격) |
161
- | 대시보드/활동 | `open_dashboard` · `open_application` · `list_recent_activity` · `get_workflow_guide` |
170
+ | 대시보드/활동 | `open_dashboard` · `open_application` · `list_recent_activity` · `get_followups` · `get_pipeline_stats` · `get_workflow_guide` |
162
171
  | 업데이트 | `check_for_update` · `update_careermate` |
163
172
 
164
173
  이 도구들 위에 7종의 워크플로우가 정의되어 있어 AI가 단계별로 자연스럽게 안내합니다: 핵심 6종(`onboarding`, `analyze_job`, `write_cover_letter`, `write_career_description`, `manage_application_status`, `prepare_interview`)과 LinkedIn·포트폴리오용 `build_personal_brand`.
@@ -235,7 +244,7 @@ CareerMate/
235
244
  - **정적 파일 보호** — 경로 traversal(상위 폴더 탈출) 차단.
236
245
  - **본문 크기 제한** — 요청 본문 8MB 제한.
237
246
  - **민감 정보 비노출** — 이력서·자기소개서 본문은 로그나 에러 응답에 노출되지 않습니다.
238
- - **외부 전송 없음** — MCP 서버는 네트워크 호출을 하지 않으며, 모든 데이터는 당신의 컴퓨터에만 남습니다. 내보내기·삭제는 대시보드 **Settings**에서 직접 할 수 있습니다.
247
+ - **사용자 데이터 외부 전송 없음** — CareerMate는 당신의 프로필·이력서·자소서 등 **개인 데이터를 외부로 보내지 않습니다.** 모든 데이터는 당신의 컴퓨터에만 남습니다. 외부로 나가는 네트워크 호출은 (1) 선택적 버전 확인, (2) 공고 검색(공개 잡보드)뿐이며, 이때도 **보내는 것은 검색 키워드뿐**(개인 데이터 아님)이고 공개 공고를 *가져오기만* 합니다(봇 차단 우회·자동 대량수집 없음). 내보내기·삭제는 대시보드 **Settings**에서 직접 할 수 있습니다.
239
248
 
240
249
  ---
241
250
 
@@ -246,7 +255,7 @@ CareerMate/
246
255
  - [`docs/SUPPORTED_AI_APPS.md`](docs/SUPPORTED_AI_APPS.md) — **설치 레퍼런스 허브**: 지원 앱 매트릭스 + 설치 3방식(에이전트/npx/zip) + 클라이언트별 수동 MCP 설정 + 알려진 제약. (사람용 안내는 https://careermate.life)
247
256
  - [`docs/START_WORKFLOW.md`](docs/START_WORKFLOW.md) — 등록부터 면접 준비까지 단계별 작업 런북.
248
257
  - [`docs/FAQ.md`](docs/FAQ.md) — **자주 묻는 질문 / 문제 해결**: "PDF가 안 읽혀요", "분석이 안 돼요", "공고 URL은 어떻게 넣어요" 등.
249
- - [`docs/dev/TODO.md`](docs/dev/TODO.md) — 남은 작업과 v1 범위 밖 항목.
258
+ - [`docs/dev/ROADMAP.md`](docs/dev/ROADMAP.md) — 로드맵(앞으로 갈 방향).
250
259
  - [`CHANGELOG.md`](CHANGELOG.md) — 버전별 변경 이력. / [`CONTRIBUTING.md`](CONTRIBUTING.md) · [`SECURITY.md`](SECURITY.md) · [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — 기여·보안·행동 강령.
251
260
 
252
261
  ---
@@ -276,14 +285,16 @@ MIT 라이선스 — 전문은 [`LICENSE`](LICENSE) 파일을 참고하세요.
276
285
 
277
286
  [한국어](#careermate) · **English**
278
287
 
279
- **An MCP-first, local-only career workspace.** You drive it through an AI agent that runs on your own computer (Claude Desktop, Claude Code, Codex, …); CareerMate stores your career data **only on this machine** and exposes it over MCP.
288
+ **Let the AI you already use manage your career — by talking to it.** Ask an AI agent running on your own computer (Claude Desktop, Claude Code, Codex, …) to register your resume, analyze postings, draft cover letters, track applications, and prep interviews; CareerMate stores the results as structured data **only on this machine** and exposes them over MCP. There is no AI inside CareerMate — your AI does the thinking, CareerMate does the storing.
289
+
290
+ ![CareerMate dashboard — offer comparison and application pipeline](https://raw.githubusercontent.com/osntak/careermate/main/offers-applications.jpeg)
280
291
 
281
292
  ---
282
293
 
283
294
  ## Core philosophy
284
295
 
285
296
  - **MCP-first** — No new app to learn. You talk to an AI agent running on your machine (Claude Desktop, Claude Code, Codex, and other local MCP clients), and that AI calls CareerMate's local MCP tools to read and write your career database.
286
- - **Local-first** — All data lives only on your computer (`~/.careermate`). Nothing is sent to external servers. The dashboard web server binds only to `127.0.0.1` (this machine).
297
+ - **Local-first** — All data lives only on your computer (`~/.careermate`). Your stored personal data is never sent to external servers — the only outbound calls are the optional version check and the **search keyword** during job search (see [Security / privacy](#security--privacy) below). The dashboard web server binds only to `127.0.0.1` (this machine).
287
298
  - **No built-in LLM** — There is no AI inside CareerMate. The "thinking" — analysis, writing — is done by **your AI**; CareerMate only stores and serves the data safely.
288
299
 
289
300
  > In short: your AI is the "brain," and CareerMate is the "career drawer" it reaches into.
@@ -305,10 +316,22 @@ You can open the dashboard at any time to see your stored data. For a step-by-st
305
316
  - **Everything through conversation with AI** — MCP tools cover onboarding, profile, resumes, cover letters, job postings, fit analysis, application status, interview prep, expert playbooks, and human-sounding writing.
306
317
  - **8-stage application status** — `draft` · `planned` · `applied` · `document_passed` · `interview` · `final_passed` · `rejected` · `on_hold`. Interview prep is suggested at `document_passed` or later.
307
318
  - **Cover-letter versioning** — Stack versions per posting, compare on a timeline, export to a file.
308
- - **Job-posting parsing** — Turn pasted posting text into structured records.
319
+ - **Job search & import** — Pull postings by keyword (role/skill) straight from public job boards (e.g. Wanted, Jumpit) and save only the ones you like. No API key or setup; it only *fetches* public postings (no bot-protection bypass, no bulk harvesting — only the search keyword is sent).
320
+ - **Job-posting parsing** — Turn pasted or imported posting text into structured records.
309
321
  - **Local dashboard** — A 7-page web UI built with framework-free, CDN-free vanilla JS (dark mode supported).
310
322
  - **Export / delete your data** — Directly from the Settings page.
311
323
 
324
+ > **Example: job search** — Ask "find backend jobs" and the AI gathers postings from public boards, presents them like this, and saves only the ones you pick:
325
+ >
326
+ > > Found 6 "backend" postings (Wanted · Jumpit):
327
+ > > 1. **miso** — Backend Developer (Node.js) · Seoul · 5–11 yrs
328
+ > > 2. **Coxwave** — [AX Workflow Builder] Backend Engineer · Seoul · 3–7 yrs
329
+ > > 3. **Daou Tech** — HTS Channel Dev · Seoul Mapo-gu · `JavaScript` `Mfc` · due 7/7
330
+ > >
331
+ > > Which should I save to analyze fit / draft a cover letter? (e.g. "save #1 and #3")
332
+
333
+ ![Job detail — company research, fit analysis, timeline](https://raw.githubusercontent.com/osntak/careermate/main/job-company-research.jpeg)
334
+
312
335
  ---
313
336
 
314
337
  ## Architecture
@@ -324,46 +347,12 @@ Two local processes share the same database.
324
347
 
325
348
  ## Quick start
326
349
 
327
- ### Requirements
328
-
329
- - **Node.js >= 22.5.0** — uses the built-in `node:sqlite`, so **no compiler or native build** is required.
330
- - Check your version:
331
- ```bash
332
- node --version
333
- ```
334
- If it's below `v22.5.0` or the command isn't found, install it — Windows: `winget install OpenJS.NodeJS.LTS`, macOS: `brew install node`, otherwise the latest LTS from https://nodejs.org.
335
-
336
- ### 1) Install
337
-
338
- There is no build step. TypeScript runs directly via `tsx`. (To get the source directly, `git clone https://github.com/osntak/careermate.git`, or skip the clone and use `npx -y careermate init`.)
339
-
340
- ```bash
341
- npm install
342
- ```
343
-
344
- ### 2) Run the dashboard
345
-
346
- ```bash
347
- npm start
348
- ```
349
-
350
- - The default address is `http://127.0.0.1:4319` and the browser opens automatically.
351
- - If the port is busy, it falls back to the next free port — check the actual address printed in the terminal.
352
- - Stop it with `Ctrl+C` in the terminal.
353
- - When connected to an AI client, saying "open the dashboard" starts the server in the background if needed, so it is not tied to the AI terminal session.
354
-
355
- ### 3) Explore with demo data (optional)
356
-
357
- If a blank screen feels unfamiliar, seed example data to try the features first.
358
-
359
- ```bash
360
- npm run seed
361
- ```
362
-
363
- ### 4) Connect to your AI (MCP)
350
+ **The only requirement is Node.js >= 22.5.0** — CareerMate uses the built-in `node:sqlite`, so no compiler or native build is needed. Check with `node --version`; if it's below 22.5 or missing, install it (Windows: `winget install OpenJS.NodeJS.LTS` · macOS: `brew install node` · otherwise the latest LTS from https://nodejs.org).
364
351
 
365
352
  CareerMate works with **any AI that can launch a local stdio MCP server on your machine**. (The web/mobile apps of ChatGPT and Gemini run in the cloud and cannot connect directly to a local stdio MCP server.)
366
353
 
354
+ ### A. Just want to use it (recommended — no clone, no build)
355
+
367
356
  Installation comes down to **three options — "who does the installing."** Pick one, in this order.
368
357
 
369
358
  #### ① Let the agent install it for you (recommended)
@@ -390,12 +379,39 @@ For other clients (Cursor, Cline, Windsurf, …), `npx -y careermate init -- --p
390
379
 
391
380
  #### ③ `careermate.zip` (Claude Desktop "chat" app only · no-Node fallback)
392
381
 
393
- This is the **only path with no terminal and no Node**. Unzip `dist/careermate.zip` (created via `npm run build:mcpb`), add the extracted folder through Claude Desktop's **Settings → Extensions → Advanced settings → Install extension…**, then restart. Note that it **depends on Claude Desktop's bundled Node version** (won't work if that Node is < 22.5).
382
+ This is the **only path with no terminal and no Node**. Download `careermate.zip` from the [latest GitHub Release](https://github.com/osntak/careermate/releases/latest), unzip it, add the extracted folder through Claude Desktop's **Settings → Extensions → Advanced settings → Install extension…**, then restart. (To build it from source: `npm run build:mcpb` → `dist/careermate.zip`.) Note that it **depends on Claude Desktop's bundled Node version** (won't work if that Node is < 22.5).
394
383
 
395
384
  Direct `.mcpb` install is a known issue in some Claude Desktop builds, so the ZIP folder path is the recommended no-terminal route. The `.mcpb` and `.zip` assets contain the same bundle.
396
385
 
397
386
  After connecting, **fully restart** the AI client and verify the connection by asking it to call `get_onboarding_status`. For details, see the AI runbook **[`INSTALL.md`](INSTALL.md)**, the human-facing install guide **https://careermate.life**, the post-install usage flow **[`docs/START_WORKFLOW.md`](docs/START_WORKFLOW.md)**, and the supported-apps matrix **[`docs/SUPPORTED_AI_APPS.md`](docs/SUPPORTED_AI_APPS.md)**.
398
387
 
388
+ ### B. Develop / contribute from source
389
+
390
+ ```bash
391
+ git clone https://github.com/osntak/careermate.git && cd careermate
392
+ npm install # no build step — TypeScript runs directly via tsx
393
+ npm start # dashboard at http://127.0.0.1:4319 (falls back to the next free port; Ctrl+C to stop)
394
+ npm run seed # (optional) explore with demo data
395
+ npm run init # register the MCP server with your AI clients, rooted at this folder
396
+ ```
397
+
398
+ When an AI client is connected, saying "open the dashboard" starts the server in the background if needed, so the dashboard is not tied to a terminal session.
399
+
400
+ ### If it doesn't work, start here (troubleshooting)
401
+
402
+ <details>
403
+ <summary><b>AI can't see the tools · not sure what's wrong · Node error · zip won't attach · port conflict</b> — 5 checks</summary>
404
+
405
+ 1. **The AI can't see CareerMate** — **Fully quit and restart** the AI app (including tray/background). Claude Code needs a one-time folder "trust" approval; use the `/mcp` command to check that careermate is listed.
406
+ 2. **Not sure what's wrong** — Run `npx -y careermate doctor` in a terminal (checks Node, data folder, DB, tool registration, updates). Or just ask your AI: "run doctor and tell me what's wrong."
407
+ 3. **Node version error** — If `node --version` is below 22.5, install the latest LTS and **open a new terminal** before retrying.
408
+ 4. **The zip won't attach in the Claude chat app** — Known issue. Add the **extracted folder** instead. If that still fails, use the `npx -y careermate init` path from ②.
409
+ 5. **Port conflict** — It falls back to the next free port automatically; check the actual address printed in the terminal.
410
+
411
+ More in [`docs/FAQ.md`](docs/FAQ.md). For **security issues**, use the private process in [`SECURITY.md`](SECURITY.md) instead of a public issue.
412
+
413
+ </details>
414
+
399
415
  ---
400
416
 
401
417
  ## The 7 dashboard pages
@@ -423,15 +439,16 @@ Dark mode is supported.
423
439
  | Resume | `read_document` · `add_resume` · `get_resumes` · `export_resume` · `delete_resume` · `open_inbox` · `read_inbox` |
424
440
  | Experience / projects / skills | `add_experience` · `get_experiences` · `delete_experience` · `add_project` · `get_projects` · `delete_project` · `add_skill` · `get_skills` · `delete_skill` |
425
441
  | Cover letter | `get_cover_letters` · `save_cover_letter_version` · `delete_cover_letter` · `export_cover_letter` |
426
- | Job posting | `save_job_posting` · `get_job_posting` · `list_jobs` · `delete_job_posting` |
442
+ | Job posting | `search_jobs` · `save_job_posting` · `get_job_posting` · `list_jobs` · `prescreen_job` · `delete_job_posting` |
443
+ | Offer | `save_offer` · `compare_offers` · `get_offer` |
427
444
  | Core context | **`get_application_context`** (gathers all context needed for an application in one call) |
428
445
  | Fit analysis | `save_fit_analysis` |
429
446
  | Application status | `update_application_status` |
430
447
  | Interview prep | `save_interview_prep` |
431
448
  | Writing | `get_writing_style_guide` (rules for human-sounding Korean writing) |
432
- | Expert knowledge (Career-OS) | `get_playbook` (16 domain playbooks) · `get_verifier` (6 pre-save rubrics) |
449
+ | Expert knowledge (Career-OS) | `get_playbook` (16 domain playbooks) · `get_verifier` (7 pre-save rubrics) |
433
450
  | Pre-save check | `validate_cover_letter` (dry-run preview before saving) · `set_verify_mode` (check strictness: default/strict) |
434
- | Dashboard / activity | `open_dashboard` · `open_application` · `list_recent_activity` · `get_workflow_guide` |
451
+ | Dashboard / activity | `open_dashboard` · `open_application` · `list_recent_activity` · `get_followups` · `get_pipeline_stats` · `get_workflow_guide` |
435
452
  | Update | `check_for_update` · `update_careermate` |
436
453
 
437
454
  On top of these tools, seven workflows are defined so the AI can guide you naturally, step by step: the six core flows (`onboarding`, `analyze_job`, `write_cover_letter`, `write_career_description`, `manage_application_status`, `prepare_interview`) plus `build_personal_brand` for LinkedIn/portfolio assets.
@@ -509,7 +526,7 @@ CareerMate/
509
526
  - **Static-file protection** — Path traversal (escaping the parent folder) is blocked.
510
527
  - **Body size limit** — Request bodies are capped at 8MB.
511
528
  - **No sensitive-data leakage** — Resume and cover-letter content is never exposed in logs or error responses.
512
- - **No external transmission** — The MCP server makes no network calls, and all data stays only on your computer. Export and delete are available directly in the dashboard **Settings**.
529
+ - **No personal-data transmission** — CareerMate never sends your personal data (profile, resumes, cover letters) anywhere; all data stays only on your computer. The only outbound network calls are (1) the optional version check and (2) job search (public job boards) — and even then only the **search keyword** is sent (no personal data), to *fetch* public postings (no bot-protection bypass, no automated bulk harvesting). Export and delete are available directly in the dashboard **Settings**.
513
530
 
514
531
  ---
515
532
 
@@ -520,7 +537,7 @@ CareerMate/
520
537
  - [`docs/SUPPORTED_AI_APPS.md`](docs/SUPPORTED_AI_APPS.md) — **Install reference hub**: supported-apps matrix + the 3 install methods (agent / npx / zip) + per-client manual MCP setup + known constraints. (Human-facing guide at https://careermate.life)
521
538
  - [`docs/START_WORKFLOW.md`](docs/START_WORKFLOW.md) — Step-by-step runbook from registration to interview prep.
522
539
  - [`docs/FAQ.md`](docs/FAQ.md) — **FAQ / troubleshooting**: "PDF won't read," "analysis isn't working," "how do I add a posting URL," etc.
523
- - [`docs/dev/TODO.md`](docs/dev/TODO.md) — Remaining work and out-of-scope-for-v1 items.
540
+ - [`docs/dev/ROADMAP.md`](docs/dev/ROADMAP.md) — Roadmap (where the project is headed).
524
541
  - [`CHANGELOG.md`](CHANGELOG.md) — Per-version change history. / [`CONTRIBUTING.md`](CONTRIBUTING.md) · [`SECURITY.md`](SECURITY.md) · [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — Contributing, security, and code of conduct.
525
542
 
526
543
  ---
@@ -42,7 +42,7 @@ SOFTWARE.
42
42
 
43
43
  ## 번들에 포함되는 npm 의존성 (런타임)
44
44
 
45
- 배포 시 `dist/` 번들(esbuild)에 코드가 인라인되는 런타임 의존성입니다. MCP 서버·프로토콜(`@modelcontextprotocol/sdk`)과 입력 스키마 검증(`zod`), 그리고 `read_document`의 문서 텍스트 추출(순수 JS)에 사용합니다. 각 라이선스 고지를 보존하며, 각 라이선스 전문은 설치된 `node_modules/<패키지>/LICENSE` 에 포함됩니다.
45
+ 배포 시 `dist/` 번들(esbuild)에 코드가 인라인되는 런타임 의존성입니다. MCP 서버·프로토콜(`@modelcontextprotocol/sdk`)과 입력 스키마 검증(`zod`), `read_document`의 문서 텍스트 추출, 그리고 이력서·자기소개서의 `.docx` 내보내기(`docx`)에 사용합니다(모두 순수 JS). 각 라이선스 고지를 보존하며, 각 라이선스 전문은 설치된 `node_modules/<패키지>/LICENSE` 에 포함됩니다.
46
46
 
47
47
  | 패키지 | 용도 | 라이선스 | 저작권 |
48
48
  | --- | --- | --- | --- |
@@ -52,5 +52,6 @@ SOFTWARE.
52
52
  | [`hwp.js`](https://github.com/hahnlee/hwp.js) | `.hwp`(HWP 5.x) → 텍스트 | Apache-2.0 | Copyright Han Lee and other contributors |
53
53
  | [`fflate`](https://github.com/101arrowz/fflate) | `.hwpx` 압축 해제 | MIT | Copyright (c) 2023 Arjun Barrett |
54
54
  | [`pdfjs-dist`](https://github.com/mozilla/pdf.js) | `.pdf` → 텍스트 | Apache-2.0 | Copyright Mozilla Foundation and contributors |
55
+ | [`docx`](https://github.com/dolanmiu/docx) | 이력서·자기소개서 → `.docx` 내보내기 | MIT | Copyright (c) 2016 Dolan Miu |
55
56
 
56
57
  > Apache-2.0(`hwp.js`, `pdfjs-dist`)은 라이선스 사본과 NOTICE 고지 보존을 요구합니다. 위 표와 `node_modules`의 동봉 라이선스로 이를 충족합니다.
@@ -59,11 +59,20 @@ if (isHelp || !ENTRIES[cmd]) {
59
59
  process.exit(isHelp ? 0 : 1);
60
60
  }
61
61
 
62
+ // node:sqlite는 22.5–22.12 / 23.0–23.3에서만 --experimental-sqlite가 필요하다.
63
+ // 22.13/23.4부터는 무플래그로 동작하고, 일부 런타임(Claude Desktop 내장 Node 24가
64
+ // 실제 사례 — CHANGELOG 0.0.3)은 모르는 플래그를 하드 거부하므로 필요한 버전에만 전달한다.
65
+ // (22.5 미만은 node:sqlite 자체가 없다 — doctor가 버전 안내를 담당.)
66
+ const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(Number);
67
+ const needsSqliteFlag =
68
+ (nodeMajor === 22 && nodeMinor >= 5 && nodeMinor < 13) || (nodeMajor === 23 && nodeMinor < 4);
69
+ const nodeFlags = ['--no-warnings', ...(needsSqliteFlag ? ['--experimental-sqlite'] : [])];
70
+
62
71
  const bundle = BUNDLES[cmd] ? path.join(ROOT, BUNDLES[cmd]) : null;
63
72
  const runArgs =
64
73
  bundle && fs.existsSync(bundle)
65
- ? ['--no-warnings', '--experimental-sqlite', bundle, ...rest]
66
- : ['--no-warnings', '--experimental-sqlite', '--import', 'tsx', path.join(ROOT, ENTRIES[cmd]), ...rest];
74
+ ? [...nodeFlags, bundle, ...rest]
75
+ : [...nodeFlags, '--import', 'tsx', path.join(ROOT, ENTRIES[cmd]), ...rest];
67
76
 
68
77
  // 자식 cwd는 tsx/tsconfig(paths 별칭) 해석을 위해 ROOT로 고정한다. 하지만 init은 사용자가
69
78
  // 명령을 친 '작업 폴더'에 .mcp.json·권한 설정을 써야 하므로, 원래 cwd를 env로 함께 넘긴다
@@ -19,17 +19,22 @@
19
19
 
20
20
  ## 2. 분석·작성 절차
21
21
  1. **회사 리서치**(company-research): 미션·사업·제품·최근 활동·인재상 → 본인과 연결할 고유 포인트 확보.
22
- 2. **문항 의도 해석:** 지원동기=여기 오게 한 *구체 경험*(표면 관심 X); 성장과정=동기의 *근원+서사 연결*(인생 연대기 X); 직무역량=역할의 *핵심 역량 1~2개 정확 식별+증명*; 입사후포부=*회사 사업방향에 묶인* 단기·중기·장기(전문가 포지셔닝) 로드맵(과대 금지). **연차 수치(1~3년 등)는 일반 로드맵 골격일 때만 — 본인 기여·성과에 '입사 후 1~2년은'처럼 저장·공고에 없는 기간을 단정하지 마라(출처 밖 기간 단정=C4).** <!-- applied: r7-cover-letter / R7 cross-vendor PASS cl-s1=94 PERFECT (opus생성·codex채점) / 2026-06-20 -->
22
+ 2. **문항 의도 해석:** 지원동기=여기 오게 한 *구체 경험*(표면 관심 X) — **'왜 이 회사·이 직무인가'가 도입 1~2문장 안에 서야 한다: 성과 일화로 열더라도 첫 문단이 끝나기 전에 회사로 연결한다(회사 연결이 마지막 문단으로 밀리면 문항 응답성 감점)**; 성장과정=동기의 *근원+서사 연결*(인생 연대기 X); 직무역량=역할의 *핵심 역량 1~2개 정확 식별+증명*; 입사후포부=*회사 사업방향에 묶인* 단기·중기·장기(전문가 포지셔닝) 로드맵(과대 금지). **포부는 재탕이 아니다 — 앞 문항에서 이미 쓴 과거 일화의 재인용으로 채우지 마라. 회사·직무에서 *새로 하려는 것*(공고의 업무·기술 키워드 기반) 최소 1개를 구체적으로 적는다**(예: 공고가 '결제 도메인'이면 그 도메인에서 앞으로 만들고 싶은 것). **연차 수치(1~3년 등)는 일반 로드맵 골격일 때만 — 본인 기여·성과에 '입사 후 1~2년은'처럼 저장·공고에 없는 기간을 단정하지 마라(출처 밖 기간 단정=C4).** <!-- applied: aspiration-not-rehash / 블라인드 벤치마크 감점 반영 --> <!-- applied: r7-cover-letter / R7 cross-vendor PASS cl-s1=94 PERFECT (opus생성·codex채점) / 2026-06-20 -->
23
23
  3. **본인 증거 매핑:** 저장 경력/프로젝트에서 문항·역량을 증명할 경험 **1~2개를 깊게** 선택(얕게 5~6개 나열 금지).
24
+ - **문항 간 성과 배분(복수 문항 자소서 — 성과 폭을 넓게):** 대표 성과 1개는 **1개 문항에만** 배정한다. 문항마다 다른 경험·성과 축을 써서 지원자의 폭이 넓어 보이게 하라(같은 프로젝트·수치를 여러 문항에 재활용하면 밑천이 얕아 보인다). 저장된 성과가 1개뿐이라 겹칠 수밖에 없으면 **문항별 각도를 완전히 분리**한다 — 한 문항은 기술·실행 과정으로, 다른 문항은 동기·의미·배움으로 다루고 **같은 수치를 재인용하지 않는다**. <!-- applied: cross-question-allocation / 블라인드 벤치마크(채용담당자 페르소나 3:0) 감점 반영 -->
24
25
  - **기존 자소서 차별화(있을 때 — 자기복제 방지):** 기존 자소서는 *참고*지 *템플릿*이 아니다. **(1) 사실은 일관되게** — 경험·수치·고유명사·사용자 보이스는 공고가 달라도 같아야 하며, 자기복제를 피하려고 억지로 비틀지 마라(사실 왜곡 = C4). **(2) 프레이밍·산문은 새로** — 직무 적합 앵글·why-this-company·도입 훅·문장 표현은 이 공고에 맞춰 새로 짠다. 같은 대표 경험을 또 쓸 거면 *이 공고의 요구역량·인재상에 맞는 다른 각*으로 재프레이밍하고, 가능하면 *다른 경험*으로 다양화한다. **직전 자소서를 회사명·일부 토큰만 바꿔 따라 쓰지 마라(가장 흔한 실패).**
25
- 4. **초안 작성:** 항목별 **소제목** + **두괄식**(핵심 결론 먼저) → **STAR-lite**(S/T 짧게, A에 무게, R=전후 델타 정량) → **직무/인재상 명시 연결**. 회사 고유 근거 1~3문장("회사명 placeholder로 바꾸면 어색"이어야 함). 글자수 **상한의 ~70%+를 채우되**, 입사후포부는 앞 문단과 **다른 새 기여**로(같은 성과·표현 반복 금지).
26
+ - **디깅 인터뷰(선택한 경험 → 초안 전 필수):** 고른 경험마다 사용자에게 3~5개를 묻는다 — (1) 가장 막혔던 순간 (2) 실패한 첫 시도와 그 이유 (3) 왜 그 방법을 골랐나(버린 대안) (4) 그때 실제로 들은·한 말 (5) 수치의 앞뒤 맥락. **사용자 답변의 표현을 그대로 수집**하고, 본문에 사용자 원문 표현을 **3개 이상**(다듬되 어휘·결 보존) 살린다 — 이 원자료가 '겪은 사람만 아는 디테일'의 유일한 출처다(디깅 없이 성과·수치 나열만으로 채우지 마라 = AI 티의 근본 원인). 수집한 답변은 `add_experience`로 해당 경험의 description/achievements에 갱신 저장해 다음 문서에서 재사용한다(디깅은 1회 자산). 컨텍스트에 이미 충분한 디깅 원자료가 있으면 재질문하지 말고 그대로 쓴다. <!-- applied: experience-digging / 블라인드 벤치마크 잔여 AI 의심도(고유 디테일 밀도 부족) 대응 -->
27
+ 4. **앵글 설정(차별화 게이트 — 초안 전 확정):** 바로 쓰지 말고, 이 공고에 맞춘 **2~3개 후보 앵글**을 먼저 세운다. 네 축으로 잡는다 — **why**(왜 이 회사·직무인가: 표면 관심이 아닌 구체적 이유) · **problems**(이 회사/팀의 어떤 문제를 풀고 싶은가 — 회사 리서치·공고 기반) · **approach**(저장 경험이 증명하는 *나만의* 접근/방법) · **tone**(원하는 문체 — `profile.preferred_tone` 우선, 없으면 담백/따뜻/격식 중 확인). **기존 자소서·다른 공고와 다른 각을 강제**해 자기복제를 끊는다(§2-3과 직결). 앵글이 컨텍스트로 자명하면 묻지 말고 1개로 진행하되 무엇을 골랐는지 검토 메모(§4②)에 적고, 모호하면 후보 앵글을 사용자에게 한 번 제시해 고르게 한 뒤 그 앵글로만 초안을 전개한다(과한 질문 금지 — 자명하면 그냥 진행). <!-- career-ops 차용: why/problems/approach/tone 앵글 프롬프트 -->
28
+ 5. **초안 작성:** 항목별 **소제목** + **두괄식**(핵심 결론 먼저) → **STAR-lite**(S/T 짧게, A에 무게, R=전후 델타 정량) → **직무/인재상 명시 연결**. 회사 고유 근거 1~3문장("회사명 placeholder로 바꾸면 어색"이어야 함). 글자수 **상한의 ~70%+를 채우되**, 입사후포부는 앞 문단과 **다른 새 기여**로(같은 성과·표현 반복 금지).
26
29
  - **STAR 앵커 우선(사실 변경 금지·표현 강화 허용):** Action/Result는 저장된 '한 일'(도입·적용·운영·분석한 것)과 저장된 결과에 앵커한다. 저장된 행위·맥락은 풍부하게 서술해도 좋다(평가자가 중시하는 경험 서술형 환영). **금지는 발명뿐** — 저장 근거가 없는 진단 결과·방법/도구·원인 규명·실패율·문서화·후속 성과를 새로 지어내지 마라. 저장에 없는 과정을 꼭 암시해야 하면 "기록/근거로 범위를 좁혔다" 수준의 중립 한 구절까지만. <!-- applied: P4-star-anchor / closed 2026-06-20 — codex 규칙-텍스트 전용 표결 agree(4/4) + claude 3모델 만장일치 + R7 산출물 PASS 간접지지(cl-s1=94 opus생성·codex채점 / cl-s2 codex생성 90 PASS) -->
27
30
  - **프레이밍 경계(작성·평가 공통):** 일반 도메인 원리는 *후보 귀속 없이* 맥락으로 OK. 비즈니스 임팩트·문제 프레이밍은 *저장된 성과/지표가 암시하는 범위 안*에서만. **(아래 예시는 IT 직군 하나의 예일 뿐 — 원리는 전 직군 동일: 영업=매출/전환 기록, 운영·생산=처리량/불량률 기록, 마케팅=유입/전환 기록 등.)** 예: p99 개선 기록 → "느린 구간을 좁혀" OK / 기록 없는 "결제 경험을 해치던" 단정 금지. 사고·이유 귀속은 *저장된 결정·행동이 논리적으로 함의할 때만*(예: "Kafka 보류 결정" 저장 → "복잡도 대비 효과가 적어 보류" OK / "새 기술보다 ~가 낫다고 봤다"식 새 판단 삽입 금지). **금지:** 후보가 측정·관찰·확인했다는 행위, 출처에 없는 중간 지표(A/B를 "클릭"으로 특정), 출처에 없는 파생 정확수치(%·배수) 단정(저장 전후값은 그대로 쓰거나 "절반 이하로" 같은 정성 표현만 허용), 진단 결과·원인·감정·의도를 후보의 사실로 단정. **수치·고유명사는 저장 데이터의 범위·채널·주체 그대로 쓴다('캠페인 누적'을 '인스타그램 누적'으로 좁히듯 채널/주체 재귀속 금지). 학습·기초만 저장된 것을 수행으로 승격하지 마라('SQL 기초 학습'+'주간 리포트 작성'→"SQL로 데이터를 추출해 리포트 작성"식 연결 단정 금지).** <!-- applied: fact-anchor-boundary / closed 2026-06-20 — codex 규칙-텍스트 전용 표결 agree(4/4) + claude 3모델 만장일치 + R7 경계강화 cross-vendor PASS 간접지지 -->
28
- 5. **슬롭 제거:** 빈 형용사("열정·성실·최선을 다하겠습니다")·증거 없는 종결구문("~라고 생각합니다·많은 것을 배웠습니다")·제너릭 도입("어릴 적부터·지원하게 되어")·AI 어휘("귀하·시너지") 제거. human-writing 가이드(`get_writing_style_guide`) 적용.
29
- 6. **규칙 점검:** 글자수 상·하한(byte/char) · 지정 양식 · 블라인드(공공: 직무무관 개인정보·학교·지역·가족·사진 금지).
31
+ - **기술 경험은 한 단계 더 날것으로(과도한 매끈함이 curated/AI 의심을 부른다):** 기술 문항·기술 경험 서술은 추상 요약("이벤트를 먼저 저장하는 방식")에 멈추지 말고 최소 1곳은 **패턴 명명·구체 구현 수준**으로 내려간다(예: "Outbox 패턴 — 수신 즉시 별도 테이블에 기록하고 워커가 폴링"). 구체 기술 흔적이 지나친 매끈함이 주는 사람확률 감점을 상쇄한다(human-baseline 실측). **단 저장 사실에 없는 구현 디테일(패턴명·아키텍처·도구)을 지어내지 마라 — 없으면 디깅 인터뷰(step 3)에서 물어 채운다.** <!-- applied: tech-detail-rawness / 광역 벤치마크 human-baseline 심판 실측(디테일 부재 감점) -->
32
+ 6. **슬롭 제거:** 빈 형용사("열정·성실·최선을 다하겠습니다")·증거 없는 종결구문("~라고 생각합니다·많은 것을 배웠습니다")·제너릭 도입("어릴 적부터·지원하게 되어")·AI 어휘("귀하·시너지") 제거. **"배웠습니다/기여하겠습니다"류 마무리 상투를 문항마다 반복하지 마라 — 문서 전체에서 한 번이면 충분하다**(human-voice 관점). human-writing 가이드(`get_writing_style_guide`) 적용.
33
+ 7. **규칙 점검:** 글자수 상·하한(byte/char) · 지정 양식 · 블라인드(공공: 직무무관 개인정보·학교·지역·가족·사진 금지).
30
34
 
31
35
  ## 3. 한국/영문 분기
32
36
  - **KR 문항형:** 문항당 별개 글, 두괄식 + 문항-역량 매핑, 소제목, 글자수 엄수. 성장과정만 가벼운 서사 허용하되 핵심은 여전히 front-load.
37
+ - **NCS 경험기술서·'시간순 기술' 요구 문항:** 문항이 시간순 기술을 지시하면 각 항목 앞에 **연·월 기간을 명시하고 엄격한 시간순으로 정렬**한다(이 지시가 두괄식보다 우선). 시점 불명 항목은 금지 — 기간이 저장·공고에 없으면 사용자에게 물어서라도 채운다.
33
38
  - **EN 단일 레터:** hook → fit(증거) → why-this-company → close, 1페이지(≈250~400단어), 능동태, 수신자 실명 리서치, **고용주 관점**(내가 줄 가치), ATS 안전 포맷(표/컬럼/머리말 금지·본문에 연락처), JD 키워드를 증거 문장 안에.
34
39
 
35
40
  ## 4. 출력 계약 (사용자 대면)
@@ -45,7 +50,9 @@
45
50
  내부 루브릭·도구명·이 EOP는 노출하지 않는다. 결과 저장은 `save_cover_letter_version`, 안내는 대시보드 링크.
46
51
 
47
52
  ## 5. 자가검증 루브릭 (제출 전 — research §리뷰어 루브릭)
53
+ **탐지관 2차 패스(루브릭 채점 전 필수):** 초안을 'AI 자소서 탐지 심사역' 눈으로 공격한다 — **균일한 문장 리듬 / 대칭 경구·최상급 일반론 / 상투 마무리("배웠습니다·기여하겠습니다" 연발)** 중 **가장 의심스러운 3문장**을 지목해, 디깅으로 확보한 사용자 원문 표현·구체 사건으로 고친 뒤 아래 루브릭으로 채점·저장한다. <!-- applied: detector-second-pass / 블라인드 벤치마크 잔여 AI 의심도 대응 -->
54
+
48
55
  **CRITICAL(하나라도 → 재작성):** C1 회사/직무/지역 오기·교차지원 복붙 흔적·**기존 자소서 템플릿 복제**(다른 공고인데 직무 적합 앵글·도입·산문이 직전 자소서와 거의 같아 회사명만 바뀐 수준 — *단 사실·수치·고유명사·보이스의 일관성은 정상이며 억지 변형 금지*; 문제는 프레이밍·문장의 무차별 carryover다) / C2 자격·필수요건 미충족·미언급 / C3 글자수(byte/char cap)·양식·필수항목 위반(**제출용 본문 블록에 결론/근거/리스크 등 메타 텍스트 혼입** 포함) / C4 날조 또는 문서 간 모순 수치(**수치·고유명사는 저장 데이터의 범위·채널·주체 그대로 쓴다 — '캠페인 누적'을 '인스타그램 누적'처럼 더 좁은 채널/주체로 재귀속(범위 변경)하거나, 저장·공고에 없는 정확수치·기간·비율('입사 후 1~2년'·%·배수)을 단정하면 C4 날조**) / C5 블라인드 위반(공공). <!-- applied: r7-cover-letter / §5 C4 채널 재귀속·파생수치 경계 (R7 cross-vendor PASS) / 2026-06-20 -->
49
- **MAJOR:** M1 제너릭·비고유 지원동기(why-this-company 증명 없음) / M2 핵심 성과에 정량 결과 없음(노력어 의존) / M3 경험을 요구 역량/직무에 미연결(문항 의도 놓침) / M4 두괄식·소제목 약함 / M5 빈 형용사 슬롭·AI 균일 / M6 입사후포부 과대·사업방향 무관.
50
- **MINOR:** 오탈자·맞춤법 / 상한 대비 과소·과패딩 / 수동·약한 동사·"나" 관점(영문) / 항목 중복·불균등 가중 / (영문) 수신자 결함.
56
+ **MAJOR:** M1 제너릭·비고유 지원동기(why-this-company 증명 없음; **지원동기 문항인데 회사가 첫 문단에 등장하지 않음 — 성과 서사가 회사 연결을 마지막 문단으로 밀어냄**) / M2 핵심 성과에 정량 결과 없음(노력어 의존) / M3 경험을 요구 역량/직무에 미연결(문항 의도 놓침) / M4 두괄식·소제목 약함 / M5 빈 형용사 슬롭·AI 균일 / M6 입사후포부 과대·사업방향 무관 / M7 문항에 '겪은 사람만 아는 디테일'(실패한 첫 시도·트레이드오프·구체 사건) 부재(성과·수치 나열만) / M8 디깅으로 확보한 사용자 원문 표현이 3개 미만.
57
+ **MINOR:** 오탈자·맞춤법 / 상한 대비 과소·과패딩 / 수동·약한 동사·"나" 관점(영문) / 항목 중복·불균등 가중 / **같은 대표 성과·수치가 두 문항에 등장(성과 폭이 좁아 보임 — §2-3 문항 간 성과 배분)** / (영문) 수신자 결함.
51
58
  **통과 = CRITICAL 0 + MAJOR 0 + 슬롭/제너릭 없음 + 모든 수치가 저장 데이터에 앵커.**
@@ -15,6 +15,7 @@
15
15
  - **(슬롯) 모르는/미앵커 디테일은 본문에 명시 슬롯으로 남긴다**(유창한 산문으로 지어내지 마라):
16
16
  - `[확인 필요: …]` — 저장 데이터에 있을 법하나 지금 맥락엔 없는 값(예: `[확인 필요: 그 프로젝트의 실제 응답시간 개선 수치]`).
17
17
  - `[저장 데이터에 없음 — 면접 전 본인 경험으로 채우기: …]` — 후보 본인만 아는 사실(예: 구체 실패 일화·당시 팀 규모·반대 의견).
18
+ - **(폴백 문장 기본 동봉) 각 슬롯에는 폴백 문장을 함께 단다** — 사용자가 못 채운 채 면접에 가도 사실 범위 안에서 정직하게 버틸 대체 답을 슬롯 바로 뒤에 붙인다(예: "정확한 수치는 확답 못 드리지만, 설계 경계는 이랬습니다"). 슬롯만 덩그러니 남기면 실전에서 침묵으로 무너진다(측정된 최대 리스크) — 폴백을 일관 동봉하면 못 채운 칸도 버틴다. 폴백도 §0.1 앵커 규칙에 종속(저장 사실·도메인 원칙 범위 안, 새 사실 발명 금지).
18
19
  - **(도메인 원칙은 꼬리, 척추 아님) '왜/어떻게/순서'(의사결정 근거)가 저장 데이터에 없으면** 후보의 실제 판단으로 단정하지 말고 둘 중 하나로 제시: (a) **'면접 전 확인' 질문**으로 분리, (b) **도메인 원칙**으로('일반적으로는 ~ 원칙으로 판단합니다'). 단 도메인 원칙은 *미앵커 칸을 정직하게 받는 fallback*이지 답의 본체가 아니다 — **답의 척추는 항상 ① 후보의 저장 사실 + ② 못 채우는 칸의 명시 슬롯이고, 원칙은 그 뒤 짧은 꼬리 한 문장**이다. 일반 원칙이 문단 절반을 넘거나 사실·슬롯보다 먼저 나오거나 "DB 먼저 캐시 나중"류 교과서 문장으로 답을 대체하면(발명이 아니어도) R1 미달. 원칙엔 "일반적으로는 ~" 표지를 달고, 가능하면 후보의 저장 사실(p99·일 1,000만 건 등)을 원칙의 *적용 대상*으로 끌어와 비제너릭하게 만든다. <!-- applied: R1 principle-is-tail-not-spine / 2026-06-20 -->
19
20
  - **(질문 텍스트도 발명 금지) 발명 금지는 '답변'만이 아니라 네가 직접 *작성하는 질문 텍스트'(꼬리·역·예상질문)에도 똑같이 적용된다(측정된 C4 직격).** 측정에서 모델은 답을 슬롯으로 잘 비워 놓고도 *질문 문장 자체*에 저장에 없는 고유명사·기술명·수치를 끌어와 발명으로 채점됐다(예: "**읽기 복제본(Read Replica)**으로는?", "더 가벼운 큐(**SQS** 등)는?", "트래픽이 **10배**면?", "입사 후 **첫 3~6개월** 성공 기준은?"). **규칙:** 네가 쓰는 질문 문구는 (a) 저장 데이터의 고유명사·기술명·수치, (b) 대상 공고/JD 명시 항목, (c) 후보의 기술 스택 범위(예: 저장이 Java·Spring·MySQL·AWS면 그 안)만 쓴다. 특정 제품명(SQS·Read Replica·Redis)·임의 배수(10배)·임의 기간(3~6개월)을 *예시로라도* 박지 말고 **일반 범주어**로: "다른 읽기 부하 분산 방식이나 더 가벼운 비동기 처리 수단은?", "트래픽이 크게 늘면(배수는 면접관이 제시)", "입사 초기 기대되는 성공 기준은?". <!-- applied: R3 question-text-no-invention / 2026-06-20 -->
20
21
  - **(자가검증 거짓 도장 금지) 본문에 미앵커 디테일을 채워 놓고 끝에 '100% 저장 데이터 앵커' 같은 자체 검증 도장을 찍는 것은 가장 나쁜 결합 실패다** — 검증 문구가 본문과 반대면 그 자체로 FAIL(§5 R10). 괄호 면피 주석으로 가짜 본문을 정당화하지 마라. 자체 검증은 본문을 줄이는 근거이지 정당화 알리바이가 아니다.
@@ -26,12 +26,14 @@
26
26
 
27
27
  - 영문 도입 첫 문장에 (직무명 + 가장 관련 있는 경험 한 가지 + 회사에 대한 구체적 한 줄)을 넣어라. 한국 문항은 결론(직무 강점/지원동기)을 첫 문장에 두는 두괄식으로 시작하라.
28
28
  - 각 강점 주장 뒤에 STAR-lite 한 단락(행동 → **전후 델타형 정량 결과**)을 붙여 증명하라.
29
+ - 복수 문항 자소서면 **대표 성과 1개를 1개 문항에만** 배정해 문항마다 다른 경험·성과 축으로 폭을 넓혀라(밑천이 얕아 보이지 않게).
29
30
  - '왜 이 회사'를 회사 고유 사실(제품·미션·최근 뉴스·인재상)로 못박아라.
30
31
  - 성과를 **전/후 비교(X→Y), 증감률(+N%), 금액·기간**으로 정량화하되, 그 수치가 저장된 이력서·경력 데이터에 근거가 있는지 확인하라.
31
32
  - 약점·실패·갈등 문항은 정량 성과가 아니라 **성찰·개선 행동**으로 답하라(이 문항에 'quantified ≥2'를 강요하지 마라).
32
33
  - 글자수 제한을 적용할 때 **count_mode(공백포함/공백제외/byte)** 를 먼저 확인하라.
33
34
  - 클로징에 명확한 다음 단계(면접 요청/연락 가능 시점)를 한 문장으로 넣어라(로케일상 가능할 때).
34
- - 저장 전 `validate_cover_letter`(현재 구현: 수치 출처·문체 신호 자동 검사 / 글자수 게이트·키워드 커버리지는 Phase B 미구현 — 연결 AI 수동)를 적용한 뒤 save_cover_letter_version으로 보관하라.
35
+ - 저장 전 `validate_cover_letter`(현재 구현: 수치 출처·문체 신호 자동 검사 + **글자수 공백포함/제외/byte 카운트 및 min_chars·max_chars·count_mode 상·하한 충족 여부**(advisory, 차단 아님) / 키워드 커버리지는 미구현 — 연결 AI 수동)를 적용한 뒤 save_cover_letter_version으로 보관하라. 한국 문항형은 문항별 한도로 각 문항을 따로 점검하라.
36
+ - **초안 전에 선택한 경험을 디깅하라** — 사용자에게 가장 막힌 순간·실패한 첫 시도·버린 대안·그때 실제로 나눈 말·수치의 앞뒤 맥락을 묻고, 답변의 **원문 표현을 3개 이상 본문에 살려라**(다듬되 어휘·결 보존). 디깅 원자료는 add_experience로 저장해 재사용한다.
35
37
  - 초안은 get_writing_style_guide의 문체를 적용해 사람이 쓴 듯 자연스럽게 다듬어라.
36
38
 
37
39
  ### Don't
@@ -43,11 +45,13 @@
43
45
  - **다른 공고에 낸 자소서를 회사명·일부 토큰만 바꿔 재사용하지 마라(자기복제).** 사실·수치·보이스는 공고 간 일관되게 두되(억지 변형 금지), 직무 적합 앵글·도입·산문은 공고마다 새로 짠다. 자기복제는 C1 위반이고, 한국은 표절검사(무하유·Copy Killer)·AI 탐지에서 자기표절로 걸린다.
44
46
  - 회사명을 바꿔도 말이 되는 제너릭 지원동기를 쓰지 마라.
45
47
  - 한 통/한 문항에 5~6개 경험을 얕게 나열하지 마라(1~2개 깊게).
48
+ - **복수 문항에 같은 대표 성과·수치를 재활용하지 마라** — 문항마다 다른 경험·성과 축을 쓴다. 저장된 성과가 하나뿐이라 겹칠 수밖에 없으면 문항별 각도를 완전히 분리(한쪽=기술·실행 과정, 다른쪽=동기·의미·배움)하고 같은 수치를 재인용하지 마라.
46
49
  - '규모'(담당 규모·팀 인원·연도)를 '성과'로 위장하지 마라 — 본인 행동의 변화량이 결과다.
47
50
  - 없는 성과·수치·고유명사를 지어내거나 과장하지 마라.
48
51
  - 공고 키워드를 맥락 없이 나열(keyword stuffing)하지 마라.
49
52
  - 나이·성별·사진·가족관계 등 직무무관 개인정보를 넣지 마라.
50
53
  - 한 페이지(또는 지정 글자수 상한/하한)를 벗어나거나 빽빽한 텍스트 벽을 만들지 마라.
54
+ - **디깅 없이, 겪은 사람만 아는 디테일(실패한 첫 시도·트레이드오프·구체 사건) 없이 성과·수치 나열만으로 문항을 채우지 마라** — 이것이 AI 티가 나는 근본 원인이다.
51
55
  - MCP·job_id 같은 기술 용어를 편지 본문/사용자 설명에 노출하지 마라.
52
56
 
53
57
  ### 워크드 예시 (Before → After)
@@ -66,7 +70,7 @@
66
70
 
67
71
  ## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
68
72
 
69
- 각 항목의 `measure.type`을 정직하게 표기한다 — **`regex`/`count`/`ratio`** 는 LLM 없이 lint로 자동 검사 가능, **`ai-judge`** 는 연결 AI의 의미 판단이 필요(정규식 불가). 현재 실재하는 정적 검사기는 `validate_cover_letter`(→lintArtifact)이며 **수치 출처(fabricated 차단) + 문체 신호**만 자동 채점한다 — 글자수 상·하한 게이트·키워드 커버리지 카운트는 **Phase B 미구현**이라 연결 AI가 수동(advisory) 적용한다. `ai-judge` 항목은 연결 AI에게 위임한다. (문서의 `lint_cover_letter`는 Phase B 도구 아이디어 명칭이다.)
73
+ 각 항목의 `measure.type`을 정직하게 표기한다 — **`regex`/`count`/`ratio`** 는 LLM 없이 lint로 자동 검사 가능, **`ai-judge`** 는 연결 AI의 의미 판단이 필요(정규식 불가). 현재 실재하는 정적 검사기는 `validate_cover_letter`(→lintArtifact)이며 **수치 출처(fabricated 차단) + 문체 신호 + 글자수(공백포함/제외/byte 카운트와 min/max 상·하한 충족 여부, advisory)**를 자동 채점한다 — 키워드 커버리지 카운트는 **미구현**이라 연결 AI가 수동 적용한다. `ai-judge` 항목은 연결 AI에게 위임한다. (문서의 `lint_cover_letter`는 Phase B 도구 아이디어 명칭이다.)
70
74
 
71
75
  | ID | 검사 항목 | 합격 기준 | 측정 방법(type · LLM 없이 셀 수 있게) |
72
76
  |----|-----------|-----------|--------------------------------|
@@ -78,7 +82,7 @@
78
82
  | R6 | 회사 고유성 | 회사명/제품/미션 고유명사 ≥2회 + 비종속 검사 | `count`(부분 자동) + `ai-judge`(완전 판정) — 토큰 등장 횟수 ≥2는 카운트 가능. '회사명 placeholder 치환 시 어색해지는 문장 ≥1'은 **연결 AI 판정(위임)** |
79
83
  | R7 | 이력서 비반복 | locale별 임계 이하 | `ratio` — 영문: 단어 5-gram 중복 ≤20%. **한국어: 어절 n-gram은 교착어 특성상 부정확 → 임계 신뢰 낮음, 의미 중복은 `ai-judge` 보조 필요(한계 명시)** |
80
84
  | R8 | STAR 행동+성과 동반 | 행동동사 단락 중 결과 절 동반 ≥1, 단 '규모≠성과' | `regex`(약) + `ai-judge` — 행동동사+결과신호 동시출현은 카운트되나 '우연 동시출현·규모 수치'를 구분하려면 연결 AI가 'R이 본인 행동의 변화량인가' 판정 |
81
- | R9 | 분량/글자수 | locale·count_mode별 상·하한 이내 | `count` — 영문 word_count ≤400. 한국: char_count가 지정 limit 이내 **그리고 하한 이상**. **count_mode(with_space\|no_space\|byte) 입력 필수**(미지정 시 fail-safe로 가장 빡빡한 기준 사용). **⚠ 현재 validate_cover_letter는 charCount 계산만 하고 max/min 게이트는 Phase B 미구현 — 글자수 상·하한 판정은 연결 AI 수동(advisory).** |
85
+ | R9 | 분량/글자수 | locale·count_mode별 상·하한 이내 | `count` — 영문 word_count ≤400. 한국: char_count가 지정 limit 이내 **그리고 하한 이상**. **count_mode(with_space\|no_space\|byte) 입력 필수**(미지정 시 fail-safe로 가장 빡빡한 기준 사용). **✅ validate_cover_letter가 공백포함/제외/byte 카운트 + min_chars·max_chars·count_mode 상·하한 충족 여부(over/under/ok)를 advisory로 반환한다(저장 차단은 안 함). 문항형은 문항별 한도로 따로 호출.** |
82
86
  | R10 | 공고 요구 매핑 | 공고 키워드 ≥3개가 증거와 함께 등장 | `ai-judge`(+count는 설계) — '증거 동반' 판정은 의미 판단이라 위임. **⚠ 키워드 토큰 매치 카운트는 현재 validate_cover_letter에 미구현(Phase B) — 키워드 커버리지·증거 동반 모두 연결 AI 수동.** **`job.requirements`/`keywords`가 비면 skip(N/A)** — 데이터 부재 시 통과/실패 강제 금지 |
83
87
  | R11 | 블라인드 가드레일 | 직무무관 개인정보 패턴 0건 | `regex` — `/(\d{2,3}\s?세|남자|여자|아버지|어머니|출신|본적|사진 첨부)/` 등 NCS 금지정보 매치 = 0(locale='ko') |
84
88
  | R12 | 1인칭 과다 | '저는/I'로 시작하는 문장 비율 ≤40% | `ratio` — 문장 분리 후 시작 토큰이 (저는\|제가\|^I\b)인 비율 계산 ≤0.40 |
@@ -18,6 +18,8 @@
18
18
  - **(사실·수치·고유명사 보존)** 기간·규모·도구·회사명 등 사실·수치·고유명사는 변형 없이 보존하고, 매핑 시 원문 수치를 그대로(substring) 인용한다. 추정·반올림·과장 금지. _(출처: AGENTS.md 보존 규칙; STAR 정량화)_
19
19
  - **(하드 게이트 별도 식별 + ATS knockout 인지)** '경력 N년 이상'·국가자격증·면허·비자·근무지 같은 **하드 게이트**는 별도 표시하고 소프트 스킬로 상쇄되지 않음을 분명히 한다. 이런 binary 요건은 ATS의 knockout/스크리닝 사전질문에서 **실제로 자동탈락되는 경우가 흔하다**(키워드 자동탈락은 드물어도 구조화 사전질문 탈락은 흔하다). 따라서 '자동탈락은 드뭄'을 하드 게이트에 일반화하지 마라. _(출처: O*NET 규제요건; NCS 자격요건; ATS knockout 실무)_
20
20
  - **(범위 한계 명시 + 오버퀄/방향 불일치)** 이 분석은 '증거로 매핑 가능한 하드 요건' 중심이며, 협업·커뮤니케이션 같은 **soft/culture fit는 다루지 않음을 명시**한다(적합도 ≠ 합격가능성). 또한 미달뿐 아니라 **오버퀄(시니어가 주니어 JD 지원)·커리어 방향 불일치**도 리스크로 표기한다. _(출처: 채용 매니저 실무; O*NET은 soft 신호 판정 도구 아님)_
21
+ - **(레벨 전략 — 타깃 레벨 캘리브레이션)** 요건 충족/미충족과 **별개로**, JD가 암시하는 직급(직함·요구 연차·책임 범위·보상 밴드)에 대해 후보가 **언더레벨 / 적정 / 오버레벨** 중 어디인지 판정하고, 경우별 포지셔닝을 제시한다. 언더레벨=궤적·전이가능 스코프·빠른 성장 근거로 보강하고 부족 영역을 솔직히 다룸; 적정=표준 강조; 오버레벨=*왜 이 직급에 지원하는지*(다운시프트 동기)·flight-risk·기대보상 재조정을 선제 해명. 이는 단순 '오버퀄 리스크 플래그'를 넘어 **행동 가능한 전략**으로 적는다. _(출처: career-ops 방법론 차용 — level strategy; 채용 매니저 실무)_
22
+ - **(의사결정 스코어카드 — '추구할 공고인가' 필터)** 요건별 표에 더해, 공고를 **소수의 의사결정 차원으로 압축한 스코어카드**(예: 직무 적합 · 레벨 적합 · 성장/학습 신호 · 보상 신호 · 근무조건(지역·원격) · 안정성/진위)를 상·중·하(또는 A~F)로 제시해 '지원에 시간을 쓸 가치가 있나'를 한눈에 돕는다. **CareerMate는 아무것도 계산하지 않는다** — 판정은 AI가 하고, 보상·문화 같은 차원은 저장된 사실에 없으면 사용자 입력·리서치가 필요함을 명시한다(없는 값을 지어내지 말 것). 오퍼를 *받은 뒤*의 심층 비교는 `offer-evaluation-decision` 플레이북 소관이며, 여기 스코어카드는 *지원 전 필터*다(경계 분리, 중복 금지). 양/질 모두에서 **점수가 낮으면 지원을 권하지 않는** 필터로 쓰되, 단일 합산점수를 '합격 확률'로 착각하지 않게 한다. _(출처: career-ops 방법론 차용 — 가중 차원 스코어링; 본 문서 충족률=맥락 신호 원칙과 정합)_
21
23
 
22
24
  ### Do
23
25