# How the Caching Mechanism Functions in Development Mode in Hiring Agent

> Learn how the hiring agent caching mechanism works in development mode. Understand when to clear the cache for faster résumé parsing and API calls.

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

---

**In development mode, the hiring-agent repository uses a lightweight file-based JSON cache to speed up résumé parsing and GitHub API calls, automatically bypassing these caches in production and self-healing by removing corrupted files.**

The `interviewstreet/hiring-agent` repository implements a deterministic file-based caching system governed by the `DEVELOPMENT_MODE` configuration flag. When enabled, this mechanism stores intermediate processing results to eliminate redundant API requests and PDF parsing during iterative development. The caching mechanism functions exclusively in development environments, ensuring production deployments always retrieve fresh data directly from sources.

## How Development Mode Activates the Cache

The cache system hinges on the `DEVELOPMENT_MODE` boolean defined in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py). When this value is set to `True` (the default for local development), conditional blocks throughout the codebase activate file-based caching behaviors. In production environments where `DEVELOPMENT_MODE` is `False`, these conditional branches are skipped entirely, forcing the application to process PDFs and fetch GitHub data from live sources on every execution.

The cache directory is created dynamically using `os.makedirs(..., exist_ok=True)`, ensuring the system fails gracefully on first run without requiring manual directory setup.

## Resume Parsing Cache in score.py

The résumé parsing pipeline in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (specifically around lines 227-260) implements caching for parsed PDF content to avoid reprocessing identical files during development iterations.

When [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) initializes, it checks for the existence of a cache file before invoking the parser:

```python

# development-mode cache check

if DEVELOPMENT_MODE and os.path.exists(cache_filename):
    print(f"Loading cached data from {cache_filename}")
    try:
        cached_data = json.loads(Path(cache_filename).read_text(encoding="utf-8"))
        loaded_resume = JSONResume(**cached_data)
        cache_loaded = True
    except Exception as e:
        print(f"⚠️ Warning: Invalid cache file {cache_filename}: {e}")
        print("Ignoring cache and reprocessing PDF...")
        os.remove(cache_filename)

```

If no valid cache exists, the system parses the PDF and writes the resulting JSON representation to `cache/resumecache_*.json`:

```python
if not cache_loaded:
    # ... parsing logic ...

    if resume_data_is_valid:
        os.makedirs(os.path.dirname(cache_filename), exist_ok=True)
        Path(cache_filename).write_text(
            json.dumps(resume_dict, ensure_ascii=False, indent=2), encoding="utf-8"
        )

```

## GitHub API Response Caching in github.py

The GitHub integration module in [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) (lines 35-50) employs an identical pattern to avoid rate-limiting issues and speed up repeated API calls during development.

Before executing an HTTP request, the code checks for a cached response:

```python
cache_filename = _create_cache_filename(api_url, params)
if DEVELOPMENT_MODE and os.path.exists(cache_filename):
    print(f"Loading cached GitHub data from {cache_filename}")
    try:
        cached_data = json.loads(Path(cache_filename).read_text(encoding="utf-8"))
        if cached_data:
            return 200, cached_data
    except Exception as e:
        print(f"⚠️ Warning: Error reading cache file {cache_filename}: {e}")
        os.remove(cache_filename)

```

Successful API responses are persisted immediately upon retrieval:

```python
if DEVELOPMENT_MODE and status_code == 200:
    os.makedirs("cache", exist_ok=True)
    Path(cache_filename).write_text(
        json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8"
    )

```

## Cache Naming Conventions and Storage Structure

Cache files follow deterministic naming schemes based on input parameters to ensure consistent cache hits across application restarts. Résumé caches use the pattern `resumecache_*.json` derived from the source PDF filename, while GitHub caches use `gh_githubcache_*.json` based on the API URL and request parameters.

All cache files are stored in a `cache/` subdirectory at the project root. The system automatically creates this directory when writing the first cache entry, eliminating setup friction for new development environments.

## Automatic Corruption Detection and Recovery

The caching mechanism implements robust error handling to prevent stale or corrupted data from crashing the application. If `json.loads()` raises an exception during cache retrieval—whether due to manual file editing, disk corruption, or schema changes—the system immediately deletes the offending file using `os.remove(cache_filename)` and falls back to fresh processing.

This self-healing behavior ensures that developers never need to manually intervene when cache files become invalid; the system transparently reprocesses the source data and generates a new cache entry on the next successful execution.

## When to Manually Clear the Development Cache

While the system handles corrupted files automatically, you should manually clear the cache directory in several specific scenarios:

- **Content updates with identical filenames**: If you modify a PDF's contents but retain the original filename, the deterministic cache key will return stale parsed data. Delete the specific `resumecache_*.json` file to force reprocessing.
- **Schema changes**: When updating the `JSONResume` model or GitHub response parsing logic, existing cache files may contain incompatible data structures. Clear the entire `cache/` directory to prevent deserialization errors.
- **Debugging freshness issues**: If you suspect cached data is masking recent changes to GitHub repositories or résumé content, removing the relevant cache files ensures you are viewing live data without disabling `DEVELOPMENT_MODE`.

To clear the cache, simply delete the `cache/` directory or specific `*.json` files within it before running the application.

## Summary

- The caching mechanism functions exclusively when `DEVELOPMENT_MODE` is `True` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), with production runs always fetching fresh data.
- [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) caches parsed résumé JSON as `resumecache_*.json` files to avoid redundant PDF processing during development iterations.
- [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) stores API responses as `gh_githubcache_*.json` to prevent repeated HTTP requests and rate-limiting delays.
- Cache files use deterministic naming based on input parameters and are stored in an auto-generated `cache/` directory.
- Corrupted cache files trigger automatic deletion and reprocessing, while manual clearing is required when source content changes but filenames remain constant.

## Frequently Asked Questions

### Where are the cache files stored in the hiring-agent repository?

Cache files are stored in the `cache/` directory at the project root. The system creates this directory automatically using `os.makedirs(..., exist_ok=True)` when writing the first cache entry, so no manual setup is required.

### Does the caching mechanism work in production mode?

No. When `DEVELOPMENT_MODE` is set to `False` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), all cache conditional blocks are bypassed. The application always parses PDFs fresh and makes live GitHub API requests, ensuring production data is never stale.

### How does the system handle corrupted cache files?

If reading a cache file raises an exception—whether from JSON syntax errors, schema mismatches, or disk corruption—the system prints a warning message, deletes the file using `os.remove(cache_filename)`, and immediately reprocesses the source data to generate a fresh cache entry.

### When should I manually delete cache files?

Manually clear cache files when you modify PDF contents without renaming the file (since cache keys are based on filenames), when updating data models that change the expected JSON structure, or when debugging to ensure you are viewing live API responses rather than cached data.