How santifer/career-ops Archetype Detection Classifies Job Roles: Token Matching Explained

santifer/career-ops classifies job roles using a deterministic three-stage pipeline that tokenizes job titles, calculates Jaccard similarity scores against six curated archetype keyword sets, and selects the highest match above a 0.6 threshold to drive CV framing and negotiation scripts.

The santifer/career-ops archetype detection system automatically categorizes every job opportunity into one of six specialized archetypes (such as AI Platform / LLMOps Engineer or Data Engineering) by analyzing the specific technologies mentioned in role descriptions. This classification engine, implemented in the open-source santifer/career-ops repository, relies on a lightweight token-matching algorithm to map diverse job postings to standardized categories. The detection logic spans role-matcher.mjs, modes/_shared.md, and reporting modules like gemini-eval.mjs.

The Three-Stage Detection Pipeline

The archetype classification engine processes each job posting through a strict sequence of tokenization, scoring, and selection. This deterministic approach ensures consistent categorization across thousands of job listings without requiring external API calls or heavy ML inference.

Stage 1: Tokenizing Job Titles with roleTokens

The pipeline begins in role-matcher.mjs (lines 63-70) with the roleTokens function, which converts raw job titles into normalized keyword arrays. The function lowercases the input, strips punctuation, and filters out generic stop-words while preserving technology-specific terms.

export function roleTokens(role) {
  const text = typeof role === 'string' ? role : String(role ?? '');
  return text
    .toLowerCase()
    .replace(/[^a-z0-9\s]/g, ' ')
    .split(/\s+/)
    .filter(w => (w.length > 3 || SHORT_SPECIALTY.has(w)) && !ROLE_STOPWORDS.has(w));
}

The tokenizer discards tokens found in ROLE_STOPWORDS (lines 13-32), which contains seniority indicators, contract modes, and generic locations. It retains short specialty acronyms like api, gpu, or ios defined in SHORT_SPECIALTY (lines 34-40), ensuring that technical abbreviations survive the filtering process. The resulting array captures only the discriminating technology words that distinguish one role from another.

Stage 2: Calculating Jaccard Similarity Scores

Each archetype is defined by a curated keyword list stored in modes/_shared.md. The detection algorithm computes a Jaccard-style overlap ratio between the job's token set and each archetype's keyword set. The scoring logic (implemented in roleFuzzyMatch within role-matcher.mjs) calculates similarity as the size of the intersection divided by the size of the union.

// Conceptual implementation based on role-matcher.mjs logic
const jobTokens = new Set(roleTokens(jobTitle));
const archTokens = new Set(archetypeKeywords);
const overlap = [...jobTokens].filter(t => archTokens.has(t));
const unionSize = new Set([...jobTokens, ...archTokens]).size;
const similarity = overlap.length / unionSize;

The system enforces a minimum similarity threshold of 0.6 (lines 100-104 in role-matcher.mjs) to prevent false positives. If a job posting shares fewer than 60% of its distinct tokens with an archetype's keyword set, that archetype is disqualified from selection. This threshold ensures that only roles with substantial technology overlap receive classification.

Stage 3: Selecting the Best Match and Detecting Hybrids

After scoring all six archetypes, the algorithm selects the candidate with the highest similarity score that meets the 0.6 threshold. If no archetype reaches this threshold, the job is classified as "unknown" (see gemini-eval.mjs, lines 306-311), and reports display Archetype: unknown.

When two archetypes both exceed the 0.6 threshold with similar scores, the system marks the posting as a hybrid role. According to modes/oferta.md (line 20), hybrid classifications report both matching archetypes, acknowledging that modern roles often span multiple domains (such as a position requiring both Data Engineering and AI Platform skills).

Archetype Definitions and Keyword Curation

The canonical definitions for the six archetypes reside in modes/_shared.md, which serves as the single source of truth for the detection system. Each archetype entry contains a name and a comma-separated keyword list representing core responsibilities and technologies.


### AI Platform / LLMOps Engineer

**Keywords:** llm, transformer, prompt-engineering, huggingface, inference, model-ops

This file is part of the system layer and is never edited by end users, ensuring consistency across the role-matcher.mjs tokenizer and downstream analytics. When gemini-eval.mjs generates reports, it extracts the detected archetype and injects it into the header (lines 348-352) using the format:

**Archetype:** AI Platform / LLMOps Engineer

Integration with Reporting and Analytics

Once classified, archetypes power the application's core features. The gemini-eval.mjs module surfaces the detected archetype in generated reports to guide CV framing and negotiation scripts. For analytics purposes, analyze-patterns.mjs parses these archetype headers from report files to aggregate statistics on job market trends by category.

The deterministic nature of this token-based approach means that classifications are reproducible and explainable—every assignment can be traced back to specific keyword overlaps between the job title and the archetype definitions in modes/_shared.md.

Summary

  • santifer/career-ops uses a three-stage pipeline in role-matcher.mjs to classify jobs into six archetypes.
  • The roleTokens function normalizes job titles by removing stop-words and preserving technical terms using ROLE_STOPWORDS and SHORT_SPECIALTY sets.
  • Jaccard similarity scores compare job tokens against archetype keywords from modes/_shared.md, requiring a minimum threshold of 0.6.
  • Roles matching two archetypes are flagged as hybrids (per modes/oferta.md), while non-matches return "unknown".
  • Classifications drive downstream features in gemini-eval.mjs and analytics in analyze-patterns.mjs.

Frequently Asked Questions

What happens if a job matches two archetypes equally well?

When two archetypes both exceed the 0.6 similarity threshold, santifer/career-ops marks the role as a hybrid and reports both classifications. This handling, documented in modes/oferta.md (line 20), ensures that cross-functional roles (such as those combining data engineering and ML operations) receive accurate multi-category labels rather than forcing a false binary choice.

Where are the archetype keywords defined in santifer/career-ops?

The six archetype definitions and their associated keyword lists are stored in modes/_shared.md. This file serves as the system-level source of truth, containing formatted entries like "### AI Platform / LLMOps Engineer" followed by curated technology keywords. The role-matcher.mjs module loads these definitions to perform classification against incoming job postings.

What is the minimum similarity threshold for classification?

The system requires a Jaccard similarity score of at least 0.6 between the job's token set and an archetype's keyword set. This threshold is hardcoded in role-matcher.mjs (lines 100-104) to filter out weak matches and ensure that only positions with substantial technology overlap receive a specific archetype assignment.

How does the system handle job titles without matching archetype keywords?

If no archetype achieves the 0.6 similarity threshold, the detection pipeline returns "unknown" as the classification. As shown in gemini-eval.mjs (lines 306-311), these cases are explicitly handled in report generation, displaying Archetype: unknown and skipping archetype-specific CV framing while still preserving the raw job data for manual review.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →