# How career-ops Auto-Updates While Preserving User Data in the Data Layer

> Learn how career-ops auto-updates system files without touching your user data like CVs, profiles, and reports. Santifer/career-ops keeps your personal information safe during system refreshes.

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

---

**The `career-ops` updater script, `update-system.mjs`, separates system files from user files and refreshes only the system layer, leaving your personal CV, profile, and reports untouched.**

The `santifer/career-ops` repository implements a dedicated mechanism that shows how career-ops auto-updates while preserving user data in the **data layer** by strictly separating **system files** from **personal content**. By defining `SYSTEM_PATHS` and `USER_PATHS` in `update-system.mjs`, the tool refreshes core scripts and templates without ever touching your CV, profile, or reports. This boundary ensures that every update cycle is safe and predictable.

## System Layer vs. User Layer Design

In `update-system.mjs`, the update logic relies on two explicit constants to draw a hard boundary between code and data.

### How SYSTEM_PATHS Defines the Updater Scope

The constant **`SYSTEM_PATHS`** lists every file that belongs to the **system layer**. This includes core assets such as [`modes/_shared.md`](https://github.com/santifer/career-ops/blob/main/modes/_shared.md), files under `templates/`, and scripts like `generate-pdf.mjs`. When the updater runs, it targets **only** these paths, ensuring that no personal content is accidentally swept into a bulk checkout.

### How USER_PATHS Protects Personal Data

The companion constant **`USER_PATHS`** explicitly covers everything that belongs to the **user layer**. Entries include [`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), the `data/` directory, and the `reports/` directory. Because these paths are excluded from the update checkout, Git’s merge logic never interferes with your local data, even if the remote repository contains newer versions of system files.

## How the Auto-Update Process Works

When you run the updater from the command line, `update-system.mjs` executes a precise workflow that refreshes the core application without touching the data layer:

1. **Check the remote repository** for a newer version using `node update-system.mjs check`.
2. **Checkout only the paths listed in `SYSTEM_PATHS`** from the latest remote commit. The script never checks out or overwrites anything defined in `USER_PATHS`.
3. **Write the fetched system files** back to your local directory while leaving all user-layer files in their exact previous state.
4. **Refresh bookkeeping files** such as `.gitignore` so that future runs continue to respect the same system-versus-user boundaries.

The script’s header formalizes this contract in lines 6–8 of `update-system.mjs`:

> “Updates **ONLY** system layer files (modes, scripts, dashboard, templates).  
> **NEVER** touches user data ([`cv.md`](https://github.com/santifer/career-ops/blob/main/cv.md), [`profile.yml`](https://github.com/santifer/career-ops/blob/main/profile.yml), [`_profile.md`](https://github.com/santifer/career-ops/blob/main/_profile.md), `data/`, `reports/`).”

## Running Updates and Rollbacks Safely

The updater exposes simple CLI commands to manage the lifecycle of your installation.

Check for available updates before applying anything:

```bash
node update-system.mjs check

```

A typical response confirms a new version is ready:

```text
career-ops update available (v1.10.0 → v1.11.0)

```

Apply the update once you are ready. This command fetches only the files listed in `SYSTEM_PATHS` and preserves everything under `USER_PATHS`:

```bash
node update-system.mjs apply

```

If an update introduces unexpected behavior, restore the prior commit without touching personal files:

```bash
node update-system.mjs rollback

```

By default, the updater respects local modifications to system files unless you explicitly pass **`--force`**, which overwrites them.

## Key Files Behind the Safe Update Mechanism

Several files in the `santifer/career-ops` repository define and enforce the update boundary:

- **`update-system.mjs`** — The core auto-updater that declares `SYSTEM_PATHS` and `USER_PATHS`, and performs the selective checkout.
- **[`DATA_CONTRACT.md`](https://github.com/santifer/career-ops/blob/main/DATA_CONTRACT.md)** — The formal specification of the system layer versus the user layer that the updater honors.
- **[`AGENTS.md`](https://github.com/santifer/career-ops/blob/main/AGENTS.md)** — Documentation of the overall architecture and how the updater integrates with the broader CLI workflow.

## Summary

- `career-ops` uses `update-system.mjs` to separate system code from user data through the `SYSTEM_PATHS` and `USER_PATHS` constants.
- The updater checks the remote repository and refreshes only the file paths listed in `SYSTEM_PATHS`.
- User files such as [`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), and directories like `data/` and `reports/` are explicitly excluded and never modified.
- Commands such as `check`, `apply`, and `rollback` give you full control, with an optional `--force` flag to override local system edits.
- Bookkeeping files like `.gitignore` are also updated to maintain consistent layer boundaries across runs.

## Frequently Asked Questions

### What happens if I have locally edited a system file?

The updater preserves your local changes to system files unless you run `node update-system.mjs apply --force`. Without the flag, the selective checkout respects your modifications while still updating the remaining system layer.

### Can the updater accidentally delete my CV or profile data?

No. The `USER_PATHS` constant in `update-system.mjs` explicitly excludes [`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), `data/`, and `reports/` from every checkout operation. The script’s header at lines 6–8 formally promises that it never touches user data.

### How do I know if a new version is available before applying it?

Run `node update-system.mjs check`. This command queries the remote repository and prints a version comparison, such as `v1.10.0 → v1.11.0`, without changing any local files.

### Is there a way to undo an update if something breaks?

Yes. Run `node update-system.mjs rollback` to restore the previous commit. This command reverts the system layer while keeping all user-layer files exactly as they were.