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.
- package/AGENTS.md +2 -2
- package/LICENSE +1 -1
- package/README.md +108 -91
- package/THIRD_PARTY_NOTICES.md +2 -1
- package/bin/careermate.mjs +11 -2
- package/dist/career-os/eop/cover-letter.md +13 -6
- package/dist/career-os/eop/interview-prep.md +1 -0
- package/dist/career-os/knowledge/cover-letter.md +7 -3
- package/dist/career-os/knowledge/fit-matching.md +2 -0
- package/dist/career-os/knowledge/verifiers/ai-detection-risk.md +57 -0
- package/dist/career-os/knowledge/verifiers/human-voice.md +7 -2
- package/dist/career-os/knowledge/verifiers/truthfulness.md +1 -0
- package/dist/doctor.mjs +19760 -1018
- package/dist/mcp.mjs +19783 -1035
- package/dist/migrate.mjs +289 -20
- package/dist/public/i18n/en/applications.js +19 -0
- package/dist/public/i18n/en/common.js +10 -0
- package/dist/public/i18n/en/documents.js +0 -10
- package/dist/public/i18n/en/home.js +5 -0
- package/dist/public/i18n/en/jobs.js +18 -1
- package/dist/public/i18n/en/profile.js +0 -5
- package/dist/public/i18n/en/settings.js +5 -2
- package/dist/public/i18n/ko/applications.js +19 -0
- package/dist/public/i18n/ko/common.js +9 -0
- package/dist/public/i18n/ko/documents.js +0 -10
- package/dist/public/i18n/ko/home.js +5 -0
- package/dist/public/i18n/ko/jobs.js +18 -1
- package/dist/public/i18n/ko/profile.js +0 -5
- package/dist/public/i18n/ko/settings.js +5 -2
- package/dist/public/lib.js +101 -0
- package/dist/public/pages/applications.js +95 -15
- package/dist/public/pages/documents.js +20 -14
- package/dist/public/pages/home.js +38 -6
- package/dist/public/pages/interview.js +11 -4
- package/dist/public/pages/jobs.js +71 -1
- package/dist/public/pages/profile.js +2 -3
- package/dist/public/pages/settings.js +2 -2
- package/dist/public/styles.css +52 -4
- package/dist/web.mjs +19001 -758
- package/docs/FAQ.md +13 -3
- package/docs/MCP_TOOLS.md +32 -12
- package/docs/career-os/eop/cover-letter.md +13 -6
- package/docs/career-os/eop/interview-prep.md +1 -0
- package/docs/career-os/knowledge/cover-letter.md +7 -3
- package/docs/career-os/knowledge/fit-matching.md +2 -0
- package/docs/career-os/knowledge/verifiers/ai-detection-risk.md +57 -0
- package/docs/career-os/knowledge/verifiers/human-voice.md +7 -2
- package/docs/career-os/knowledge/verifiers/truthfulness.md +1 -0
- package/package.json +5 -2
- package/packages/core/src/index.ts +2 -0
- package/packages/core/src/jobsearch.ts +190 -0
- package/packages/core/src/offers.ts +41 -0
- package/packages/core/src/services.ts +29 -3
- package/packages/core/src/summary.ts +431 -9
- package/packages/core/src/verify/charcount.ts +87 -0
- package/packages/core/src/verify/index.ts +1 -0
- package/packages/core/src/verify/lint.ts +5 -0
- package/packages/db/src/connection.ts +70 -2
- package/packages/db/src/index.ts +1 -0
- package/packages/db/src/repositories.ts +179 -13
- package/packages/db/src/schema.ts +169 -8
- package/packages/exporters/src/docx.ts +165 -0
- package/packages/exporters/src/index.ts +142 -9
- package/packages/exporters/src/markdown.ts +16 -11
- package/packages/knowledge/src/index.ts +8 -3
- package/packages/mcp-tools/src/result.ts +9 -0
- package/packages/mcp-tools/src/tools.ts +303 -60
- package/packages/parsers/src/documents.ts +7 -1
- package/packages/prompts/src/humanize.ts +4 -0
- package/packages/shared/src/schemas.ts +198 -0
- package/scripts/init.ts +7 -0
package/docs/FAQ.md
CHANGED
|
@@ -108,12 +108,22 @@ AI에게 "이 공고 저장하고 분석해줘"라고 하면서 URL이나 본문
|
|
|
108
108
|
|
|
109
109
|
### 내 데이터는 어디에 저장되나요?
|
|
110
110
|
사용자 컴퓨터의 `~/.careermate`(Windows: `%USERPROFILE%\.careermate`)에만 저장됩니다.
|
|
111
|
-
대시보드 **설정 > 데이터 저장 위치**에서 정확한 경로를 볼 수 있습니다.
|
|
112
|
-
|
|
111
|
+
대시보드 **설정 > 데이터 저장 위치**에서 정확한 경로를 볼 수 있습니다. CareerMate가
|
|
112
|
+
외부 서버로 개인 데이터를 보내는 일은 없습니다(외부 호출은 선택적 버전 확인과 공고
|
|
113
|
+
검색 시 검색 키워드뿐).
|
|
114
|
+
|
|
115
|
+
### AI와 대화하면 내 데이터는 어디로 가나요?
|
|
116
|
+
CareerMate 도구의 응답(프로필·이력서·자소서 등)은 **당신이 연결한 AI 클라이언트**
|
|
117
|
+
(Claude·Codex 등)에 전달되어 그 AI가 분석·작성에 사용합니다 — 그 데이터의 처리에는
|
|
118
|
+
**해당 AI 서비스의 개인정보 정책**이 적용됩니다. CareerMate 자체는 그 어떤 서버로도
|
|
119
|
+
데이터를 보내지 않지만, "AI에게 보여준 내용"은 그 AI 서비스로 간다는 점은 알아두세요.
|
|
120
|
+
민감한 항목은 저장하지 않거나, AI 서비스의 학습 제외(opt-out) 설정을 확인하면 됩니다.
|
|
113
121
|
|
|
114
122
|
### 백업하거나 전부 삭제하려면?
|
|
115
123
|
대시보드 **설정 > 백업 / 내보내기**에서 백업 생성·전체 JSON 내보내기를, **위험 구역**에서
|
|
116
|
-
전체 초기화를 할 수 있습니다(초기화 직전 자동 백업).
|
|
124
|
+
전체 초기화를 할 수 있습니다(초기화 직전 자동 백업). **주의:** 초기화해도 자동 백업 파일은
|
|
125
|
+
데이터 폴더의 `backups/`에 남습니다 — PC 양도 등으로 흔적 없이 지우려면 초기화 후
|
|
126
|
+
`~/.careermate` 폴더 자체(또는 그 안의 `backups/`)를 직접 삭제하세요.
|
|
117
127
|
|
|
118
128
|
---
|
|
119
129
|
|
package/docs/MCP_TOOLS.md
CHANGED
|
@@ -16,7 +16,7 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
16
16
|
|
|
17
17
|
| 읽기전용(✅) 도구 | 쓰기/부수효과(✏️) 도구 |
|
|
18
18
|
| --- | --- |
|
|
19
|
-
| `read_document`, `read_inbox`, `get_onboarding_status`, `get_profile`, `get_resumes`, `get_experiences`, `get_projects`, `get_skills`, `get_cover_letters`, `get_job_posting`, `list_jobs`, `get_application_context`, `list_recent_activity`, `get_workflow_guide`, `get_playbook`, `get_verifier`, `validate_cover_letter`, `get_writing_style_guide`, `check_for_update` | `open_inbox`, `save_profile`, `add_resume`, `delete_resume`, `add_experience`, `delete_experience`, `add_project`, `delete_project`, `add_skill`, `delete_skill`, `save_cover_letter_version`, `delete_cover_letter`, `set_verify_mode`, `save_job_posting`, `delete_job_posting`, `save_fit_analysis`, `update_application_status`, `save_interview_prep`, `export_cover_letter`, `export_resume`, `export_profile`, `open_dashboard`, `open_application`, `update_careermate` |
|
|
19
|
+
| `read_document`, `read_inbox`, `get_onboarding_status`, `get_profile`, `get_resumes`, `get_experiences`, `get_projects`, `get_skills`, `get_cover_letters`, `get_job_posting`, `list_jobs`, `prescreen_job`, `search_jobs`, `compare_offers`, `get_offer`, `get_application_context`, `list_recent_activity`, `get_followups`, `get_pipeline_stats`, `get_workflow_guide`, `get_playbook`, `get_verifier`, `validate_cover_letter`, `get_writing_style_guide`, `check_for_update` | `open_inbox`, `save_profile`, `add_resume`, `delete_resume`, `add_experience`, `delete_experience`, `add_project`, `delete_project`, `add_skill`, `delete_skill`, `save_cover_letter_version`, `delete_cover_letter`, `set_verify_mode`, `save_job_posting`, `delete_job_posting`, `save_fit_analysis`, `update_application_status`, `save_interview_prep`, `save_offer`, `export_cover_letter`, `export_resume`, `export_profile`, `open_dashboard`, `open_application`, `update_careermate` |
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -141,9 +141,11 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
141
141
|
|
|
142
142
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
143
143
|
| --- | --- | --- | --- | --- | --- |
|
|
144
|
-
| `
|
|
144
|
+
| `search_jobs` | 키워드로 무인증 공개 잡보드(원티드·점핏)에서 공고를 *가져옴*(저장은 안 함) | `keyword`(필수), `sources?`, `limit?`(기본 10) | `{ query, results[](회사·직무·url·지역·경력·기술·마감), providers[] }` | 사용자가 "○○ 공고 찾아줘"라고 할 때. 결과를 보여주고 **고른 것만** save_job_posting | ✅ |
|
|
145
|
+
| `save_job_posting` | 채용공고 저장(있으면 갱신). 저장 시 지원(application) 항목 자동 생성 | `company`, `position`(필수), `url?`, `location?`, `employment_type?`, `description?`, `requirements?`, `keywords?`, `deadline?`, `source?`, `questions?`(회사 지정 자소서 문항·글자수: `question`·`min_chars`·`max_chars`·`count_mode`), `schedule?`(전형 일정: `label`·`date`(YYYY-MM-DD) 필수·`time`(HH:MM)·`note`) | 저장된 `JobRecord`(`job_id` 포함) | 공고를 DB에 등록/갱신할 때 | ✏️ |
|
|
145
146
|
| `get_job_posting` | 공고 1건 상세 조회 | `job_id` | `{ job, fit, application, cover_letters, interview }` | 한 공고의 분석·상태·자소서·면접 자료를 한 번에 볼 때 | ✅ |
|
|
146
147
|
| `list_jobs` | 저장된 모든 공고를 지원 상태·적합도 점수와 함께 목록화 | 없음 | 공고 메타 포함 배열 | 전체 공고를 훑어볼 때 | ✅ |
|
|
148
|
+
| `prescreen_job` | 공고 키워드 ↔ 보유 기술 목록 **+ 대표 이력서 본문** 겹침을 결정론으로 계산(값싼 사전 필터, LLM 없음) | `job_id` | `{ job_keywords, matched[], missing[], coverage, user_skill_count, resume_matched[], combined_matched[], combined_coverage, resume_checked }` | 본격 적합도 분석 전 "깊게 볼 가치 있나" 빠르게 가늠할 때(여러 공고 우선순위). combined_coverage가 낮은데 보유 역량이면 이력서 보강 신호 | ✅ |
|
|
147
149
|
| `delete_job_posting` | 채용공고 삭제 | `job_id`, `confirm:"DELETE"` | 삭제 결과 | 사용자가 목록에서 삭제 대상을 확인한 뒤 | ✏️ |
|
|
148
150
|
|
|
149
151
|
- `url`이 같으면 중복 생성 없이 갱신됩니다.
|
|
@@ -153,6 +155,19 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
153
155
|
|
|
154
156
|
---
|
|
155
157
|
|
|
158
|
+
## 5-1. 오퍼 (Offers)
|
|
159
|
+
|
|
160
|
+
받은 채용 제안(오퍼)을 공고에 연결해 저장·비교합니다(공고당 1건). 점수·최종평은 **연결된 AI가 저장 시 작성**하고(CareerMate엔 LLM 없음), 대시보드는 그걸 렌더링합니다. 정밀 비교는 `compare_offers` 데이터를 받아 AI가 `offer-evaluation`·`salary-negotiation` 관점으로 수행합니다.
|
|
161
|
+
|
|
162
|
+
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
163
|
+
| --- | --- | --- | --- | --- | --- |
|
|
164
|
+
| `save_offer` | 오퍼 저장(공고당 1건, 갱신). 현금성은 만원 단위 숫자, AI가 `ai_score`·`verdict`(최종평) 함께 작성. `offer_status`로 진행 상태(open/accepted/declined)를 기록 — 거절해도 삭제하지 않고 조건 기록으로 보존 | `job_id`(필수), `offer_status?`(open/accepted/declined), `base_salary?`·`bonus_amount?`·`welfare_amount?`·`signing_amount?`(만원), `equity_note?`, `comp_note?`, `work_arrangement?`, `contract_type?`, `accept_deadline?`, `ai_score?`, `verdict?`, `notes?` | 저장된 오퍼(+`total_comp_annual_est` 결정론 합산). accepted 저장 시 지원 상태(최종 합격) 갱신 제안 동봉 | 사용자가 오퍼를 받아 저장·평가할 때, 또는 "그 오퍼 거절했어/수락했어"라고 할 때 | ✏️ |
|
|
165
|
+
| `compare_offers` | 저장된 모든 오퍼를 점수순으로 회사·직무·현금성 총액추정·최종평·`offer_status`와 함께 반환 — 비교는 진행 중(open) 위주, 지난 오퍼는 과거 조건 기준점으로만 | 없음 | `OfferWithJob[]`(점수 desc) | "오퍼 비교해줘" 또는 여러 오퍼를 함께 판단할 때 | ✅ |
|
|
166
|
+
| `get_offer` | 특정 공고의 오퍼 1건 조회 | `job_id` | 오퍼 또는 `null` | 한 공고의 오퍼를 확인할 때 | ✅ |
|
|
167
|
+
|
|
168
|
+
- `total_comp_annual_est`(연 현금성 추정) = 기본급 + 성과급 + 복지(일시금 제외), CareerMate가 결정론으로 합산. 없으면 `null`.
|
|
169
|
+
- 회사 평판은 `save_job_posting`의 `reputation`에 저장해두면 오퍼 판단·면접에 함께 활용됩니다.
|
|
170
|
+
|
|
156
171
|
## 6. 적합도 (Fit Analysis)
|
|
157
172
|
|
|
158
173
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
@@ -169,7 +184,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
169
184
|
|
|
170
185
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
171
186
|
| --- | --- | --- | --- | --- | --- |
|
|
172
|
-
| `update_application_status` | 지원 상태 변경. `document_passed` 이상이면 면접 준비를 제안하는 힌트 동봉 | `job_id`, `status`, `note?` | 변경 결과(`hint
|
|
187
|
+
| `update_application_status` | 지원 상태 변경. `document_passed` 이상이면 면접 준비를 제안하는 힌트 동봉. `rejected`로 바꿀 때는 탈락 회고로 `rejected_stage`(서류/인적성/면접/최종/기타)를 함께 기록 — 없으면 기록을 유도하는 `suggested_next_action` 동봉 | `job_id`, `status`, `note?`, `rejected_stage?` | 변경 결과(`hint`·회고 유도 포함 가능) | 지원 진행 단계가 바뀔 때 | ✏️ |
|
|
173
188
|
|
|
174
189
|
지원 상태 8단계(`APPLICATION_STATUSES`):
|
|
175
190
|
|
|
@@ -192,14 +207,15 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
192
207
|
|
|
193
208
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
194
209
|
| --- | --- | --- | --- | --- | --- |
|
|
195
|
-
| `save_interview_prep` | 예상
|
|
210
|
+
| `save_interview_prep` | 면접 *준비*(예상 질문·STAR·자기소개)와 면접 *후 디브리프*를 한 공고에 저장(같은 공고면 갱신) | `job_id`(필수), `questions?`, `star_guides?`, `self_introduction?`, `notes?`, `debrief?` | 저장된 `InterviewPrepRecord`(질문 수 포함) | 사용자가 공고 기준 면접 준비를 요청했을 때, 또는 면접을 본 뒤 디브리프를 남길 때 | ✏️ |
|
|
196
211
|
|
|
197
212
|
입력 구조(`InterviewPrepInputSchema`):
|
|
198
213
|
|
|
199
|
-
- `questions[]`: `{ question, intent?(질문 의도), followups?(예상 꼬리 질문), answer_outline?(답변 가이드/핵심 포인트) }`
|
|
214
|
+
- `questions[]`: `{ question, category?('technical'|'behavioral'), intent?(질문 의도), followups?(예상 꼬리 질문), answer_outline?(답변 가이드/핵심 포인트) }`
|
|
200
215
|
- `star_guides[]`: `{ question, situation?, task?, action?, result? }`
|
|
201
216
|
- `self_introduction`: 1분 자기소개 초안
|
|
202
217
|
- `notes`: 면접 후기/메모
|
|
218
|
+
- `debrief`(면접 후): `{ asked_questions?(실제로 받은 질문), went_well?, to_improve?, next_round_focus?(다음 라운드 대비), sentiment?('positive'|'neutral'|'negative'), interviewed_at? }` — 면접 전 준비와 한 엔티티에 함께 쌓이며, 부분 저장 시 기존 디브리프 필드와 **병합**(덮어쓰지 않음). 다음 라운드 준비·일관성 점검에 활용.
|
|
203
219
|
|
|
204
220
|
---
|
|
205
221
|
|
|
@@ -207,11 +223,13 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
207
223
|
|
|
208
224
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
209
225
|
| --- | --- | --- | --- | --- | --- |
|
|
210
|
-
| `export_cover_letter` | 자기소개서를 Markdown
|
|
211
|
-
| `export_resume` | 저장된 이력서·경력기술서 등 문서를 Markdown
|
|
212
|
-
| `export_profile` | 프로필·경력·프로젝트·보유 기술을 한 장의 이력서 형식으로 모아 Markdown
|
|
226
|
+
| `export_cover_letter` | 자기소개서를 Word(`.docx`)·Markdown·인쇄용 HTML 파일로 데이터 폴더 `exports/`에 저장 | `cover_letter_id`, `format?`(`md`(기본)/`html`/`docx`) | `{ path, filename, content }`(docx는 `content`가 안내문, 실제 파일은 `path`) | 사용자가 "자소서 파일로 받고 싶어"라고 할 때(ATS 제출이면 `docx`) | ✏️ |
|
|
227
|
+
| `export_resume` | 저장된 이력서·경력기술서 등 문서를 Word(`.docx`)·Markdown·인쇄용 HTML 파일로 `exports/`에 저장 | `document_id`, `format?`(`md`(기본)/`html`/`docx`) | `{ path, filename, content }`(docx는 `content`가 안내문) | 공고 맞춤 이력서를 `add_resume`로 저장한 뒤 "이력서 파일로 받고 싶어"라고 할 때(ATS 제출이면 `docx`) | ✏️ |
|
|
228
|
+
| `export_profile` | 프로필·경력·프로젝트·보유 기술을 한 장의 이력서 형식으로 모아 Word(`.docx`)·Markdown·인쇄용 HTML·JSON Resume 파일로 `exports/`에 저장 | `format?`(`md`(기본)/`html`/`docx`/`json`) | `{ path, filename, content }`(docx는 `content`가 안내문) | 사용자가 "내 프로필을 이력서로 뽑아줘"라고 할 때, 또는 다른 이력서 도구·테마와 연동할 표준 데이터가 필요할 때(`json`) | ✏️ |
|
|
213
229
|
|
|
230
|
+
- Word(`.docx`)는 ATS 제출에 알맞은 단일 컬럼 표준 레이아웃입니다(회사 지정 양식 채우기는 아직 지원하지 않습니다).
|
|
214
231
|
- HTML은 인쇄용으로, 브라우저에서 PDF로 저장할 수 있습니다.
|
|
232
|
+
- `export_profile`의 `json`은 [JSON Resume](https://jsonresume.org) v1.0.0 표준 형식입니다 — 100+ 테마(HTML/PDF 렌더)·다른 이력서/ATS 도구와 상호운용됩니다. 빈 필드는 생략하고 저장된 날짜는 그대로 내보냅니다.
|
|
215
233
|
- 대시보드의 Documents·Profile 페이지에서 직접 다운로드할 수도 있습니다.
|
|
216
234
|
|
|
217
235
|
---
|
|
@@ -233,6 +251,8 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
233
251
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
234
252
|
| --- | --- | --- | --- | --- | --- |
|
|
235
253
|
| `list_recent_activity` | 최근 활동 내역(공고 저장, 적합도 분석, 자소서 버전, 상태 변경, 면접 준비 등) 조회 | `limit?`(기본 20) | `ActivityRecord[]` | "최근에 뭐 했지?" 또는 이어서 작업할 맥락이 필요할 때 | ✅ |
|
|
254
|
+
| `get_followups` | 지금 챙길 항목 한 번에 — 무응답 지원(지원 후 무응답·서류합격 후 일정대기·면접 후 결과대기)·임박/지난 마감(지원 전 단계)·면접 준비 누락 공고·오늘~7일 내 전형 일정(D-day)·같은 날짜 일정 충돌. 지원 항목엔 결정론 팔로업 타이밍(`followup_timing` due=5~7영업일·overdue=8영업일+, `business_days_since`)과 45일+ 무응답 시 `suggest_on_hold` | 없음 | `{ today, followups[]{…, followup_timing?, business_days_since?, suggest_on_hold?}, deadlines[], interview_todo[], upcoming_schedule[]{ job_id, company, position, label, date, time?, d_day }, schedule_conflicts[]{ date, items[] } }` | "내 지원 현황 어때?/뭐 챙겨야 해?/이번 주 일정 뭐 있어?/언제 팔로업?" 또는 세션 이어가며 놓친 것 점검할 때 | ✅ |
|
|
255
|
+
| `get_pipeline_stats` | 지원 파이프라인 분석 — 현재 상태 분포·단계별 도달 깔때기(지원→서류→면접→최종, 상태 변경 이력 복원)·통과율·결과 요약·탈락 단계 분포(`rejected_by_stage`·`rejected_unrecorded`) | 없음 | `{ total, by_status[], funnel, rates, outcomes, rejected_by_stage[], rejected_unrecorded, note }` | "내 합격률/지원 통계 어때?", "어느 단계에서 떨어져?"라고 물을 때(비율은 설명용, 표본 작으면 추세만) | ✅ |
|
|
236
256
|
|
|
237
257
|
---
|
|
238
258
|
|
|
@@ -248,15 +268,15 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
248
268
|
|
|
249
269
|
## 12-1. 전문가 플레이북·검증 루브릭 (Career-OS)
|
|
250
270
|
|
|
251
|
-
`get_workflow_guide`가 안내한 "전문가 실행 절차(EOP)"를 실제로 받아 적용하는 serve 도구입니다. CareerMate는 `docs/career-os/{eop,knowledge}`의 전문가 지식(16개 도메인 플레이북 +
|
|
271
|
+
`get_workflow_guide`가 안내한 "전문가 실행 절차(EOP)"를 실제로 받아 적용하는 serve 도구입니다. CareerMate는 `docs/career-os/{eop,knowledge}`의 전문가 지식(16개 도메인 플레이북 + 7개 검증 루브릭)을 그대로 돌려주고, 작성·점검·판단은 연결된 AI가 합니다(내부 LLM 없음). 지침 원문은 사용자에게 노출하지 말고 결과물에만 반영하세요.
|
|
252
272
|
|
|
253
273
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
254
274
|
| --- | --- | --- | --- | --- | --- |
|
|
255
275
|
| `get_playbook` | 도메인별 작성·판단 원칙·Do/Don't·Before→After·자가검증 포인트(시니어 전문가 기준) | `domain`(16개 enum) | `{ domain, content }` | 산출물을 손보기 직전, `get_workflow_guide`가 안내한 도메인을 받아 적용할 때 | ✅ |
|
|
256
|
-
| `get_verifier` | 검증기 루브릭(점검 항목·합격 기준·세는 방법). 실제 점검·판정은 AI가 직접 수행 | `id`(
|
|
276
|
+
| `get_verifier` | 검증기 루브릭(점검 항목·합격 기준·세는 방법). 실제 점검·판정은 AI가 직접 수행 | `id`(7개 enum) | `{ id, content }` | 산출물을 `save_*`로 저장하기 직전 자가검증할 때 | ✅ |
|
|
257
277
|
|
|
258
278
|
- `get_playbook` 도메인(16): `resume`, `ats`, `cover-letter`, `fit-matching`, `human-writing`, `company-research`, `recruiter-screen`, `interview-behavioral`, `interview-technical`, `salary-negotiation`, `offer-evaluation-decision`, `rejection-triage-iteration`, `linkedin-profile`, `portfolio`, `networking-referrals`, `onboarding-first-90-days`.
|
|
259
|
-
- `get_verifier` id(
|
|
279
|
+
- `get_verifier` id(7): `truthfulness`, `consistency`, `recency-staleness`, `responsiveness-on-target`, `ats-compat`, `human-voice`, `ai-detection-risk`(한국 AI-자소서 탐지 시장 전용 — 진정성·면접 방어가능성·자기복제 점검).
|
|
260
280
|
- 권장 흐름: `get_application_context`(맥락 + 추천 경로) → `get_workflow_guide(workflow_id)`(EOP + 적용할 플레이북/검증기 순서) → `get_playbook(domain)`(작성) → `get_verifier(id)`(저장 전 자가검증) → `save_*`(저장).
|
|
261
281
|
- 지식 정본은 `docs/career-os/`이며, 이 지식층의 설계·아직 구현하지 않은 범위(B-2: det 게이트·점수 계산)는 [`docs/career-os/implementation/README.md`](career-os/implementation/README.md)를 참고하세요.
|
|
262
282
|
|
|
@@ -268,7 +288,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
|
|
|
268
288
|
|
|
269
289
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
270
290
|
| --- | --- | --- | --- | --- | --- |
|
|
271
|
-
| `validate_cover_letter` | 저장하지 않고 미리 점검만 — 저장 시 차단될 항목·문체 신호를
|
|
291
|
+
| `validate_cover_letter` | 저장하지 않고 미리 점검만 — 저장 시 차단될 항목·문체 신호를 보여줌. 글자수도 3기준으로 세고 한도 충족 여부 반환 | `text`(필수), `job_id?`, `strict?`, `min_chars?`, `max_chars?`, `count_mode?` | 점검 리포트(`blocking[]`·신호·수치 출처 분석·`charLimit`) | `save_cover_letter_version`으로 저장하기 직전 미리 확인할 때. 공고 `questions`에 문항별 한도가 있으면 그 값을 넘겨 문항마다 점검 | ✅ |
|
|
272
292
|
| `set_verify_mode` | 저장 전 자동 점검의 엄격도 변경(기본/엄격). 엄격 모드는 이력서 본문에 근거 없는 수치까지 차단 | `strict`(true=엄격, false=끄기) | `{ strict }` | 사용자가 "엄격하게 봐줘"에 동의해 모드를 바꿀 때(이번 한 건만이면 모드 대신 `strict:true`를 인자로) | ✏️ |
|
|
273
293
|
|
|
274
294
|
- `validate_cover_letter`의 `blocking`이 비어 있지 않으면, 같은 본문을 `save_cover_letter_version`으로 저장할 때도 막힙니다(의도한 값이면 `force:true`로 저장).
|
|
@@ -19,17 +19,22 @@
|
|
|
19
19
|
|
|
20
20
|
## 2. 분석·작성 절차
|
|
21
21
|
1. **회사 리서치**(company-research): 미션·사업·제품·최근 활동·인재상 → 본인과 연결할 고유 포인트 확보.
|
|
22
|
-
2. **문항 의도 해석:** 지원동기=여기 오게 한 *구체 경험*(표면 관심 X)
|
|
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
|
-
|
|
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
|
-
|
|
29
|
-
6.
|
|
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 증명
|
|
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`(현재 구현: 수치 출처·문체 신호 자동 검사
|
|
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 차단) + 문체
|
|
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로 가장 빡빡한 기준 사용).
|
|
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
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# AI 탐지 리스크 (AI-detection-risk) — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 한국 채용 산출물(특히 자기소개서·경력기술서)을 **저장 직전** 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사·판정은 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
> **역할 경계 (중요).** 이 루브릭의 목적은 **탐지기를 속이는 것이 아니다.** "GPT킬러를 우회하는 법"을 가르치지 않는다 — 그것은 기만이고, 한국 HR 현실에서도 실패하는 전략이다. 이 루브릭이 보장하려는 것은 **글이 실제로 지원자 본인의 것이고(진정성), 면접에서 한 문장 한 문장 설명할 수 있는가(방어가능성)** 다. 그 결과로 탐지 리스크는 *부차적으로* 낮아진다. 즉 검사 대상은 "AI 티"가 아니라 **"내 것이 아닌·설명 못 하는 부분"** 이다. (문체의 "AI 티" 자체는 짝 검증기 [`human-voice.md`](./human-voice.md)가 담당한다 — 둘은 역할이 다르다.)
|
|
6
|
+
|
|
7
|
+
## 1. 목적 — 왜 한국 시장에서 이게 별도 검증기인가
|
|
8
|
+
|
|
9
|
+
한국 채용은 자기소개서 비중이 크고, **AI 작성 탐지가 제도화**돼 있다. 검증된 시장 사실:
|
|
10
|
+
|
|
11
|
+
- 2025년 제출 자소서의 **약 64%가 AI 작성으로 추정**됐고(전년 48.5%), 전 문항 AI 작성도 20.6%로 늘었다.
|
|
12
|
+
- **무하유 GPT킬러**(문장 구조·확률분포·패턴 기반 AI 생성률 산출)는 탐지 정확도를 **최대 98%**로 표방하며 LG전자·롯데·KB국민은행·국민연금공단 등이 도입했다. 표절 검사 **카피킬러**는 국내 대학 96%가 쓴다. B2B 솔루션 **프리즘(PRISM)**은 마스킹+표절+AI 탐지+면접질문 생성을 묶는다.
|
|
13
|
+
- 기업의 **65.4%가 AI 자소서 적발 시 불이익**을 준다고 답했다.
|
|
14
|
+
|
|
15
|
+
그런데 **탐지 = 즉시 탈락은 아니다.** HR 담당자들의 공통 입장은 *"AI를 썼느냐보다, 그 내용을 면접에서 본인이 설명할 수 있느냐"* 다. 동시에 탐지기는 **신뢰성 한계**가 분명하다 — OpenAI는 자사 AI 분류기를 2023년 정확도 부족으로 폐기했고, Stanford 연구는 탐지기가 **비원어민 글을 거짓양성으로 과도하게 적발**한다고 보고했다. 즉 탐지기는 틀릴 수 있고, 방어선은 "탐지를 피하는 글"이 아니라 **"누가 봐도 내 경험에서 나온, 내가 설명 가능한 글"** 이다.
|
|
16
|
+
|
|
17
|
+
따라서 이 검증기는 다음을 본다: ① 본문의 모든 구체 주장이 **지원자의 저장된 사실(이력서·경력·프로젝트)에 앵커**되는가, ② 면접에서 **꼬리질문에 답할 수 있는** 구체성(상황·행동·수치)이 있는가, ③ 일반론·차용 가능한 문장(회사명만 바꾸면 어디든 통하는 글)이 과하지 않은가.
|
|
18
|
+
|
|
19
|
+
## 2. 검사 항목
|
|
20
|
+
|
|
21
|
+
> 적용 단위: 한 산출물(자소서 1편/문항, 경력기술서 1부). "주장"은 지원자가 자신에 대해 단언하는 문장(역량·성과·경험·동기)을 가리킨다.
|
|
22
|
+
|
|
23
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게) |
|
|
24
|
+
|----|------|-----------|------------------------|
|
|
25
|
+
| D1 | 구체 주장의 앵커링 | 본문의 모든 성과·경험 주장이 저장된 사실(이력서 본문·경력·프로젝트)에 **추적 가능**. 미앵커 주장 0건 | 각 주장 문장에서 (회사/역할/수치/기술/사건) 토큰 추출 → 저장 코퍼스에 존재하는지 대조. 어디에도 없는 주장 수 = 0. (수치는 결정론 점검 `validate_cover_letter`의 `fabricated`/`unverified`와 교차) |
|
|
26
|
+
| D2 | 면접 방어가능성 | 각 핵심 일화가 **꼬리질문 1개에 답할 구체(상황·내 행동·결과)** 를 담음. "설명 못 할" 일반 문장 비율 ≤ 20% | 일화 문장에 (구체 행위 동사+목적어) 또는 (수치/기간/규모)가 있는지 확인 → 없는 문장 비율. "면접관이 '구체적으로 뭘 하셨죠?'라 물으면 막히는 문장" 카운트 |
|
|
27
|
+
| D3 | 차용 가능성(swappability) | 회사명·직무명을 **다른 공고로 바꿔도 그대로 통하는** 일반 문장이 과하지 않음(도입·지원동기에서 특히). 전체의 30% 미만 | 회사 고유 사실(제품·인재상·핵심가치·최근 이슈)·지원자 고유 사실 중 **어느 쪽도 참조하지 않는** 문장 비율. (공고에 `company_overview`/`talent_profile`/`core_values`가 저장돼 있으면 그 정렬 여부로 본다) |
|
|
28
|
+
| D4 | 일반론·교과서 정의 밀도 | "○○란 ~이다", "급변하는 시대에는~" 류 **누구나 쓸 수 있는 정의·시류 진술**이 과하지 않음. 100문장당 3개 이하 | 결정론 lint의 `cliche`·`generic_opener`·`hype` 신호 수를 참조 + 정의형 문장("~란 …입니다") 패턴 카운트 |
|
|
29
|
+
| D5 | 자기복제(carryover) | 다른 공고용 기존 자소서에서 **회사명만 바꾼 문단·문장**을 그대로 옮겨오지 않음(끌개 복제 방지). verbatim 재사용 문장 0건, 산문 carryover ≤ 20% | 기존 자소서(맥락에 포함)와 신규 본문을 문장 단위로 대조 → 사실 일관 영역(보이스·수치)은 허용하되, *직무 적합 앵글·도입·지원동기 산문*의 verbatim 일치 수와 carryover 비율 측정. (짝 가드: 자기복제 방지 EOP) |
|
|
30
|
+
| D6 | 탐지기 한계 인지(거짓확신 방지) | 결과 보고 시 "탐지 통과=합격"·"탐지=탈락"의 **양쪽 거짓확신을 두지 않음** | 점검 결론에 (a) 탐지기는 틀릴 수 있음(비원어민 거짓양성) (b) 최종 관문은 면접 설명력임을 명시했는지 확인(서술 점검) |
|
|
31
|
+
|
|
32
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
33
|
+
|
|
34
|
+
- **D1 미앵커 주장(critical):** 저장된 사실에 없는 성과·경험은 (a) 사용자에게 사실 여부를 확인해 근거를 보강하거나 (b) 문장을 제거한다. **임의로 그럴듯하게 채우지 않는다**(환각 금지). 수치는 결정론 게이트(`validate_cover_letter`)와 교차해 차단.
|
|
35
|
+
- **D2 방어 불가 문장(critical):** "막히는 문장"은 그 일화의 *내 행동·구체 결과*로 다시 쓴다. 채울 구체가 없으면 그 일화 자체를 더 설명 가능한 다른 경험으로 교체. 동반 면접 준비(`save_interview_prep`)로 꼬리질문 답을 미리 준비하도록 연결.
|
|
36
|
+
- **D3 차용 가능 문장(warn→fix):** 회사 고유 사실(저장된 `company_overview`/`talent_profile`/`core_values` 또는 사용자 리서치)이나 지원자 고유 사실로 재작성. 둘 다 없으면 사용자에게 회사 리서치·본인 일화를 청한다.
|
|
37
|
+
- **D4 일반론 과다(warn):** 정의·시류 진술을 지원자 경험 진술로 치환. 글자수가 빠듯하면 일반론부터 덜어낸다.
|
|
38
|
+
- **D5 자기복제(critical):** 사실·수치·보이스는 일관 유지하되, **직무 적합 앵글·도입·지원동기는 공고별로 새로 쓴다.** 같은 결함이 2번 고쳐도 남으면 멈추고 사용자에게 확인(무한정 변형으로 사실 왜곡 금지).
|
|
39
|
+
- **D6 보고 프레이밍:** 사용자에게 결과를 전할 때 탐지 점수를 단정하지 말고, "탐지기는 오탐이 있으며 핵심은 면접 설명력"이라는 맥락과 함께 전한다.
|
|
40
|
+
- **종료 조건:** D1·D2·D5 critical 0건 + D3·D4 사용자 확인 완료. 통과 시 `save_cover_letter_version`/`add_resume`로 저장하고 대시보드 링크 안내, 이어서 면접 준비를 다음 행동으로 제안.
|
|
41
|
+
|
|
42
|
+
> **윤리 경계:** 이 루프의 어느 단계도 "사실을 왜곡해 탐지를 피하라"고 지시하지 않는다. 탐지 리스크는 *진정성·구체성·차별화*의 부산물로만 낮춘다. 사실·수치·고유명사는 끝까지 보존한다.
|
|
43
|
+
|
|
44
|
+
## 4. 출처 (Provenance)
|
|
45
|
+
|
|
46
|
+
- **AI 자소서 비율 64.4%(2025)·전문항 20.6%** — 무하유·프리즘 데이터(언론 종합) · https://v.daum.net/v/20251123025247720
|
|
47
|
+
- **무하유 GPT킬러 탐지율 최대 98%·대기업 도입·카피킬러 대학 96%·프리즘** — 무하유 공식 · https://www.copykiller.com/gptkiller , https://www.muhayu.com/
|
|
48
|
+
- **기업 65.4% 적발 시 불이익·"AI 여부보다 면접 설명력"** — 고용노동부·한국고용정보원 및 HR 인식 조사(언론 종합)
|
|
49
|
+
- **OpenAI AI 분류기 2023 폐기(정확도 부족)** — OpenAI, "AI classifier" 회수 공지(2023)
|
|
50
|
+
- **탐지기 비원어민 거짓양성** — Liang et al., Stanford, "GPT detectors are biased against non-native English writers" (2023) · https://arxiv.org/abs/2304.02819
|
|
51
|
+
- **자기복제 방지 설계** — CareerMate ADR-0005, EOP `cover-letter.md` §1·§2-3·§5
|
|
52
|
+
|
|
53
|
+
## 5. Phase B 힌트
|
|
54
|
+
|
|
55
|
+
- **결정론 연계:** D1(수치)·D4(클리셰/제너릭/하이프)·D5(자기복제 후보)는 이미 `@careermate/core/verify`(lint 신호·provenance)로 일부 셀 수 있다 — 이 검증기는 그 결과를 **의미 판단으로 묶는** 상위 루브릭이다. `validate_cover_letter` 리포트의 `fabricated`/`signals`를 D1/D4 입력으로 재사용.
|
|
56
|
+
- **MCP 도구 아이디어:** `get_verifier({ id: "ai-detection-risk" })` — 이 루브릭 반환. 별도 점수 도구는 만들지 않는다(탐지 점수의 단정은 거짓확신을 낳으므로 의도적으로 회피).
|
|
57
|
+
- **데이터 형태 힌트:** 입력 = 신규 본문 + `get_application_context`의 저장 사실 + 기존 자소서 + (있으면) 공고의 회사 리서치 필드. 출력 = `{ unanchored_claims[], undefendable_sentences[], swappable_ratio, carryover_ratio, framing_ok }` — 모두 연결 AI가 채운다.
|
|
@@ -35,6 +35,9 @@
|
|
|
35
35
|
| C10 | 빈말 채움(filler) 문장 | 정보 없는 채움 문장("~에 대한 저의 열정은 남다릅니다" 류)이 **전체 문장의 5% 미만** | §filler 패턴과 매칭되거나 숫자·고유명사·동사 목적어가 전혀 없는 문장 수를 센다 |
|
|
36
36
|
| C11 | 구체 증거(수치·사례) 존재 | 본문에 **정량 근거(숫자/기간/규모/성과 지표)가 최소 2개** 이상 | 숫자+단위/퍼센트/"N배"/"N명"/"N개월" 패턴 매칭 수가 2 이상인지 확인 |
|
|
37
37
|
| C12 | 번역투 문법 밀도 *(advisory)* | 아래 §번역투 패턴이 **100단어당 3개 이하** (권고 신호, 하드 실패 없음) | §번역투 패턴 목록과 부분 매칭 → 밀도 계산. **맥락 확인 필수**: 정상 용법에서도 등장하는 표현이 많으므로 밀도가 높더라도 연결 AI가 문맥을 보고 최종 판단. 단독으로 불합격 처리하지 않는다 |
|
|
38
|
+
| C13 | 캐치프레이즈·모티프 반복 | 같은 캐치프레이즈·모티프(반복되는 고유 표현·슬로건, 예: "1원도 틀리지 않는")가 **문서 전체에서 2회 이하** | 반복 등장하는 짧은 고유 구절을 식별해 등장 횟수를 센다. **3회 이상이면 인위적 장치**로 읽혀 사람 목소리를 깎는다(문항형 자소서는 문항 전체를 한 문서로 합쳐서 센다). C1의 '슬롭 사전 단어 반복'과 달리 사전에 없는 **글 고유의 반복 구절**을 잡는다 |
|
|
39
|
+
| C14 | 문장 리듬 변주 *(advisory)* | 비슷한 길이(±3단어 이내) 문장이 **4개 이상 연속되지 않고**, 각 단락에 짧은 문장(≤8단어) **1개 이상** | 인접 문장의 단어 수 배열에서 유사 길이 연속 구간의 최대 길이를 재고, 단락별 최단 문장 길이를 확인한다. C3(전체 표준편차·burstiness)와 달리 **국소적 연속 단조**를 잡는다. **권고 신호(게이트 아님)** — 짧은 문항·bullet 구간 false-positive 방지 |
|
|
40
|
+
| C15 | 기술 디테일 구체성 *(advisory)* | 기술 경험·기술 문항 서술에 추상 요약을 넘어선 **패턴 명명·구체 구현 수준 디테일이 최소 1개**(예: "Outbox 패턴", "인덱스 재설계로 풀스캔 제거") | 추상 동사구("~하는 방식"·"처리했다"·"관리했다")만으로 기술을 서술한 구간을 표시한다. 지나치게 매끈한 curated 요약은 사람확률을 깎는 AI 의심 신호(human-baseline 실측). **단 저장에 없는 구현 디테일을 지어내면 C8·C9 위반이므로, 없을 때는 발명이 아니라 사용자에게 물어 채우도록 권고**한다. **권고 신호(게이트 아님)** — 비기술 직군·짧은 문항 false-positive 방지 |
|
|
38
41
|
|
|
39
42
|
### 슬롭 사전 (C1 — 부분 일치로 카운트)
|
|
40
43
|
|
|
@@ -76,12 +79,14 @@
|
|
|
76
79
|
연결된 AI는 위 항목을 채점해 **불합격 항목 ID + 근거(센 수치/매칭된 문자열/위치)** 를 모은다. 그다음 항목별로 아래 수정 지시를 적용해 **재작성 → 동일 루브릭 재검증**한다. 재검증 통과까지 반복하되, **C8·C9(사실·고유명사 보존)는 단 1건이라도 위반 시 즉시 하드 실패**로 처리하고 다른 어떤 개선보다 우선해 복구한다.
|
|
77
80
|
|
|
78
81
|
- **C1·C2·C6 위반(슬롭/상투/과장)**: 매칭된 단어·구문을 나열하고, 각각을 그 사람의 실제 경험·맥락에서 나온 **구체 표현으로 1:1 치환**한다. 일반론을 사실로 바꾼다. 치환 후 밀도를 다시 센다.
|
|
79
|
-
- **
|
|
82
|
+
- **C13 위반(모티프 반복)**: 3회 이상 등장한 캐치프레이즈·모티프를 표시하고, **첫 1~2회만 남기고 나머지는 매번 다른 말로 바꿔** 표현한다(같은 슬로건을 문항마다 되풀이하지 않는다). 권고 신호이므로 재작성을 강제하지는 않되, 반복 횟수를 다시 센다.
|
|
83
|
+
- **C3·C4·C5·C14 위반(단조로움·리듬)**: **모두 권고 신호**이므로 위반이 있어도 재작성을 강제하지 않는다. 다음 조건 중 하나 이상이면(연속 3문장 이상 동일 시작어 / 단락 내 3단 병렬 2회 초과 / **비슷한 길이 문장 4개 이상 연속[C14]**) 구체적 수정 제안을 함께 낸다(여전히 권고): 긴 문장 1~2개를 쪼개 **짧은 강조 문장(≤8단어)** 삽입, 연속 동일 시작어 문장의 도입부 변경, 3단 병렬을 1개로 축소·문장 형태 비대칭화. 표준편차·시작어 분포·연속 길이를 재측정한다.
|
|
80
84
|
- **C7 위반(목소리 불일치)**: 다수 종결어미·인칭으로 **전체를 통일**한다. 격식이 튀는 구간을 주변 톤에 맞춰 다시 쓴다.
|
|
85
|
+
- **C15 위반(기술 디테일 추상)**: 추상 요약만 있는 기술 서술 구간을 표시하고, 패턴명·구체 구현으로 한 단계 내리도록 권고한다 — 단 저장에 없으면 지어내지 말고 사용자에게 묻는다(권고 신호, 게이트 아님).
|
|
81
86
|
- **C10·C11 위반(빈말/근거 부족)**: 빈말 문장을 삭제하거나, 원본 데이터(`get_application_context`로 받은 경력·성과·스킬)에서 **수치·사례를 끌어와** 구체화한다. 없으면 지어내지 말고 사용자에게 해당 수치를 묻는다.
|
|
82
87
|
- **C8·C9 위반(사실/고유명사 손상)**: 원본에서 누락·왜곡된 숫자·고유명사를 **원문 그대로 복원**한다. 추정·대체 금지. 복원 후 집합 비교를 재수행해 100%를 확인한다.
|
|
83
88
|
|
|
84
|
-
재검증 종료 조건: **C1·C2·C6·C7·C10·C11 전부 합격 + C8·C9 위반 0
|
|
89
|
+
재검증 종료 조건: **C1·C2·C6·C7·C10·C11 전부 합격 + C8·C9 위반 0건**(C13 모티프 반복은 권고 신호로, 3회 이상이면 수정 권고하되 게이트는 아니다). **C3·C4·C5·C14·C15(문장 길이·시작어·3단 병렬·리듬 변주 단조성 신호 + 기술 디테일 구체성)는 게이트가 아니라 권고 신호**다 — 단독으로 종료를 막지 않고 개선 권고만 한다(짧은 문항·이력서 bullet 등 통계 무의미 구간 false-positive 방지; §2 advisory note·`human-writing.md` R12/line86과 동일선). 단 뚜렷한 위반(연속 3문장 이상 동일 시작어[C4] / 단락 내 3단 병렬 2회 초과[C5] — §2 표의 단락당 1회 기준을 크게 넘는 밀집)엔 구체 수정 제안을 함께 낸다(재작성 강제는 아님). 그 외 한 항목이라도 불합격이면 루프를 멈추지 않는다. (C3·C4·C5 게이트 정렬 완료 2026-06-20: 셋 다 권고 신호로 통일, human-writing.md 게이트 집합 R5/R6/R9/R11과 정합. cross-verifier 근거 구분은 §4 보존 — C5=Wikipedia rule-of-three, C3·C4=burstiness.)
|
|
85
90
|
|
|
86
91
|
## 4. 출처 (Provenance)
|
|
87
92
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- **과장(inflation):** 있는 사실을 부풀림(직함 격상, 팀 성과를 개인 성과로 귀속, "참여"를 "주도"로).
|
|
12
12
|
- **미검증 정밀도(false precision):** 저장 데이터에 근거 없는 구체 수치("매출 37% 증가")를 생성.
|
|
13
13
|
- **갭 은폐(gap concealment):** 모르는 것을 모른다고 하지 않고 빈칸을 그럴듯하게 메움.
|
|
14
|
+
- **속성 추론 비약(attribute leap):** 저장된 *기법·행위*에서 저장되지 않은 *성과·속성*을 단정하는 "그럴듯한 추론" 누수. **기법·무결성 ≠ 성과·가용성·규모.** 예: "듀얼라이트·대사(정합성 기법)" → "무중단/제로다운타임(가용성 성과)" 단정; "정합성 오류 0건" → "장애 0"; "Kafka 사용" → "대용량"; "p99 개선" → "사용자 경험 개선" 단정. 기법이 그 성과를 *가능케 한다*고 저장 성과 자체는 없으면 단정 금지 — 기법만 진술하거나 `[확인 필요]`로 둔다(가장 흔하고, 숫자·고유명사가 없어 결정론으로 안 잡히는 누수다).
|
|
14
15
|
|
|
15
16
|
> 경계 원칙: **표현을 강하게 다듬는 것(action verb·두괄식·정량화)은 허용, 사실을 바꾸는 것은 금지.** 강한 동사로 쓰되 동사가 가리키는 행위·결과는 저장 데이터와 일치해야 한다. 이 검증기는 사람처럼 쓰기(`human-writing.md`)의 "Fact lock(R7)" 신호를 **전 산출물·전 사실유형으로 확장한 전용 게이트**다.
|
|
16
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "careermate",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CareerMate — an MCP-first, local-first career workspace. Connect it to a local AI agent (Claude Desktop, Claude Code, Codex); CareerMate stores your career data locally on your machine and exposes it over MCP.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -66,12 +66,15 @@
|
|
|
66
66
|
"shots:seed": "node --no-warnings --experimental-sqlite --import tsx scripts/shots-seed.ts",
|
|
67
67
|
"shots": "node --no-warnings --experimental-sqlite --import tsx scripts/shots.ts",
|
|
68
68
|
"doctor": "node --no-warnings --experimental-sqlite --import tsx scripts/doctor.ts",
|
|
69
|
-
"test": "node --no-warnings scripts/
|
|
69
|
+
"test": "node --no-warnings scripts/test-all.mjs",
|
|
70
70
|
"test:ui": "node --no-warnings scripts/run.mjs scripts/ui-smoke.ts \"UI_VERDICT PASS\"",
|
|
71
|
+
"test:dist": "node --no-warnings scripts/test-dist.mjs",
|
|
72
|
+
"prepublishOnly": "node --no-warnings scripts/test-all.mjs && node --no-warnings scripts/test-dist.mjs",
|
|
71
73
|
"typecheck": "tsc --noEmit"
|
|
72
74
|
},
|
|
73
75
|
"dependencies": {
|
|
74
76
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
77
|
+
"docx": "^9.7.1",
|
|
75
78
|
"fflate": "^0.8.3",
|
|
76
79
|
"hwp.js": "^0.0.3",
|
|
77
80
|
"mammoth": "^1.12.0",
|