How Bonus Points and Deductions Are Handled in Resume Scoring: A Technical Guide to the Hiring-Agent Repository
Bonus points are added to and deductions are subtracted from the aggregated category scores, with the final total capped at the maximum possible score plus a 20-point bonus ceiling.
The interviewstreet/hiring-agent repository provides a structured resume evaluation system that scores candidates across four core categories before applying adjustments. Understanding how bonus points and deductions in resume scoring are mathematically processed and stored is crucial for customizing evaluation pipelines or auditing results. This guide examines the specific Pydantic models, calculation logic in the scoring module, and CSV export mechanisms that manage these adjustments.
Pydantic Models for Adjustments
Defining Bonus Points and Deductions in models.py
In models.py (lines 31–42), the system defines BonusPoints and Deductions as Pydantic models that encapsulate these adjustments. The BonusPoints model restricts the total field to a range of 0–20 points, while Deductions stores a non-negative total (the negative sign is applied during calculation). Both models include descriptive fields—breakdown for bonuses and reasons for deductions—that provide human-readable context for the numeric adjustments.
Score Calculation Logic in score.py
Aggregating and Adjusting the Final Score
The core arithmetic occurs in score.py (lines 57–68). After summing the four core category scores (Open Source, Self Projects, Production, Technical Skills), the function adds evaluation.bonus_points.total and subtracts evaluation.deductions.total. The computed sum is then bounded by max_possible_score, defined as the sum of category maximums plus the 20-point bonus ceiling.
Reporting Bonuses and Deductions
The print_evaluation_results function (lines 71–84) handles display logic. It prints a "BONUS POINTS" block showing the total and breakdown when bonuses exist, and a "DEDUCTIONS" block when the deduction total exceeds zero. This mirrors the internal calculation and provides transparency in the evaluation output.
Data Export in transform.py
When persisting evaluation data, transform_evaluation_response in transform.py (lines 15–22) maps adjustment data to four specific CSV columns: bonus_points and bonus_breakdown for bonuses, and deductions and deduction_reasons for deductions. This structure enables detailed analytics on how adjustments influence final candidate rankings.
Implementation Examples
Creating an Evaluation with Bonus Points and Deductions
from models import (
CategoryScore,
Scores,
BonusPoints,
Deductions,
EvaluationData,
)
# Core category scores
scores = Scores(
open_source=CategoryScore(score=30, max=35, evidence="..."),
self_projects=CategoryScore(score=25, max=30, evidence="..."),
production=CategoryScore(score=20, max=25, evidence="..."),
technical_skills=CategoryScore(score=8, max=10, evidence="..."),
)
# Bonus points earned (e.g., for a hackathon win)
bonus = BonusPoints(total=12.5, breakdown="Hackathon winner (+12.5)")
# Deductions (e.g., missing contact info)
deductions = Deductions(total=3, reasons="Missing phone number")
# Full evaluation object
evaluation = EvaluationData(
scores=scores,
bonus_points=bonus,
deductions=deductions,
key_strengths=["Strong open‑source contributions"],
areas_for_improvement=["Add a professional summary"],
)
# Print the formatted results (including bonus & deductions)
from score import print_evaluation_results
print_evaluation_results(evaluation, candidate_name="Alice Example")
Running this script produces formatted output including the bonus and deduction details:
⭐ BONUS POINTS: 12.5
Hackathon winner (+12.5)
⚠️ DEDUCTIONS: -3
Missing phone number
Exporting to CSV Format
from transform import transform_evaluation_response
row = transform_evaluation_response(
file_name="alice_resume.pdf",
resume_data=None, # (omitted for brevity)
github_data=None,
evaluation=evaluation,
)
print(row["bonus_points"], row["deductions"])
# → 12.5 3
The resulting dictionary contains bonus_points, bonus_breakdown, deductions, and deduction_reasons ready for CSV serialization.
Summary
- Bonus points are capped at 20 points and defined in the
BonusPointsmodel inmodels.py(lines 31–42). - Deductions are stored as non-negative values in the
Deductionsmodel, with subtraction applied during final score calculation inscore.py. - The final score is computed by adding bonuses and subtracting deductions from the core category scores, then capping at
max_possible_score(category maximums plus 20). - Both adjustments are exported via
transform.pyinto dedicated CSV columns for downstream analysis.
Frequently Asked Questions
What is the maximum number of bonus points allowed?
The BonusPoints model in models.py enforces a hard limit of 20 points on the total field. This constraint is also respected in the final score calculation in score.py, where the max_possible_score equals the sum of category maximums plus 20.
How does the system prevent negative total scores?
While deductions are stored as non-negative values in the Deductions model, the subtraction occurs during final aggregation in score.py. The system caps the final result to realistic boundaries, though the underlying arithmetic processes the raw values before capping.
Where is the final score calculation performed?
The definitive calculation occurs in score.py within the evaluation results processing logic (lines 57–68). This function aggregates the four core category scores, applies the bonus addition and deduction subtraction, and enforces the maximum score boundary.
How are bonus points and deductions exported for analysis?
The transform_evaluation_response function in transform.py (lines 15–22) maps these values to four distinct CSV columns: bonus_points and bonus_breakdown for bonuses, and deductions and deduction_reasons for deductions. This enables detailed post-processing and reporting workflows.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →