Skip to content

Fit Scoring Engine

Chazona Baum edited this page Jun 24, 2026 · 1 revision

Relevant source files

The Fit Scoring Engine is responsible for evaluating the compatibility between a Job and the user's Target Criteria. It implements a two-layer rubric consisting of a Hard Layer (strict filters that generate flags) and a Soft Layer (weighted scoring across five dimensions).

Architecture Overview

The engine operates on a "Recall-Safe" principle: flags and penalties are only applied when a conflict is explicitly known. If data is missing from either the Job or the Profile, the engine defaults to a neutral stance to avoid false negatives src-tauri/src/fit.rs#3-5

The primary entry point is score_fit, which consumes a Job, TargetCriteria, and CompetencyIndex to produce a FitBreakdownsrc-tauri/src/fit.rs#335-338

Data Flow: Natural Language to Code Entities

The following diagram illustrates how raw job descriptions and user profile data are transformed into structured entities and finally processed by the scoring engine.

Scoring Pipeline Data Flow

flowchart TD
    subgraph subGraph2 ["Scoring Engine (src-tauri/src/fit.rs)"]
        HF["hard_filters()"]
        SS["score_fit()"]
        FB["FitBreakdown Struct"]
    end
    subgraph subGraph1 ["Code Entity Space"]
        JobEntity["Job Struct"]
        ExpEntity["Experience Struct"]
        TC["TargetCriteria Struct"]
        CI["CompetencyIndex"]
    end
    subgraph subGraph0 ["Natural Language Space"]
        JD["Job Description (Markdown)"]
        EXP["Experience Notes (Markdown)"]
    end
    JD --> JobEntity
    EXP --> ExpEntity
    ExpEntity --> TC
    JobEntity --> HF
    TC --> HF
    HF --> SS
    JobEntity --> SS
    CI --> SS
    SS --> FB
Loading

Sources: src-tauri/src/fit.rs#55-63src-tauri/src/fit.rs#335-376src-tauri/src/experience.rs#45-72src-tauri/src/experience.rs#96-127


The Two-Layer Rubric

1. Hard Layer: Filters and Flags

The hard_filters function checks for "Dealbreakers" and "Cautions" src-tauri/src/fit.rs#265-266

  • Dealbreaker: A hard conflict (e.g., location mismatch, comp below floor). If any dealbreaker fires, the final score is collapsed to 0src-tauri/src/fit.rs#8-9
  • Caution: A noteworthy mismatch that does not zero out the score but is surfaced to the user.
Check Logic Level
Arrangement Fired if job.remote is known and conflicts with target.work_arrangements. Dealbreaker
Location Fired if the job is not remote and the metro does not match targeted metros. Dealbreaker
Compensation Fired if job.comp_high is known and is less than target.comp_floor. Dealbreaker
Visa Fired if job.visa_sponsorship is explicitly false but user requires it. Dealbreaker

Sources: src-tauri/src/fit.rs#21-32src-tauri/src/fit.rs#265-333

2. Soft Layer: Sub-scores

The engine calculates five sub-scores (0–100), which are then weighted by the user's FitWeightssrc-tauri/src/fit.rs#356-361

Sub-score Function Logic Summary
Seniority seniority_fit Two-track model (IC/Mgmt) + YOE reducer.
Skills skills_fit Coverage of required (80%) and preferred (20%) skills.
Comp comp_fit Proximity of job high-end to user target vs. floor.
Arrangement arrangement_fit Exact match (100) vs. known mismatch (15) vs. neutral (50).
Domain domain_fit Matching job domains against user's targeted domains.

Sources: src-tauri/src/fit.rs#55-60src-tauri/src/fit.rs#94-158src-tauri/src/fit.rs#165-184src-tauri/src/fit.rs#191-200


Seniority Model: Two-Track and YOE Reducer

The seniority_fit calculation is the most complex component of the engine, accounting for both title-based rank and chronological experience src-tauri/src/fit.rs#94-99

Two-Track Mapping

Seniority is split into Track::Ic and Track::Managementsrc-tauri/src/fit.rs#67-70 The level_track helper maps strings to these tracks and a numerical rank src-tauri/src/fit.rs#74-86

Seniority Rank Distance Penalties:

  • Exact Match: 100
  • Distance 1: 60 (e.g., Senior vs. Mid)
  • Distance 2: 30
  • Distance 3+: 10
  • Cross-track mismatch: 10 (e.g., IC applying for Dept Head)

Sources: src-tauri/src/fit.rs#11-12src-tauri/src/fit.rs#132-137

YOE Reducer

The YOE reducer scales the base seniority score down if the candidate's total months of experience is less than the job's minimum requirement src-tauri/src/fit.rs#91-93

Formula:reduced_score = base_score * min(candidate_months / (job_yoe_min * 12), 1.0)

The candidate_months is calculated in experience.rs by computing the "envelope" (earliest start to latest end) of all experience entries src-tauri/src/experience.rs#96-127


Implementation Details

FitBreakdown Struct

The result of a scoring run is encapsulated in FitBreakdown, which is serialized and stored in the Job's Markdown frontmatter src-tauri/src/fit.rs#55-63

pub struct FitBreakdown {
    pub seniority: i64,
    pub skills: i64,
    pub comp: i64,
    pub arrangement: i64,
    pub domain: i64,
    pub flags: Vec<Flag>,
    pub score: i64, // Combined weighted score (0 if dealbreaker)
}

Frontend Bands

On the frontend, the fit_score integer is mapped to a FitBand for UI display (e.g., "Strong", "Good", "Mismatch") src/lib/fit.ts#7-14

Fit Scoring Logic Mapping

flowchart LR
    UI["UI Components"]
    subgraph subGraph1 ["Svelte Frontend (src/lib/)"]
        FitBand["fitBand() (fit.ts)"]
        SortRoles["sortRoles() (rolesView.ts)"]
    end
    subgraph subGraph0 ["Rust Backend (src-tauri/src/fit.rs)"]
        ScoreFit["score_fit()"]
        HF["hard_filters()"]
        SF["seniority_fit()"]
        SK["skills_fit()"]
    end
    ScoreFit --> FitBand
    FitBand --> UI
    ScoreFit --> SortRoles
    SortRoles --> UI
Loading

Sources: src-tauri/src/fit.rs#335-376src/lib/fit.ts#7-14src/lib/rolesView.ts#11-30

Scoring Weights

The final score is a weighted average based on FitWeights. If weights are not provided, the engine defaults to equal distribution (20% per dimension) src-tauri/src/fit.rs#356-361

Sources: src-tauri/src/fit.rs#340-348

Clone this wiki locally