How the Dual-Layer Data Architecture in Career-Ops Works: A Complete Guide

Career-Ops implements a dual-layer data architecture that strictly separates user-owned files (CVs, profiles, application trackers) from system-owned logic (scripts, modes, templates), ensuring personal data survives automatic updates while the automation codebase evolves freely.

The santifer/career-ops repository solves the upgrade dilemma through a dual-layer data architecture formalized in DATA_CONTRACT.md. This design creates an immutable boundary between files that belong to the candidate and files managed by the system. By enforcing this separation, Career-Ops guarantees that your personal data and customizations persist untouched even as evaluation scripts, scoring rules, and templates receive updates.

Understanding the Two Layers

User Layer (Immutable Personal Data)

Files in the user layer belong to the candidate and are protected from automatic updates. According to DATA_CONTRACT.md (lines 5-22), this layer includes:

  • cv.md – Your personal markdown CV
  • config/profile.yml – Personal identity, compensation targets, and constraints
  • modes/_profile.md – Custom archetypes, narrative positioning, and negotiation scripts
  • data/applications.md – The canonical application tracker (source of truth)
  • Writing samples and saved job descriptions

The contract explicitly defines the protection rule: “If a file is in the User Layer, no update process may read, modify, or delete it” (DATA_CONTRACT.md#L70-L74).

System Layer (Replaceable Automation Logic)

All remaining files constitute the system layer and can be safely replaced by new releases. As defined in DATA_CONTRACT.md (lines 27-35), this includes:

  • modes/_shared.md – Global scoring rules and shared utilities
  • modes/oferta.md – Evaluation mode instructions for single offers
  • merge-tracker.mjs – Script that merges tracker additions
  • templates/* – HTML templates used for PDF generation
  • docs/* – Documentation and architecture guides

The governing rule states that system-layer files “can be safely replaced with the latest version from the upstream repo” (DATA_CONTRACT.md#L70-L74).

How the Layers Interact in Practice

Evaluation Pipeline

When processing a job description, the system reads user-layer files as the source of truth. The evaluation logic residing in system-layer mode files such as modes/oferta.md and modes/_shared.md processes your cv.md and config/profile.yml, then writes outputs (reports, PDFs, and tracker entries) into user-layer directories including reports/, output/, and batch/tracker-additions/.

Tracker Management

The canonical tracker at data/applications.md lives in the user layer, meaning automation workers never edit it directly. Instead, they emit TSV lines into batch/tracker-additions/. The system-layer script merge-tracker.mjs then merges these additions into the user-owned file without overwriting existing entries, as documented in docs/ARCHITECTURE.md (lines 92-99).

Update Safety

When a new Career-Ops version releases, the update checker replaces only system-layer files. This guarantees that personal data and customizations in the user layer survive every upgrade, while new scoring rules in modes/_shared.md or templates in templates/cv-template.html update automatically.

Working with the Architecture

Adding Application Entries

To safely add a new application without touching the canonical tracker directly:


# Write a TSV line to the batch folder – the system script will merge it.

cat <<EOF > batch/tracker-additions/001-companyX.tsv
001\t$(date +%F)\tCompanyX\tSenior Engineer\tEvaluated\t4.3/5\t✅\t[001](reports/001-companyX-$(date +%F).md)\tInitial evaluation
EOF

Then execute the merge script:


# Run the merge script (system-layer) – safe because it only updates the tracker.

node merge-tracker.mjs

Verify the update preserved your history:


# Verify that the user-layer tracker contains the new row.

cat data/applications.md

Modifying Personal Archetypes

Update your personal definitions without fear of system overwrites:


# Edit modes/_profile.md – never touched by system updates.

sed -i 's/Backend Engineer/Data Engineer/g' modes/_profile.md

Key Files by Layer

Layer File Purpose
User cv.md Candidate's markdown CV
User config/profile.yml Personal identity and compensation targets
User modes/_profile.md Custom archetypes and negotiation scripts
User data/applications.md Canonical application tracker (source of truth)
System modes/_shared.md Global scoring rules and shared utilities
System modes/oferta.md Evaluation mode instructions
System merge-tracker.mjs Merges TSV additions into the user-layer tracker
System templates/cv-template.html HTML template for PDF generation

Summary

  • Career-Ops uses a dual-layer data architecture defined in DATA_CONTRACT.md to separate user data from system logic.
  • User Layer files (cv.md, config/profile.yml, data/applications.md) are immutable to system updates and contain personal data.
  • System Layer files (modes/_shared.md, merge-tracker.mjs, templates/*) can be replaced during updates without affecting user data.
  • The merge-tracker.mjs script respects this boundary by appending to rather than overwriting data/applications.md.
  • This architecture ensures your job search history and personal profiles survive codebase evolution.

Frequently Asked Questions

What happens if I modify a system-layer file?

If you modify files like modes/_shared.md or templates/cv-template.html, those changes will be overwritten when you update Career-Ops to a new version. To preserve customizations, maintain your changes in user-layer files (such as modes/_profile.md) which are excluded from the update process.

Can I move files between the user and system layers?

Moving files between layers violates the data contract and will break the update safety guarantees. The DATA_CONTRACT.md explicitly lists which paths belong to each layer (lines 5-35). Keep personal data only in the listed user-layer paths to ensure the update checker preserves your files.

How does the tracker merge process prevent data loss?

The merge-tracker.mjs script (system layer) reads TSV additions from batch/tracker-additions/ and appends them to data/applications.md (user layer) without truncating the existing file. As documented in docs/ARCHITECTURE.md (lines 92-99), this append-only approach ensures your historical application data remains intact even if the merge script itself receives updates.

Are user-layer files ever read by the system?

Yes, system-layer scripts read user-layer files as inputs. For example, evaluation modes read cv.md and config/profile.yml to generate personalized reports. However, the contract strictly prohibits system-layer processes from writing to, modifying, or deleting user-layer files, creating a read-only relationship that protects your data from corruption during automation.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →