How career-ops Separates User-Layer and System-Layer Files: A Two-Tier Data Contract

santifer/career-ops enforces a strict two-tier data contract that isolates personal user data in the user-layer from core system code in the system-layer, ensuring user customizations survive repository upgrades while allowing automated system updates.

The open-source career management framework career-ops implements a rigorous separation of concerns between user-owned content and system-provided functionality. This architecture, defined in AGENTS.md, prevents accidental data loss during updates by distinguishing between files that serve as the source of truth for your career data and those that power the evaluation engine.

Understanding the Two-Tier Architecture

User-Layer Files (Immutable User Data)

These files constitute your personal data vault and are never overwritten automatically. According to the source code in AGENTS.md, this layer includes your canonical CV (cv.md), personal profile configuration (config/profile.yml), custom archetypes (modes/_profile.md), and tracker data such as article-digest.md, portals.yml, and contents of data/, documents/, reports/, output/, and interview-prep/ directories. The system treats these as the source of truth for all user-visible output. When you define target roles, salary expectations, or personal narratives, the agent must write exclusively to these user-layer files.

System-Layer Files (Auto-Updatable Engine)

All remaining infrastructure—including scripts, templates, and shared definitions—comprises the system layer. These files, including modes/_shared.md, all .mjs scripts (such as scan.mjs and set-status.mjs), templates/, dashboard utilities in dashboard/, batch processing helpers in batch/, and instruction definitions like CLAUDE.md, CODEX.md, and AGENTS.md itself, are updated automatically via update-system.mjs without affecting user data. The source code explicitly prohibits embedding user-specific content in these files to prevent overwrite collisions during upstream updates.

Enforcement Rules That Prevent Data Loss

Rule 1: Never Write User Data to System Files

The primary constraint requires that all personalization—including custom archetypes, compensation targets, and narratives—be persisted only to modes/_profile.md or config/profile.yml. Editing system-layer files such as modes/_shared.md with user-specific data violates this contract and risks destruction during automated updates.

Rule 2: Isolate Procedural Customizations

Custom workflow preferences belong in modes/_custom.md, a user-layer file instantiated from a template when missing. This separation allows you to override system behaviors without modifying the underlying engine code, preserving your workflow rules across system updates.

Rule 3: Enable Automated System Updates

Files in the system-layer are explicitly designated as auto-updatable. The update-system.mjs script modifies only these files—such as core .mjs automation scripts and shared mode definitions—ensuring you receive bug fixes and features without manual intervention.

Practical Implementation Examples

The following examples demonstrate correct versus incorrect file operations according to the career-ops data contract.

When adding a new target role, always modify the user-layer configuration:

// ✅ Correct: edit config/profile.yml (user layer)
import yaml from 'js-yaml';
import fs from 'fs';
const profile = yaml.load(fs.readFileSync('config/profile.yml', 'utf8'));
profile.targets.push('Senior Data Engineer');
fs.writeFileSync('config/profile.yml', yaml.dump(profile));

// ❌ Incorrect: editing a system script
// This would break the system‑layer rule
// const script = fs.readFileSync('modes/_shared.md', 'utf8');
// // ... modify script with user data – DISALLOWED

To update the system-layer safely without touching user data:


# Updating system‑layer code via the built‑in updater (safe for system files)

node update-system.mjs apply   # touches only system‑layer files

# User‑layer files remain untouched

File Reference: User vs. System Layers

Tier Important Files Purpose
User‑Layer cv.md Canonical CV (source of truth).
config/profile.yml Personal profile, salary targets, language settings.
modes/_profile.md User‑specific archetypes and narrative.
modes/_custom.md Custom workflow rules (generated from template).
article-digest.md, portals.yml, data/*, documents/*, reports/*, output/*, interview-prep/* Tracker, documents, generated artifacts – all user‑owned.
System‑Layer modes/_shared.md Shared mode definitions, never edited for a single user.
*.mjs scripts (e.g., scan.mjs, set-status.mjs) Core engine logic.
templates/* PDF/LaTeX templates, state definitions.
AGENTS.md, CLAUDE.md, CODEX.md, OPENCODE.md Agent and instruction definitions.
dashboard/*, batch/* Automation and batch processing helpers.

Summary

  • santifer/career-ops implements a strict two-tier data contract that isolates personal data from system code.
  • User-layer files (cv.md, config/profile.yml, modes/_profile.md, etc.) serve as the immutable source of truth and are never overwritten by automated updates.
  • System-layer files (.mjs scripts, modes/_shared.md, templates) power the evaluation engine and are maintained via update-system.mjs.
  • Enforcement rules prohibit writing user data to system files, ensuring personalization survives repository upgrades.
  • Custom workflows belong in modes/_custom.md, keeping procedural overrides separate from core logic.

Frequently Asked Questions

What happens if I accidentally edit a system-layer file with my personal data?

If you embed user-specific content in system-layer files such as modes/_shared.md or .mjs scripts, that data will be destroyed when update-system.mjs applies upstream changes. Always redirect personal edits to config/profile.yml or modes/_profile.md to prevent data loss.

How do I safely update the career-ops system without losing my data?

Run node update-system.mjs apply from the repository root. This command touches only system-layer files such as core scripts and shared definitions, leaving your user-layer files (cv.md, profile configurations, and tracker data) completely untouched.

Which file should I edit to add custom job search rules?

Add custom workflow preferences to modes/_custom.md, which is a user-layer file generated from a template if missing. This keeps your procedural modifications separate from the system engine while ensuring they persist through updates.

Are user-layer files tracked in version control?

Yes. User-layer files are kept under version control but are excluded from bulk system updates. This allows you to track changes to your CV and profile over time while still receiving automated improvements to the underlying career-ops engine.

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 →