# Which User-Layer Files Are Automatically Protected From System Updates in CareerOps

> Discover which CareerOps user layer files are automatically protected from system updates. Learn how your CV, notes, and config files stay safe during updates.

- Repository: [Santiago Fernández de Valderrama/career-ops](https://github.com/santifer/career-ops)
- Tags: how-to-guide
- Published: 2026-08-22

---

**All files enumerated in the [`DATA_CONTRACT.md`](https://github.com/santifer/career-ops/blob/main/DATA_CONTRACT.md) User Layer table—including your CV, application tracker, interview notes, and personal configuration files—are automatically shielded from modification and will never be overwritten by the `update-system.mjs` script.**

CareerOps (santifer/career-ops) implements a strict **Data Contract** architecture that partitions the repository into a mutable System Layer and an immutable User Layer. Understanding which user-layer files are automatically protected from system updates in CareerOps ensures your personal data, customizations, and job-search history remain intact when upgrading the framework.

## Understanding the Data Contract Architecture

The protection mechanism centers on [`DATA_CONTRACT.md`](https://github.com/santifer/career-ops/blob/main/DATA_CONTRACT.md), the central source of truth that explicitly enumerates every path belonging to the User Layer. According to the contract specification:

> “If a file is in the User Layer, no update process may read, modify, or delete it.” — [[`DATA_CONTRACT.md`](https://github.com/santifer/career-ops/blob/main/DATA_CONTRACT.md)](https://github.com/santifer/career-ops/blob/main/DATA_CONTRACT.md#L70)

This rule is enforced by the `update-system.mjs` script, which consults the User Layer list before applying any upstream changes. Files matching these protected paths are excluded from automatic updates, while files in the System Layer (scripts, templates, and core logic) can be safely overwritten.

## Complete List of Protected User-Layer Files

The Data Contract organizes protected files into logical categories based on their function within your job-search workflow.

### Core Personal Data Files

These files contain your identity, CV content, and foundational configuration:

- **[`cv.md`](https://github.com/santifer/career-ops/blob/main/cv.md)** — Your canonical markdown CV and primary professional narrative.
- **[`config/profile.yml`](https://github.com/santifer/career-ops/blob/main/config/profile.yml)** — Identity definitions, target roles, and strategic positioning parameters.
- **[`config/cv-facts.json`](https://github.com/santifer/career-ops/blob/main/config/cv-facts.json)** — Fact-check allowlist for CV accuracy validation.
- **[`config/benchmarks.yml`](https://github.com/santifer/career-ops/blob/main/config/benchmarks.yml)** — Optional market compensation benchmarks and comparison data.
- **[`config/local-paths.txt`](https://github.com/santifer/career-ops/blob/main/config/local-paths.txt)** — Fork-local path configurations specific to your environment.

### Customization and Profile Files

These files define your narrative archetypes, voice guardrails, and procedural preferences:

- **[`modes/_profile.md`](https://github.com/santifer/career-ops/blob/main/modes/_profile.md)** — Psychological archetypes, narrative frameworks, and negotiation scripts.
- **[`modes/_custom.md`](https://github.com/santifer/career-ops/blob/main/modes/_custom.md)** — Procedural rules, output formatting preferences, and custom instructions.
- **[`modes/_brief.md`](https://github.com/santifer/career-ops/blob/main/modes/_brief.md)** — Compact profile brief for quick reference.
- **[`voice-dna.md`](https://github.com/santifer/career-ops/blob/main/voice-dna.md)** — Voice guardrails and tonal consistency rules for generated content.

### Interview Preparation and Story Bank

These paths store your accumulated interview intelligence and company-specific research:

- **[`article-digest.md`](https://github.com/santifer/career-ops/blob/main/article-digest.md)** — Portfolio proof points and external validation snippets.
- **[`interview-prep/story-bank.md`](https://github.com/santifer/career-ops/blob/main/interview-prep/story-bank.md)** — Accumulated STAR+R stories and behavioral examples.
- **`interview-prep/{company}-{role}.md`** — Company-specific preparation notes (templated paths).
- **`interview-prep/sessions/*.md`** — Interview session transcripts and post-interview debriefs.

### Application Tracking and Pipeline Data

These files constitute the operational core of your job search and serve as the single source of truth:

- **[`data/applications.md`](https://github.com/santifer/career-ops/blob/main/data/applications.md)** — Master application tracker (the canonical record of all submissions).
- **`data/applications.db`** — Derived SQLite index (regenerated from [`applications.md`](https://github.com/santifer/career-ops/blob/main/applications.md)).
- **[`data/pipeline.md`](https://github.com/santifer/career-ops/blob/main/data/pipeline.md)** — URL inbox and opportunity queue.
- **`data/scan-history.tsv`** — Append-only history of job board scans.
- **`data/scan-runs.tsv`** — Per-run counters and scan metadata.
- **`data/portal-health.tsv`** — Portal availability and health status logs.

### Interaction and Follow-Up Records

These paths track your ongoing conversations and interview processes:

- **[`data/follow-ups.md`](https://github.com/santifer/career-ops/blob/main/data/follow-ups.md)** — Follow-up history and communication timelines.
- **[`data/active-interviews.md`](https://github.com/santifer/career-ops/blob/main/data/active-interviews.md)** — Active interview processes and stage tracking.
- **[`data/agent-inbox.md`](https://github.com/santifer/career-ops/blob/main/data/agent-inbox.md)** — Append-only request queue for automated agents.
- **[`data/reply-candidates.json`](https://github.com/santifer/career-ops/blob/main/data/reply-candidates.json)** — Normalized employer replies and response tracking.
- **`data/pdf-index.tsv`** — PDF-to-report linkage index.

### Personal Configuration and Plugins

These files store your local tool configuration and private extensions:

- **[`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml)** — Custom job portal list and source definitions.
- **[`config/plugins.yml`](https://github.com/santifer/career-ops/blob/main/config/plugins.yml)** — Enabled plugins and feature flags.
- **[`opencode.json`](https://github.com/santifer/career-ops/blob/main/opencode.json)** — OpenCode project configuration and environment settings.
- **`plugins.local/`** — Directory containing private, user-developed plugins.
- **`plugins.lock`** — Plugin integrity pins and version locks.

### Compensation and Outcomes Documentation

These files record salary data, offers, and final outcomes:

- **`data/salary-observations.tsv`** — Compensation observations and market data points.
- **`status-log.tsv`** — Status transition ledger and workflow state changes.
- **`data/offers/*`** — Received offers, negotiation notes, and preparation artifacts.
- **`data/outcomes/*`** — Outcome logs and archived application artifacts.

### Skill Development and Blacklist

These paths manage your learning pipeline and exclusion lists:

- **`data/upskill/*`** — Skill-gap analyses and learning plans.
- **[`data/blacklist.md`](https://github.com/santifer/career-ops/blob/main/data/blacklist.md)** — Do-not-apply list and exclusion criteria.
- **`data/assessments.tsv`** — Skills-assessment log and capability tracking.
- **`data/contacts.tsv`** — Job-search phonebook and networking contacts.

### User-Generated Content

These directories contain your original writing and generated outputs:

- **`documents/*`** — Raw intake sources (LinkedIn exports, diplomas, certificates).
- **[`data/intake-state.json`](https://github.com/santifer/career-ops/blob/main/data/intake-state.json)** — Fingerprint of ingested sources and processing state.
- **`writing-samples/*`** — Personal writing samples for style calibration (excluding system README).
- **`reports/*`** — Evaluation reports generated for each job description analysis.
- **`output/*`** — Generated PDFs and final application materials.
- **`jds/*`** — Saved job descriptions and posting archives.

## How the Update Mechanism Enforces Protection

The `update-system.mjs` script implements the Data Contract by cross-referencing every file operation against the User Layer enumeration. When the script detects a path matching the protected list, it skips that file regardless of upstream changes, ensuring zero data loss during framework upgrades.

This architectural choice creates a **immutable boundary** around your personal content. While System Layer files (such as core automation scripts and template generators) receive updates and bug fixes, User Layer files remain under your exclusive control.

## Verifying File Protection Programmatically

You can programmatically verify protection status using the Data Contract as an authority source.

### Check Protection Status Before Writing

```javascript
import { readFileSync } from 'fs';
import { execSync } from 'child_process';

// Extract protected paths from DATA_CONTRACT.md (simplified example)
const protectedPaths = [
  'cv.md',
  'config/profile.yml',
  'data/applications.md',
  'interview-prep/story-bank.md',
  'data/blacklist.md',
  // ... additional paths from the User Layer table
];

function safeWrite(filePath, content) {
  if (protectedPaths.some(p => filePath.startsWith(p) || filePath === p)) {
    console.warn(`⚠️  ${filePath} is User Layer protected and excluded from auto-updates.`);
    // Proceed with write or implement additional safeguards
  }
  // Write logic here
}

```

### List All Protected Files via CLI

```bash

# Assuming a utility script that parses DATA_CONTRACT.md

node list-user-files.mjs

# Expected output includes:

# cv.md

# config/profile.yml

# modes/_profile.md

# data/applications.md

# data/scan-history.tsv

# ...

```

### Prevent Accidental Overwrites in Automation

```javascript
#!/usr/bin/env node
const fs = require('fs');
const protected = require('./user-protected-list.json'); // Generated from DATA_CONTRACT.md

const target = process.argv[2];

if (protected.includes(target)) {
  console.error(`Refusing to overwrite protected User Layer file: ${target}`);
  process.exit(1);
}

fs.writeFileSync(target, 'new content');

```

## Summary

- **The Data Contract ([`DATA_CONTRACT.md`](https://github.com/santifer/career-ops/blob/main/DATA_CONTRACT.md))** explicitly defines the User Layer boundary that shields personal files from system updates.
- **Protected categories** include Core Personal Data ([`cv.md`](https://github.com/santifer/career-ops/blob/main/cv.md), [`config/profile.yml`](https://github.com/santifer/career-ops/blob/main/config/profile.yml)), Application Tracking ([`data/applications.md`](https://github.com/santifer/career-ops/blob/main/data/applications.md)), Interview Prep ([`interview-prep/story-bank.md`](https://github.com/santifer/career-ops/blob/main/interview-prep/story-bank.md)), and User Configuration ([`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml), `plugins.local/`).
- **The `update-system.mjs` script** enforces protection by skipping all User Layer paths during automatic updates.
- **Verification methods** allow you to programmatically confirm protection status before executing write operations.

## Frequently Asked Questions

### What happens if I accidentally modify a system-layer file?

If you modify a system-layer file, those changes will be overwritten the next time you run `update-system.mjs`, as the script only respects the User Layer boundary. To preserve customizations, migrate your changes into the User Layer (such as [`modes/_custom.md`](https://github.com/santifer/career-ops/blob/main/modes/_custom.md) or `plugins.local/`) or maintain them as separate patches outside the repository.

### How do I add a new file to the User Layer protection?

The protected file list is authoritative in [`DATA_CONTRACT.md`](https://github.com/santifer/career-ops/blob/main/DATA_CONTRACT.md). To add a new protected path, you must submit a pull request or fork modification that updates the User Layer table in the Data Contract. Once the contract recognizes the path as User Layer, the `update-system.mjs` script will automatically exclude it from future updates.

### Will my application history be deleted during a CareerOps update?

No. Your application history stored in [`data/applications.md`](https://github.com/santifer/career-ops/blob/main/data/applications.md) (and its derived `data/applications.db`) is explicitly listed in the User Layer. The update mechanism will never read, modify, or delete these files, preserving your complete job-search history across all system upgrades.

### Can I trust that my interview notes remain private during updates?

Yes. All interview preparation materials—including [`interview-prep/story-bank.md`](https://github.com/santifer/career-ops/blob/main/interview-prep/story-bank.md), company-specific prep files, and session transcripts—are classified as User Layer content. According to the Data Contract implemented in `update-system.mjs`, these files are completely invisible to the update process, ensuring your strategic notes and salary discussions remain private and unaltered.