From d56eccce20fb00fff79069f4e29bbf55e0e5ce9c Mon Sep 17 00:00:00 2001 From: IKetutWidiyane Date: Sat, 4 Jul 2026 02:09:07 +0700 Subject: [PATCH] Add rule to detect excessive buzzword usage --- packages/core/src/__tests__/evaluator.test.ts | 11 +++++++++++ packages/core/src/evaluator/index.ts | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/packages/core/src/__tests__/evaluator.test.ts b/packages/core/src/__tests__/evaluator.test.ts index fa5c2ad..42e1ff1 100644 --- a/packages/core/src/__tests__/evaluator.test.ts +++ b/packages/core/src/__tests__/evaluator.test.ts @@ -49,6 +49,17 @@ describe("evaluate", () => { expect(issueNames).toContain("Responsibility without ownership"); }); + it("flags buzzword overuse when 5+ anti-patterns match", async () => { + const result = await evaluate({ + cv: { content: weakCV, format: "markdown" }, + }); + + const buzzwordIssue = result.issues.find((i) => i.element === "Buzzword overuse"); + expect(buzzwordIssue).toBeDefined(); + expect(buzzwordIssue?.severity).toBe("critical"); + expect(buzzwordIssue?.why).toContain("cliche"); + }); + it("finds strengths in strong CVs", async () => { const result = await evaluate({ cv: { content: strongCV, format: "markdown" }, diff --git a/packages/core/src/evaluator/index.ts b/packages/core/src/evaluator/index.ts index 37cdc08..ed232aa 100644 --- a/packages/core/src/evaluator/index.ts +++ b/packages/core/src/evaluator/index.ts @@ -182,6 +182,16 @@ function findIssues(cv: string, _archetype: RoleArchetype) { }); } } + + // Buzzword overuse: if 5+ anti-patterns matched, surface a critical issue + if (issues.length >= 5) { + issues.push({ + element: "Buzzword overuse", + why: `Your CV triggered ${issues.length} cliche patterns. This signals AI-generated or template-copied content to screeners.`, + fix: "Replace each flagged phrase with a specific achievement. One real number beats ten adjectives.", + severity: "critical", + }); + } // Word count heuristic: CVs >800 words (~2 pages), >1000 clearly too long const wordCount = cv.trim() ? cv.trim().split(/\s+/).length : 0;