# How Hiring Agent Validates Cached Resume Data to Ensure Integrity

> Discover how Hiring Agent ensures resume data integrity. Learn about Pydantic validation, automatic cache deletion, and reprocessing to maintain accurate hiring decisions.

- Repository: [HackerRank/hiring-agent](https://github.com/interviewstreet/hiring-agent)
- Tags: internals
- Published: 2026-07-17

---

**The Hiring Agent validates cached resume data by using Pydantic schema validation in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) and [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py), automatically deleting corrupted cache files and reprocessing PDFs when validation fails, ensuring only structurally valid data influences hiring decisions.**

When processing résumé PDFs, the `interviewstreet/hiring-agent` repository stores JSON representations on disk under the `cache/` directory to speed up development workflows. To ensure cached resume data integrity, the system implements a multi-layer validation strategy that combines strict schema enforcement with automatic corruption recovery.

## The Cache Validation Pipeline

The validation flow follows a four-step process that ensures only verified data enters the hiring pipeline.

### Step 1: Development-Mode Cache Detection

The system consults cached files only when `DEVELOPMENT_MODE` is enabled in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py). This guard prevents accidental use of stale data in production environments. The code checks for files matching the pattern `cache/resumecache_<pdf-name>.json` before attempting to load them.

### Step 2: Schema Validation with Pydantic

When a cache file exists, the code loads it using `json.loads()` and instantiates the `JSONResume` Pydantic model from [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py). According to the source code in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (lines 225-232), this construction validates the JSON schema against required fields, data types, and value constraints. If the JSON is malformed or violates the schema, the constructor raises an exception immediately.

### Step 3: Self-Healing Error Handling

If any exception occurs during loading or validation, the system removes the corrupted file and falls back to reprocessing the PDF. As implemented in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (lines 236-242), the exception handler prints a warning, deletes the invalid cache file using `os.remove(cache_filename)`, and proceeds to extract the résumé from the original PDF. This ensures that no stale or tampered data persists in the cache.

### Step 4: Conditional Cache Writing

After reprocessing, the system only writes a new cache file if the extracted data passes validation. The code in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (lines 258-262) checks `if newly_extracted_resume.is_valid():` before writing the JSON to disk. Invalid or empty resume data triggers the message "Newly extracted resume data is empty/invalid. Skipping cache write," preventing broken cache entries from ever being created.

## Implementation in score.py and github.py

The validation logic appears in both the résumé processor and the GitHub data fetcher.

In [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py), the flow handles PDF extraction caching:

```python
from pathlib import Path
import json
import os
from models import JSONResume

# Build cache filename from PDF path

cache_filename = f"cache/resumecache_{Path(pdf_path).stem}.json"

# Attempt to load cached data

if DEVELOPMENT_MODE and os.path.exists(cache_filename):
    try:
        cached_data = json.loads(Path(cache_filename).read_text(encoding="utf-8"))
        loaded_resume = JSONResume(**cached_data)  # Pydantic validation

    except Exception as e:
        print(f"⚠️ Warning: Invalid cache file {cache_filename}: {e}")
        print("Ignoring cache and reprocessing PDF…")
        os.remove(cache_filename)  # Delete corrupted cache

        loaded_resume = None

```

In [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) (lines 34-49), the same pattern applies to API response caching using the `_create_cache_filename` helper. The code attempts to load cached JSON, validates it against the expected structure, and deletes the file if parsing fails.

## Key Integrity Mechanisms

The Hiring Agent employs four specific safeguards to guarantee cached resume data integrity:

- **Schema enforcement**: The `JSONResume` Pydantic model validates all required fields, data types, and constraints upon instantiation.
- **Exception-driven fallback**: Any loading or parsing error triggers immediate cache deletion and fresh reprocessing.
- **Development-mode guard**: The `DEVELOPMENT_MODE` flag ensures caches are only consulted in controlled environments.
- **Write-only-when-valid**: The system skips caching entirely when `is_valid()` returns false, preventing storage of malformed extractions.

## Practical Code Example

The following complete example demonstrates the full validation workflow:

```python
from pathlib import Path
import json
import os
from models import JSONResume

DEVELOPMENT_MODE = True
pdf_path = "resumes/jane_doe.pdf"

# 1️⃣ Build cache filename

cache_file = f"cache/resumecache_{Path(pdf_path).stem}.json"

# 2️⃣ Try to load cached resume

if DEVELOPMENT_MODE and os.path.exists(cache_file):
    try:
        data = json.loads(Path(cache_file).read_text())
        resume = JSONResume(**data)  # Validates schema

        print("✅ Loaded resume from cache")
    except Exception as exc:
        print(f"⚠️ Invalid cache: {exc}")
        os.remove(cache_file)  # Clean corrupted cache

        resume = None
else:
    resume = None

# 3️⃣ If cache miss or invalid, re-process PDF and cache result

if resume is None:
    resume = extract_resume_from_pdf(pdf_path)  # Your PDF-parsing logic

    if resume.is_valid():
        Path(cache_file).write_text(json.dumps(resume.dict()))
        print("🗂️ Cached fresh resume")
    else:
        print("❌ Resume data invalid – not caching")

```

This pattern in [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) follows identical validation logic for API responses, replacing the file path and JSON model with the GitHub response model.

## Summary

- Hiring Agent validates cached resume data using **Pydantic schema validation** via the `JSONResume` model in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py).
- Corrupted cache files are **automatically deleted** and the system falls back to reprocessing the original PDF.
- The **`DEVELOPMENT_MODE`** flag ensures caching only occurs in development environments, preventing production reliance on stale data.
- New cache entries are written only when **`is_valid()`** returns true, ensuring broken extractions never persist.
- The same validation pattern appears in [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) for GitHub API response caching.

## Frequently Asked Questions

### What happens if the cached JSON file is corrupted?

If the cached JSON is malformed or violates the schema, the `JSONResume` constructor raises an exception. The code catches this in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (lines 236-242), prints a warning, deletes the corrupted file using `os.remove()`, and reprocesses the PDF from scratch.

### How does Hiring Agent prevent invalid data from being cached?

Before writing to the cache, the code checks `if newly_extracted_resume.is_valid():` as shown in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (lines 258-262). Only valid resume data is serialized to disk; empty or invalid extractions are skipped with a console warning.

### Is the cache used in production environments?

No. The cache is only consulted when `DEVELOPMENT_MODE` is enabled in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py). This guard ensures that production pipelines always process fresh PDFs and never rely on potentially stale cached data from the `cache/` directory.

### Does the GitHub data caching use the same validation strategy?

Yes. The [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) file implements identical validation logic using the `_create_cache_filename` helper. It loads cached JSON, validates the structure, and deletes the file if any parsing errors occur, ensuring only well-formed API responses are reused.