CareerOps Layered Agentic Architecture: A Three-Tier System for Autonomous Job Search
CareerOps implements a strict three-layered agentic architecture that separates system scripts, user data, and AI decision logic to enable autonomous, side-effect-free job search automation.
The santifer/career-ops repository demonstrates how to build a modular, AI-agnostic job application assistant using a layered agentic architecture. By dividing responsibilities across distinct tiers—executable code, personal data stores, and Markdown-based reasoning engines—the system ensures that specialized agents operate within strict boundaries without risking data corruption or unintended side effects.
The Three Layers of the CareerOps Stack
The architecture is organized into three primary layers that reflect distinct concerns: system execution, user data management, and AI-driven decision logic.
System Layer: Execution Agents
The System Layer contains the code that runs the tool, including scripts, CLI entry points, and updater logic. According to ARCHITECTURE.md, this layer never touches user-generated files.
Key components include:
scan.mjs– The discovery agent that scrapes public ATS APIsproviders/– Pluggable job-source plugins for extending discoveryupdate-system.mjs– Self-update agent that upgrades only system filesAGENTS.md– Entry point mapping for compatible AI coding CLIs
This layer acts as the operational brain of the platform, handling file I/O operations, network requests, and system maintenance while maintaining read-only access to user configurations.
User Layer: Data Sovereignty
The User Layer stores the candidate’s personal data, CV, application tracker, and customizations. Files in this tier include cv.md, config/profile.yml, modes/_profile.md, and the data/ and reports/ directories.
A critical architectural constraint governs this layer: the system layer reads from here but never modifies it. User data resides in the data/applications.md tracker and the jds/ directory for job descriptions, serving as the single source of truth that persists across system upgrades.
AI-Prompt Layer: Reasoning Logic
The AI-Prompt Layer consists of Markdown "brain" files that encode scoring rules, archetype detection, and generation logic. These files are read by any AI-coding CLI (such as Claude Code or OpenCode) or by lightweight evaluators.
Core prompt files include:
modes/_shared.md– Core scoring engine used by every evaluation agentmodes/oferta.md– Full evaluation workflow covering blocks A through H- Locale-specific variants (e.g.,
modes/de/oferta.md) for internationalization
Because this layer consists solely of Markdown text files, the system remains AI-agnostic—the "brain" can be swapped without changing system code.
How the Agentic Pipeline Executes
The layers interact through a strict six-stage pipeline flow, with each script acting as a focused autonomous agent that receives input and emits output without side effects on unrelated layers.
1. Discovery via scan.mjs
The discovery agent scrapes public job boards using pluggable providers and writes raw listings to data/pipeline.md.
# Populate the pipeline with fresh opportunities
node scan.mjs
2. Liveness Validation via check-liveness.mjs
Before incurring evaluation costs, the liveness agent filters out closed postings.
# Verify a posting is still live (zero-token operation)
node check-liveness.mjs <url>
3. Evaluation via AI-Prompt Agents
The evaluation agent reads the job description, the user’s cv.md, and the scoring rules in modes/oferta.md and modes/_shared.md to generate a structured report.
# Create reports/NNN-*.md and update the tracker
node oferta.mjs <report-num> <url>
4. Tracking via merge-tracker.mjs
This agent atomically updates data/applications.md, preserving the single source of truth for application statuses.
5. Document Generation via generate-pdf.mjs
PDF and LaTeX generators produce final CVs and cover letters using templates in templates/.
# Generate output/cv.pdf from cv.md + templates
node generate-pdf.mjs cv
6. Self-Update via update-system.mjs
The updater safely upgrades only the system layer while leaving the user layer untouched.
# Apply latest system updates without touching personal data
node update-system.mjs apply
Boundary Enforcement and AI Agnosticism
The agentic nature of CareerOps derives from strict boundary enforcement between layers. Scripts in the system layer possess write access only to temporary working directories and the data/pipeline.md buffer, while maintaining read-only access to user files like config/profile.yml.
The AI-prompt layer reinforces this design by externalizing all decision logic into Markdown files. Because modes/_shared.md and modes/oferta.md contain pure reasoning instructions rather than executable code, any compatible AI model can serve as the evaluation agent without requiring system modifications or API-specific integrations.
Key Files in the Architecture
| File | Layer | Responsibility |
|---|---|---|
ARCHITECTURE.md |
Documentation | High-level overview of layer interactions |
scan.mjs |
System | Discovery agent for job board scraping |
providers/README.md |
System | Extension point for new job-source plugins |
modes/_shared.md |
AI-Prompt | Core scoring engine (archetype detection) |
modes/oferta.md |
AI-Prompt | Complete evaluation workflow blocks A-H |
update-system.mjs |
System | Safe upgrade mechanism respecting boundaries |
data/applications.md |
User | Canonical application tracker database |
AGENTS.md |
System | CLI entry point mappings for AI tools |
Summary
- Three-layer separation prevents system updates from corrupting user data and ensures AI logic remains vendor-agnostic.
- Six-stage pipeline moves from job discovery (
scan.mjs) through evaluation (modes/oferta.md) to document generation (generate-pdf.mjs). - Strict write boundaries allow the system layer to read
cv.mdandconfig/profile.ymlbut prohibit modification of user-layer files. - Markdown-based reasoning in
modes/_shared.mdenables any AI-coding CLI to act as the evaluation agent without code changes.
Frequently Asked Questions
What distinguishes CareerOps as "agentic" rather than a simple script collection?
CareerOps implements autonomous agents that follow the stimulus-response pattern: each script (scan.mjs, oferta.mjs, generate-pdf.mjs) receives specific inputs (URLs, file paths) and produces deterministic outputs (Markdown reports, PDFs) while maintaining isolation from other layers. The architecture treats these scripts as independent workers that coordinate through the filesystem rather than monolithic application logic, enabling parallel execution and failure isolation.
How does the System Layer avoid modifying User Layer files?
The architecture enforces a read-only contract where system scripts access user data like cv.md and data/applications.md exclusively for reading. Write operations from agents such as merge-tracker.mjs target specific controlled files within the user layer's structure, while update-system.mjs explicitly excludes user directories from its file operations. This separation is documented in ARCHITECTURE.md as "The Two Layers: The Data Contract."
Can CareerOps work with AI models other than Claude or OpenCode?
Yes. Because the AI-Prompt Layer consists of standard Markdown files (modes/_shared.md, modes/oferta.mjs) containing natural language instructions and scoring rubrics, any AI coding assistant that can read project files can serve as the reasoning engine. The AGENTS.md file standardizes entry points across different CLI tools, making the system truly AI-agnostic.
What occurs during the Evaluation stage of the pipeline?
During Evaluation, the system invokes the AI-prompt agent (typically via oferta.mjs) which loads the job description from jds/, the candidate profile from cv.md, and the scoring rules from modes/oferta.md blocks A through H. The agent generates a structured Markdown report saved to reports/NNN-*.md containing fit scores and archetype analysis, then merge-tracker.mjs atomically appends this entry to data/applications.md without overwriting existing records.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →