Skill Matrix Engine - Real-Time Scenarios and Operating Model

Purpose and scope

This document describes how the skill matrix engine behaves in operations. It is aligned with the current * skill-matrix-engine* codebase and the Flyway migrations V1__skill_matrix_schema.sql (tables + column defaults) and V2__rubric_preset_seed.sql (system rubric anchors + sample formula/version rows). Features that are only policy goals or live outside this repo are called out explicitly.

For business and end users: what the migrations mean

Migration file In plain language Why you should care
V1__skill_matrix_schema.sql Creates all skill-matrix tables and defines default numbers on each formula column (weights, bonuses, caps) whenever a new formula row is created without overriding a column. Guarantees a consistent, auditable starting policy. Your live tenant may use different weights after admins publish updates—the app always reads the active formula for the logged-in tenant.
V2__rubric_preset_seed.sql (1) Loads global rubric anchors (suggested 0–10 starting scores per evidence type and tier). (2) Optionally seeds sample skill_formula_config + skill_formula_version rows for one reference tenant UUID so a fresh environment can demo version history (version.v1version1). Rubrics help students and staff see fair starting points before quality/recency adjustments. The seeded version1 policy slightly raises work experience vs exam weight compared to version.v1—useful story for “we value demonstrated practice alongside formal assessment.”

Seeded formula labels (reference data in V2 only)

Important: Production tenants that are not that UUID have no rows from this insert until your team publishes a formula in the UI/API. The worked examples below use the V2 seeded version1 weights so numbers match a typical post-migrate demo database.

Evidence types (code)

EvidenceType includes: CERTIFICATIONS, PROJECTS, PUBLICATIONS, COMPETITIONS, EXAMS, HACKATHONS, TRAININGS, EXPERIENCE, AWARDS, CONFERENCES, PATENTS, SELF_ASSESSMENT.

Row-level behavior (student_skill_evidence):

Evidence weight matrix (V1 DDL defaults vs V2 seeded version1)

Weights are per evidence type. The twelve configured weights must sum to 1.00 within tolerance 0.0001.
Top 3 and bottom 2 types (used for completeness and low-type down-weighting) are always recalculated from whatever weights your tenant’s active formula row has—not from this document.

V1 — Column defaults on skill_formula_config (schema template)

These are the numbers baked into CREATE TABLE in V1__skill_matrix_schema.sql when a column is not specified on insert.

Type DDL default weight
EXAMS 0.22
PROJECTS 0.18
EXPERIENCE 0.14
CERTIFICATIONS 0.10
TRAININGS 0.09
HACKATHONS 0.07
COMPETITIONS 0.06
PUBLICATIONS 0.05
PATENTS 0.04
AWARDS 0.03
CONFERENCES 0.02
SELF_ASSESSMENT 0.00

Top 3 (V1 defaults only): EXAMS, PROJECTS, EXPERIENCE. Bottom 2 (low-weighted): SELF_ASSESSMENT (weight **0 **), CONFERENCES ( 0.02 ) — see Engine buckets below. AWARDS is mid-mass, not low-weighted.

V2 — Seeded published policy version1 (skill_formula_config second insert row)

This matches V2__rubric_preset_seed.sql: same non-weight columns as V1 defaults; only exam vs experience balance changes vs version.v1 in the same file.

Type version1 weight Change vs version.v1 in V2 (first row)
EXAMS 0.17 −0.05
PROJECTS 0.18 unchanged
EXPERIENCE 0.19 +0.05
CERTIFICATIONS 0.10 unchanged
TRAININGS 0.09 unchanged
HACKATHONS 0.07 unchanged
COMPETITIONS 0.06 unchanged
PUBLICATIONS 0.05 unchanged
PATENTS 0.04 unchanged
AWARDS 0.03 unchanged
CONFERENCES 0.02 unchanged
SELF_ASSESSMENT 0.00 unchanged

How to explain version1 to stakeholders: “We still reward exams and projects highly, but internships and jobs move slightly ahead of exam marks in the default mix—reflecting that proven on-the-job use of a skill matters as much as a test score.”

Top 3 (version1 weights): EXPERIENCE, PROJECTS, EXAMS. Bottom 2 (low-weighted): SELF_ASSESSMENT ( 0 ), CONFERENCES ( 0.02 ) — same rule as V1; only ranking of the top three changed.

Engine buckets (configured mass: top, low, mid)

This mirrors SkillScoringService: labels come only from configured weights on skill_formula_config, never from a student’s rubric or raw scores.

Implementation Value Meaning
TOP_WEIGHTED_COUNT 3 Types with the largest configured weights (deriveTopWeightedTypes).
LOW_WEIGHTED_COUNT 2 Types with the smallest configured weights (deriveLowWeightedTypes).
LOW_PRIORITY_DOWNWEIGHT 0.4 Applied to a present low-weighted type’s configured weight before splitting 100% across present types, only if the student has evidence in at least two top-weighted types.

Algorithm (dynamic redistribution branch).

  1. Build sourceScores per type (after anchor, multipliers, recency, top-k merge).
  2. Present types = types with sourceScore > 0.
  3. Top-weighted set = take all (EvidenceType, weight) pairs, sort by weight descending, keep 3 keys.
  4. Low-weighted set = same pairs, sort by weight ascending, keep 2 keys.
  5. Top-present count = how many present types fall in the top-weighted set.
  6. For each present type, start with effectiveWeight = configuredWeight. If topPresent >= 2 and the type is in the low-weighted set, set effectiveWeight *= 0.4.
  7. Dynamic weight for that type = effectiveWeight / Σ(effectiveWeight over present types) → present types’ dynamic weights sum to 1.
  8. Completeness bonus uses only the top-weighted set: count how many of those three have sourceScore > 0, multiply by completeness_bonus_per_top_type, cap 0.20.

Colloquial “high mass.” High configured mass = large weight in the published formula. “High mass present” in logic = at least two of the three top-weighted types have non-zero source scores — that unlocks ×0.4 on any present low-weighted type.

Mid-mass types. Types in neither the top-3 nor bottom-2 sets (with default V1 / V2 seeds, seven types: e.g. certifications through awards between experience and conferences).

SELF_ASSESSMENT at weight 0. It is always one of the two smallest weights in default migrations, so it sits in lowWeightedTypes. Down-weighting applies only if the student has self-assessment lines that produce sourceScore > 0 and topPresent >= 2. If only self rows exist but weight is 0, effectiveWeight stays 0 — an edge case to avoid relying on self-only profiles when the formula gives self zero global weight.

Ties. Equal configured weights: which type occupies a top-3 or bottom-2 slot depends on sort tie-breaking; avoid identical weights if you need stable labels in audits.

Full descending rank — V1 DDL default weights

Rank Evidence type Configured weight Bucket
1 EXAMS 0.22 Top-weighted (high mass)
2 PROJECTS 0.18 Top-weighted
3 EXPERIENCE 0.14 Top-weighted
4 CERTIFICATIONS 0.10 Mid-mass
5 TRAININGS 0.09 Mid-mass
6 HACKATHONS 0.07 Mid-mass
7 COMPETITIONS 0.06 Mid-mass
8 PUBLICATIONS 0.05 Mid-mass
9 PATENTS 0.04 Mid-mass
10 AWARDS 0.03 Mid-mass
11 CONFERENCES 0.02 Low-weighted
12 SELF_ASSESSMENT 0.00 Low-weighted

Full descending rank — V2 seeded version1 weights

Rank Evidence type Configured weight Bucket
1 EXPERIENCE 0.19 Top-weighted
2 PROJECTS 0.18 Top-weighted
3 EXAMS 0.17 Top-weighted
4 CERTIFICATIONS 0.10 Mid-mass
5 TRAININGS 0.09 Mid-mass
6 HACKATHONS 0.07 Mid-mass
7 COMPETITIONS 0.06 Mid-mass
8 PUBLICATIONS 0.05 Mid-mass
9 PATENTS 0.04 Mid-mass
10 AWARDS 0.03 Mid-mass
11 CONFERENCES 0.02 Low-weighted
12 SELF_ASSESSMENT 0.00 Low-weighted

If your team publishes a new formula, re-rank the twelve types and replace top 3 / bottom 2; the UI should show whatever the API returns in topWeightedTypes / lowWeightedTypes on the latest computation.

Skill aggregation (per student, per skill)

Institutional vs employer-visible scoring

For each skill, the engine can compute two bundles:

  1. Institutional: all non-scoring-excluded rows.
  2. Employer-visible: subset with visibility EMPLOYER or BOTH.

The profile stores final institutional score (after optional decay and override) and, when the employer bundle is non-empty, employer_visible_final_score and employer_visible_confidence. Job match evaluation can use either via useEmployerVisibleScores.

Dynamic weight redistribution (evidence-based scoring)

When use_dynamic_weight_redistribution is true (default), the engine adapts to evidence the student actually submitted. Top-weighted and low-weighted sets are only the three largest and two smallest configured weights (see Engine buckets). With self_assessment_weight = 0 (V1/V2 defaults), low-weighted types are * SELF_ASSESSMENT* and CONFERENCES, not AWARDS.

Formula flow (SkillScoringService.computeScoreBundle)

If use_dynamic_weight_redistribution is false, steps 4–5 are skipped: there is no “present-types only” normalization and no ×0.4 low-type step; contributions are configuredWeight × sourceScore per type (zero where there is no score). Completeness still uses topWeightedTypes.

  1. Calibrated anchor (per evidence row): blends rubric (base_score_0_10) and self-assessment ( student_self_assessment_score_0_10) with inflation dampening when self-assessment exceeds rubric:
    • dampenedSelf = rubric + gap / (1 + sensitivity × gap) for gap = max(0, self − rubric); if self ≤ rubric, no dampening.
    • anchor = rubric × credibility + dampenedSelf × (1 − credibility) where credibility = rubricAnchorFloor + (verifiedRubricBoost if verified), capped at 1.0.
  2. Per-row effective score: anchor × min(1, quality) × min(1, confidence) × recency, then clamped to 0–10.
  3. Top-k diminishing aggregation per evidence type using top_k_per_source (k = 3 default) and decay_factor ( 0.70 default): weighted average of the top scores with weights 1, decay, decay², ….
  4. Low-priority down-weighting (inside dynamic core): for each present type, start from configured weight; if the count of present types that belong to topWeightedTypes is ≥ 2 and the type is in * *lowWeightedTypes**, multiply its weight by 0.4 (LOW_PRIORITY_DOWNWEIGHT).
  5. Dynamic weights among present types only: dynamic_weight = effective_weight / Σ effective_weight so present types sum to 1.0 (missing types get 0).
  6. Weighted core (before diversity) = Σ (dynamic_weight × source_score) + completeness bonus (see below). The value persisted as weighted_core in skill_score_computation includes the completeness bonus.
  7. Completeness bonus = min(0.20, count(top types with evidence) × completeness_bonus_per_top_type) (defaults: * 0.05* per type, cap 0.20). Here “top types with evidence” means members of topWeightedTypes with sourceScore > 0.
  8. Diversity bonus = min(diversity_bonus_cap, max(0, distinctTypesWithScore − 1) × bonus_per_source) (defaults: cap 0.80, 0.20 per extra type).
  9. Consistency penalty = consistency_penalty_factor × sqrt(variance of non-zero source scores) across types ( default factor 0.08).
  10. Final model score = clamp to [0, 10] of (weighted_core + diversity_bonus − consistency_penalty).
  11. Profile-only cap: if the student has only one evidence type and that type is not CERTIFICATIONS, PROJECTS, EXAMS, or EXPERIENCE, the final score is capped at profile_only_max_cap (default 5.5).
  12. Optional skill-level decay: if skill_level_decay_enabled and no human override, institutional (and employer) scores drift toward skill_level_decay_baseline_0_10 based on skill_level_decay_basis (default EVIDENCE_DATE) and half-life skill_level_decay_half_life_days (default 365). When skill_level_decay_apply_on_read is true, decay can be re-applied on read from stored intrinsic scores.
  13. Human override: if an active per-skill override exists, displayed institutional score is the override; decay is not applied to the overridden value.

Confidence (0–100)

confidence_score on the profile uses:

100 × (0.35 × coverage + 0.30 × verificationRatio + 0.20 × freshness + 0.15 × stability)

Recency multiplier (high level)

If evidence_date is null, recency defaults to 0.70. Otherwise exponential decay uses type-specific half-lives ( days), e.g. EXAMS / CERTIFICATIONS / TRAININGS 540; PROJECTS / COMPETITIONS / HACKATHONS / EXPERIENCE 365; PUBLICATIONS / PATENTS 720; AWARDS / CONFERENCES 270; SELF_ASSESSMENT 180.

Config parameters (formula)

Parameter Default Description
top_k_per_source 3 How many evidence lines per type participate in diminishing aggregation
decay_factor 0.70 Decay weight for 2nd, 3rd, … best line within a type
diversity_bonus_cap 0.80 Upper bound on diversity bonus
bonus_per_source 0.20 Increment per extra evidence type beyond the first
consistency_penalty_factor 0.08 Scales spread penalty across types
profile_only_max_cap 5.5 Cap for “single weak-type-only” profiles (see step 11)
use_dynamic_weight_redistribution true Enable redistribution among present types
completeness_bonus_per_top_type 0.05 Bonus per top-weighted type with evidence (max 0.20)
self_inflation_sensitivity 0.5 Dampening strength when self-assessment exceeds rubric (DB allows 0–5)
rubric_anchor_floor 0.4 Minimum rubric weight in anchor blend
verified_rubric_boost 0.3 Extra rubric weight when verified; floor + boost ≤ 1.0
skill_level_decay_enabled false Time decay toward baseline
skill_level_decay_basis EVIDENCE_DATE What timestamps drive decay
skill_level_decay_half_life_days 365 Half-life for decay curve
skill_level_decay_baseline_0_10 5.0 Baseline score toward which skill decays
skill_level_decay_apply_on_read false Re-apply decay on API read

SkillScoringService only (not separate DB columns): TOP_WEIGHTED_COUNT = 3, LOW_WEIGHTED_COUNT = 2, LOW_PRIORITY_DOWNWEIGHT = 0.4.

These non-weight defaults match V1__skill_matrix_schema.sql column definitions; the V2 seed inserts use the same values for rubric-anchor and decay fields on both version.v1 and version1 rows (only the twelve weights differ between those two configs).

FormulaPublishRequest today carries weights and skill-level decay fields; other parameters keep entity/DB defaults on publish unless extended in code.

Dynamic formula scenarios (illustrative)

Scenario Evidence present Behaviour
Single type Only CERTIFICATIONS 100% dynamic weight to that type; no penalty for missing other categories.
Two low-mass types CERTIFICATIONS + PUBLICATIONS Redistribute by configured mass (e.g. 0.10 vs 0.05 → ~67% / ~33%).
Top types only Any two of EXPERIENCE / PROJECTS / EXAMS (under V2 version1) Strong signal; completeness bonus can apply.
Mixed top + low e.g. EXAMS + PROJECTS + CONFERENCES With ≥2 top-weighted types present, each present low-weighted type (default seeds: CONFERENCES, or SELF_ASSESSMENT if it has score) is ×0.4 before normalization. AWARDS is not low-weighted under default weights.
Only low types e.g. CERTIFICATIONS + PUBLICATIONS + AWARDS Redistribution only; no ×0.4 low-type rule (fewer than two top types present).

With dynamic mode off

Configured weights apply to all types; missing types contribute zero but their weight is not reallocated—students with sparse types are not boosted by redistribution.

Skill score computation ledger

Each recompute persists skill_score_computation (when profile build runs with useExistingProfile):

API: GET /skill-matrix/student/{studentId}/skill/{skillName}/computation-history?limit=10

Computation reason values (observed in code paths)

EVIDENCE_UPDATE, EVIDENCE_BATCH, EVIDENCE_VERIFICATION, EVIDENCE_VERIFICATION_BULK, MANUAL_RECOMPUTE, FORMULA_PUBLISH_RECOMPUTE, FORMULA_ROLLBACK_RECOMPUTE (plus any explicit string passed into recomputeStudentSkills).

Formula decision flags (explainability / audit)

Including: DYNAMIC_WEIGHT_REDISTRIBUTION, LOW_PRIORITY_DOWNWEIGHTED, COMPLETENESS_BONUS_APPLIED, DIVERSITY_BONUS_APPLIED, CONSISTENCY_PENALTY_APPLIED, HUMAN_OVERRIDE_APPLIED, SKILL_LEVEL_DECAY_APPLIED.

Explainability payload (explainability_json)

In addition to sourceScores, sourceWeights (configured or dynamic, depending on mode), weightedContributions, topWeightedTypes, lowWeightedTypes, diversityBonus, completenessBonus, consistencyPenalty, finalScore:

Worked examples in tables

Scenarios and full computation outputs below are shown only as tables (no JSON). Narrative blocks explain why ** each case behaves as it does. The field names match * GET /skill-matrix/student/{studentId}/skill/{skillName}/computation-history* (SkillComputationDto) and the * *explainability_json column on student_skill_profile. Numeric splits use the V2 seeded published policy version1 weights (see above), with dynamic redistribution on, unless noted.

Conventions (read once)

Concept Meaning
sourceScores (per type) After rubric/self anchor, quality, confidence, recency, and top-k aggregation within that type.
configuredWeight From active skill_formula_config (below).
dynamicWeight Renormalized over types that have non-zero source score; low types may be ×0.4 before normalization when ≥2 top-weighted types are present.
weightedCore (ledger) Σ (dynamicWeight × sourceScore) + completenessBonus—does not include diversity or consistency.
finalScore (ledger) Same as displayed institutional final_skill_score for that run: after cap, decay, override.
confidenceScore Depends on dates and verification; examples use rounded values.
topWeightedTypes / lowWeightedTypes Exactly 3 keys with largest configured weights / 2 keys with smallest (see Engine buckets). Persisted list order may vary.

Configured weights for examples (version1 from V2__rubric_preset_seed.sql):

Evidence type Weight
EXAMS 0.17
PROJECTS 0.18
EXPERIENCE 0.19
CERTIFICATIONS 0.10
TRAININGS 0.09
HACKATHONS 0.07
COMPETITIONS 0.06
PUBLICATIONS 0.05
PATENTS 0.04
AWARDS 0.03
CONFERENCES 0.02
SELF_ASSESSMENT 0.00

Derived labels: top weighted = EXPERIENCE, PROJECTS, EXAMS; low weighted = SELF_ASSESSMENT, CONFERENCES ( with version1 / default zero self weight).


Example A — Only certifications (single evidence type)

Scenario. A student adds one strong, verified certification for skill Spring Boot. No exams or projects yet.

Why this matters. Dynamic mode does not punish missing high-weight types: the only present type receives **100% ** of the redistributed weight, so the score reflects certification quality instead of being dragged down by empty buckets.

Pipeline (step-by-step).

Step Outcome
Types with score CERTIFICATIONS only
Dynamic weights CERTIFICATIONS → 1.000 (all mass on present types)
Sum of contributions 8.2 (illustrative source score × 1.0)
Completeness bonus 0 (no evidence in top-3 types EXPERIENCE / PROJECTS / EXAMS)
weightedCore 8.2
Diversity bonus 0 (one type)
Consistency penalty 0 (one type)
Profile-only cap Not applied (CERTIFICATIONS is exempt)
Model final (before decay/override) 8.2

Audit row / API (computation-history) — identifiers and context

Field Illustrative value
id 10001
profileId 5001
formulaConfigId 42
formulaVersionId 1
evidenceIds 91001
evidenceTypesPresent CERTIFICATIONS
computationReason EVIDENCE_UPDATE
computedAt (ISO timestamp of recompute)

Per-type snapshot (only non-zero row shown; zeros omitted for brevity)

Type configuredWeight sourceScore dynamicWeight weightedContribution
CERTIFICATIONS 0.10 8.2 1.0 8.2

Ledger totals and flags

Field Value
weightedCore 8.2
completenessBonus 0
diversityBonus 0
consistencyPenalty 0
finalScore 8.2
confidenceScore ~44 (illustrative)
formulaDecisions DYNAMIC_WEIGHT_REDISTRIBUTION

Profile explainability_json (same run)

Key Value
sourceWeights (dynamic mode) CERTIFICATIONS → 1.0
weightedContributions CERTIFICATIONS → 8.2
topWeightedTypes EXPERIENCE, PROJECTS, EXAMS
lowWeightedTypes SELF_ASSESSMENT, CONFERENCES (order may vary)
completenessBonus 0
diversityBonus 0
consistencyPenalty 0
finalScore 8.2
modelFinalScoreBeforeOverride 8.2
humanOverrideApplied false

Example B — Exam + project (two top types)

Scenario. Same skill has institutional exam evidence (aggregated 8.0) and a project (aggregated **7.0 **).

Why this matters. Two top-weighted types are present, so the student earns a completeness bonus. Multiple types also trigger diversity and a small consistency penalty when scores differ.

Pipeline.

Step Outcome
Dynamic split EXAMS 0.17 / (0.17+0.18) ≈ 0.486; PROJECTS ≈ 0.514
Contributions EXAMS ~3.89; PROJECTS ~3.60; sum ~7.49
Completeness 2 top types × 0.05 → 0.10
weightedCore ~7.59
Diversity (2−1) × 0.20 → 0.20
Consistency 0.08 × σ(8,7) ≈ 0.04
Model final ~7.59 + 0.20 − 0.04 ≈ 7.75

Per-type snapshot

Type configuredWeight sourceScore dynamicWeight weightedContribution
EXAMS 0.17 8.0 0.486 3.89
PROJECTS 0.18 7.0 0.514 3.60

Ledger totals and flags

Field Value
weightedCore ~7.59
completenessBonus 0.10
diversityBonus 0.20
consistencyPenalty 0.04
finalScore ~7.75
confidenceScore ~48.5 (illustrative)
formulaDecisions DYNAMIC_WEIGHT_REDISTRIBUTION; COMPLETENESS_BONUS_APPLIED; DIVERSITY_BONUS_APPLIED; CONSISTENCY_PENALTY_APPLIED

Example C — Exam + project + conference (low-weighted type down-weighted)

Scenario. Same skill adds conference evidence (aggregated 6.0) alongside exam 8.0 and project 7.0.

Why this matters. Under default / version1 weights, CONFERENCES is one of the two low-weighted types (with SELF_ASSESSMENT). Because two top-weighted types (EXPERIENCE / PROJECTS / EXAMS — here exam + project) are present, CONFERENCES uses configured weight × 0.4 before normalization, so a light conference line cannot outweigh exam + project. (AWARDS would not get this treatment — it is mid-mass.)

Pipeline.

Step Outcome
Effective weights before normalize EXAMS 0.17; PROJECTS 0.18; CONFERENCES 0.02×0.4 = 0.008
Sum 0.358 → dynamic ≈ 0.475 / 0.503 / 0.022
Contributions sum 7.45
Completeness +0.10 → weightedCore ≈ 7.55
Diversity +0.40 (three types)
Consistency 0.065
Model final 7.89

Per-type snapshot

Type configuredWeight effective before norm dynamicWeight (illustr.) sourceScore weightedContribution (illustr.)
EXAMS 0.17 0.17 0.475 8.0 3.80
PROJECTS 0.18 0.18 0.503 7.0 3.52
CONFERENCES 0.02 0.008 0.022 6.0 0.13

Ledger totals and flags

Field Value (illustr.)
weightedCore ~7.55
completenessBonus 0.10
diversityBonus 0.40
consistencyPenalty ~0.065
finalScore ~7.89
formulaDecisions Includes LOW_PRIORITY_DOWNWEIGHTED and the same bonus/penalty flags as B

Example D — Certification + publication (no top-three coverage)

Scenario. Only CERTIFICATIONS (8.0) and PUBLICATIONS (7.0)—no exam, project, or experience.

Why this matters. Weights still redistribute (67% / 33% by 0.10 vs 0.05), so the student is not forced to zero on missing exams. But no completeness bonus applies, because neither type is in the configured top three.

Pipeline.

Step Outcome
Dynamic split CERT ~0.667; PUB ~0.333
Contribution sum 7.67
Completeness 0
weightedCore ~7.67
Diversity 0.20
Consistency ~0.04
Model final ~7.83

formulaDecisions: DYNAMIC_WEIGHT_REDISTRIBUTION only among bonuses/penalties (no COMPLETENESS_BONUS_APPLIED).


Example E — Single publication (profile-only cap)

Scenario. Only PUBLICATIONS, aggregated 9.0.

Why this matters. For one evidence type that is not CERTIFICATIONS / PROJECTS / EXAMS / EXPERIENCE, the engine caps the published score at profile_only_max_cap (default 5.5) so a single weak-category line cannot look like a full-strength profile.

Stage Value
weightedCore 9.0
diversity / consistency 0
Pre-cap model total 9.0
finalScore (ledger + profile) 5.5 (cap applied)

Note: weighted_core in the ledger still reflects contributions + completeness; final_score is after cap (and decay/override if any).


Example F — Human override after a computed score

Scenario. Model result ~7.75 (as in Example B under version1); admin sets governed override 8.50.

Why this matters. Auditors read modelFinalScoreBeforeOverride vs finalScore; the ledger **final_score ** stores what students and HR see (8.50).

Output Value
finalScore / final_skill_score 8.50
modelFinalScoreBeforeOverride (explainability) ~7.75
humanOverrideApplied true
confidenceScore Usually unchanged from model path
formulaDecisions Includes HUMAN_OVERRIDE_APPLIED (plus prior model flags)

Example G — Institutional vs employer-visible headline scores

Scenario. One evidence row is INTERNAL (campus-only); another is BOTH (counts for employer view). Institutional scoring sees two types; employer bundle sees one.

Why this matters. There is one institutional computation-history row per skill recompute (institutional pipeline). The profile still exposes employer_visible_final_score when the employer bundle is non-empty.

Where What it reflects
skill_score_computation / history Institutional weights and evidence set
final_skill_score Institutional, after cap / decay / override
employer_visible_final_score Employer-visible subset only, same formula path
explainability: employerVisibleFinalScore Recruiter-oriented headline when present
explainability: sourceWeights Dynamic (or configured) weights for the profile context—employer-only rows can collapse to one type at 100%

Example H — Job match (JobMatchResultDto)

Scenario. Job mandatory: Java min 7.0, SQL min 6.0. Student scores 3.15 and 4.54 (both **unmet **). Nice-to-have rollup yields niceToHaveFitScore = 72. Mean profile confidence 62.

Why this matters. Mandatory fit still averages min(100, score/minRequired×100) per line—even when the bar is failed—then combines with nice-to-have and confidence. If mandatoryPass is false, stored final_match_score is half the blended score.

Mandatory lines (illustrative)

Skill minRequired student score Line fit % Met?
Java 7.0 3.15 45.0 No
SQL 6.0 4.54 75.67 No

Derived match fields

Field Value How
mandatoryCoveragePct 0 0 of 2 mandatory met
mandatoryPass false At least one unmet
mandatoryFitScore ~60.33 Average of 45.0 and 75.67
niceToHaveFitScore 72 From nice-to-have requirements
evidence / confidence input 62 Mean confidence across student profiles
Blended (pre-gate) ~63.5 0.6×60.33 + 0.25×72 + 0.15×62
finalMatchScore ~31.75 × 0.5 when mandatoryPass is false

API record (JobMatchResultDto fields)

Field Illustrative value
studentId 120835
mandatoryPass false
mandatoryCoveragePct 0.0
mandatoryFitScore 60.33
niceToHaveFitScore 72.0
finalMatchScore 31.75
student null (often filled by caller)

Embedded match explainability (string explainabilityJson — logical columns)

Key Value
mandatoryCoverage 0.0
mandatoryFit 60.33
niceToHaveFit 72.0
confidence 62.0
scorePerspective INSTITUTIONAL or EMPLOYER_VISIBLE per useEmployerVisibleScores

Reconciling outputs (checklist)

# Check
1 Dynamic weights on types with score sum to 1.0 (others 0).
2 weightedCore ≈ sum of weightedContributions + completenessBonus.
3 Model raw = clamp [0,10] of (weightedCore + diversityBonus − consistencyPenalty); then profile-only cap; then skill decay; then override → matches finalScore on ledger and final_skill_score.
4 computationReason matches the trigger (e.g. EVIDENCE_UPDATE, MANUAL_RECOMPUTE, FORMULA_PUBLISH_RECOMPUTE).

Actor responsibilities

Students

University placement admin / TPO

Guideline examples (policy, not automatic API validation):

Company HR / recruiters

Skill matrix engine (system)

Real-time scenarios

End-to-end behaviors below map to tables and numeric outputs in * Worked examples in tables* (Examples A–H).

1) Student adds certification

2) Student adds production project

3) Student has only certification + publication (no exams/projects)

4) Exam signal in this service

5) Skill time decay (optional)

6) Recruiter job matching (JobMatchingService)

7) Formula version change (admin)

8) Manual recompute / override

9) Async failure hygiene

Rubric presets: system defaults vs tenant overrides

Reference anchors ship in V2__rubric_preset_seed.sql (tenant_id NULL). They set the institutional starting score (0–10) used in the calibrated anchor when ingest does not override base_score. Higher = stronger default signal for that evidence class.

System rubric anchors (V2 seed, business view)

Evidence type / tier Rubric score (0–10) One-line meaning (from seed description)
(fallback) 5.0 Neutral anchor when no rule matches
PUBLICATIONS 8.5 Peer-reviewed / reputable publication
PATENTS 9.0 Granted patent
CERTIFICATIONS 8.0 Vendor / industry certification
EXAMS 7.5 Formal proctored or institution exam
EXPERIENCE 7.5 Employment / internship with outcomes
COMPETITIONS 7.2 Ranked or adjudicated competition
PROJECTS 7.0 Substantive project / portfolio work
AWARDS 7.0 Recognized award or honor
HACKATHONS 6.8 Time-boxed build event
TRAININGS 6.5 Structured course / workshop
CONFERENCES 6.5 Talk, poster, or participation
SELF_ASSESSMENT 4.5 Learner-declared—pair with other evidence
CERT … foundational 7.0 Entry-tier cert
CERT … associate 7.5 Associate-level cert
CERT … professional 8.5 Professional-tier cert
CERT … specialty 9.0 Specialty / expert-tier cert
PROJECT … course 6.5 Course / lab project
PROJECT … capstone 8.0 Capstone / major project
PROJECT … production 8.5 Production / real users

Tenant overrides: tenant_id set on a row applies only to that tenant; priority and specificity decide which row wins (RubricPresetService). GET /skill-matrix/rubric-presets/options supports UI and ingest.

Controls for high accuracy and trust

What to monitor daily

Definition of done for enterprise rollout