What Is the Core Architecture of career-ops? A Deep Dive into the System/User Boundary Design

Career-ops uses a flat-root, two-layer architecture that enforces a strict Data Contract between system code and user data, enabling local-first, AI-agnostic job search automation.

This architecture powers santifer/career-ops, an open-source job search toolkit that runs entirely on your machine and works with any AI coding CLI. The design ensures your sensitive career data never mixes with the tool's source code, making updates safe and reproducible.


The Two-Layer Data Contract

At the heart of career-ops architecture lies the Data Contract documented in DATA_CONTRACT.md and ARCHITECTURE.md. This contract creates an immutable boundary between two layers:

  • System layer — Contains all tool code: prompts, scripts, templates, dashboards, and update-system.mjs. Defined in SYSTEM_PATHS.
  • User layer — Contains your private data: CV, profile, tracker, reports, and job descriptions. Defined in USER_PATHS.

Only update-system.mjs can modify system files. User data is Never touched during updates. This separation prevents accidental data loss and enables safe self-upgrades.


Core Design Principles

The three principles in ARCHITECTURE.md【/cache/repos/github.com/santifer/career-ops/main/ARCHITECTURE.md#L9-L12】 shape every architectural decision:

  • Local-first — All processing runs against local files. No external service stores your data.
  • AI-agnostic — Prompt files in modes/ drive AI logic. Claude Code, Codex, OpenCode, or any AI CLI can execute them.
  • Human-in-the-loop — The tool prepares content; you review and submit applications.

Architecture Components

The component map in ARCHITECTURE.md【/cache/repos/github.com/santifer/career-ops/main/ARCHITECTURE.md#L36-L50】 breaks into these interconnected parts:

Component Function Key Files
AI Interface Reads prompt files and executes commands AGENTS.md, CLI entry files
Prompt Engine Scoring, evaluation, application logic modes/*.md, modes/_shared.md
Job Discovery Zero-token job source scanning scan.mjs, providers/
Evaluation Pipeline A-H block structured scoring oferta.md, _shared.md
Generation Tools PDF, LaTeX CV, cover letter creation generate-*.mjs, templates/
Tracking System Canonical application tracker data/applications.md, merge-tracker.mjs
Updater Safe system self-updates update-system.mjs

Data Flow Through the System

A typical run follows this sequence, visualized in ARCHITECTURE.md【/cache/repos/github.com/santifer/career-ops/main/ARCHITECTURE.md#L78-L86】:

  1. Scan — node scan.mjs pulls public listings via ATS APIs or providers/ modules → writes to data/pipeline.md

  2. Evaluate — node oferta.mjs loads modes/oferta.md, reads cv.md, _profile.md, and the JD → produces reports/NNN-*.md

  3. Track — reserve-report-num.mjs and merge-tracker.mjs atomically update data/applications.md

  4. Generate — generate-pdf.mjs, build-cv-html.mjs create application materials

  5. Human Review — You inspect reports and decide whether to apply


Key Script Entry Points

These top-level scripts implement the architecture's operations:


# Discover jobs without API tokens

node scan.mjs

# Evaluate a specific job posting

codex exec "oferta https://company.com/jobs/123"

# Generate PDF from current CV

node generate-pdf.mjs

# Reserve batch report numbers for parallel processing

node reserve-report-num.mjs --count 5   # Output: 042-046

All scripts enforce the system/user boundary and are located in the repository root alongside ARCHITECTURE.md.


Quality Assurance Mechanisms

The architecture includes automated safeguards described in ARCHITECTURE.md【/cache/repos/github.com/santifer/career-ops/main/ARCHITECTURE.md#L88-L92】:

  • test-all.mjs — Runs 500+ validation checks
  • updater-migration-tests.mjs — Verifies system/user separation during updates
  • CI pipeline — CodeQL, CodeRabbit, and Renovate for continuous validation

Multi-CLI Compatibility

Each AI coding CLI reads a dedicated tiny entry file that forwards to AGENTS.md【/cache/repos/github.com/santifer/career-ops/main/ARCHITECTURE.md#L72-L74】. This design lets the same core logic run on Claude Code, OpenCode, Gemini, and future CLIs without modification.


Critical Source Files

Understanding these files unlocks the full architecture:

File Purpose
ARCHITECTURE.md Canonical design documentation and component map
DATA_CONTRACT.md Formal system/user boundary specification
modes/_shared.md Scoring logic, spend-tier routing, global rules
modes/oferta.md Evaluation prompt with A-H block structure
scan.mjs Zero-token job discovery entry point
providers/ Per-job-board modules
generate-pdf.mjs / build-cv-html.mjs Playwright-based document generation
merge-tracker.mjs Atomic TSV tracker updates
update-system.mjs Safe self-update implementation
AGENTS.md Open-agent-skill definition for all CLIs

Summary

  • Career-ops architecture centers on a two-layer Data Contract enforcing strict separation between system code and user data
  • Local-first processing ensures no external service ever holds your career information
  • AI-agnostic prompt files in modes/ enable compatibility across any AI coding CLI
  • Human-in-the-loop design keeps you in control of final application decisions
  • Safe updates through update-system.mjs modify only system paths listed in SYSTEM_PATHS

Frequently Asked Questions

What makes career-ops "local-first"?

All job discovery, evaluation, and document generation runs on your machine using local files. Your CV, profile, and application history never leave your system or get stored by external services. This is enforced by the Data Contract's USER_PATHS definition and implemented in scripts like scan.mjs and generate-pdf.mjs.

How does the system/user boundary prevent data loss?

USER_PATHS explicitly lists directories and files that update-system.mjs will never touch. This means running node update-system.mjs to get the latest career-ops features cannot accidentally overwrite your CV, tracker, or reports. The updater-migration-tests.mjs suite continuously validates this boundary.

Can I use career-ops with AI tools other than Claude Code?

Yes. The architecture is AI-agnostic by design. Prompt logic lives in modes/*.md files that any AI CLI can read. Each supported tool has a thin entry file that routes to AGENTS.md, the canonical skill definition. This works with Codex, OpenCode, Gemini, and compatible alternatives.

What happens if I run scripts in the wrong order?

The tracker system uses atomic operations via reserve-report-num.mjs and merge-tracker.mjs to prevent corruption. However, best practice follows the documented flow: scan → evaluate → track → generate → review. This sequence ensures data/pipeline.md feeds oferta.md evaluation, which correctly populates data/applications.md before document generation.

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 →