Career-Ops local AI job screening, ATS resume generation, and pipeline tracking workflow

Document type
Field manual
Updated
Reading time
10 min

Configure career-ops-hq/career-ops (version 1.39.0) across its A-to-H evaluation framework, 39 core modes, 55+ job-board parsers, and two-layer data contract, including zero-token scanning, fact-verification gates, and the Go TUI dashboard.

Source
Document details
career-ops-hq/career-ops
License
MIT

Run zero-token job portal scans, structured A-to-H evaluations, Playwright fact-checked PDF resume builds, and human-in-the-loop application tracking inside your existing AI coding CLI.

Core routable modes
39Plus 3 interview sub-modes, 1 regional mode, and 20 locale directories
Job-board parser modules
55+Pre-configured with 100+ companies and 35+ search queries
Recommended apply threshold
4.0/5Covering Blocks A to H and posting liveness checks

01A-to-H evaluation framework, human-in-the-loop boundary, and two-layer architecture

System purpose

career-ops-hq/career-ops (version 1.39.0), released by Santiago Fernández de Valderrama Aparicio (@santifer) under the MIT license, is a local-first AI job-search agent developed during the author's own job search (740 listings evaluated, 68 applied, 12 interviews, and 1 offer). The system executes locally via the open Agent Skill standard (sharing .agents/skills/career-ops/SKILL.md and AGENTS.md) across Claude Code, Codex, OpenCode, Antigravity CLI (agy), Pi, Oh My Pi, Qwen, Kimi, GitHub Copilot, and Grok Build CLI without connecting to any proprietary backend or telemetry service.

The core workflow combines "Blocks A-to-H structured evaluation" with a strict "Human-in-the-Loop" boundary: when a user pastes a job URL or JD text, auto-pipeline checks whether the posting is still live (check-liveness.mjs), classifies the role into a target archetype (LLMOps, Agentic, PM, SA, FDE, or Transformation), and evaluates it against cv.md across Blocks A through F (role match, gaps, level strategy, comp research, personalization, and STAR+R interview prep), Block G (posting legitimacy and repost signals), and Block H (draft application answers for high-scoring roles), then renders an ATS-readable PDF resume via Playwright using Space Grotesk + DM Sans templates and records a row in data/applications.md. By default, the system advises skipping roles scored below 4.0/5, never auto-submits applications (prepare-application.mjs sends no POST requests), and never sends emails.

Mode categoryRepresentative modesOutput files or script entrypointsCore function and execution boundary
Job discovery and triagescan, discover, triage, pipeline, batch, titlesscan.mjs, scan-ats-full.mjs, data/pipeline.mdZero-token scans across 100+ company ATS boards, new board resolution, fast first-pass triage from modes/_brief.md, and parallel headless evaluation
Deep role evaluationauto-pipeline, oferta, ofertas, deep, eu-swereports/{###}-{slug}-{date}.mdRuns Blocks A through H evaluation, multi-offer comparison, company AI strategy research, and European software-engineering role calibration
CV and application draftingpdf, ats, latex, latex-tex, text, cover, email, contacto, applygenerate-pdf.mjs, verify-cv-facts.mjs, output/*.pdfGenerates fact-checked PDF or LaTeX resumes, A4 cover letters, application email drafts, LinkedIn outreach messages under 300 characters, and interactive form filling
Interview and offer stageinterview-prep, interview/plan, interview/practice, interview/debrief, interview-redflag, offer-prepinterview-prep/story-bank.md, salary-gap.mjsAccumulates the STAR+R story bank, runs mock interviews, flags employer warning signs, walks through contract clauses, and prepares lawyer question lists
Tracking and targeting optimizationtracker, followup, reply-watch, outcome, patterns, calibrate, upskill, training, projectdata/applications.md, analyze-patterns.mjs, stats.mjsTracks follow-up cadence, classifies employer replies, analyzes per-ATS conversion rates and rejection patterns, and calibrates score predictability and skill gaps
Profile onboarding and maintenanceinterview, intake, master-profile, add, expand, retro, agent-inbox, updatedoctor.mjs, update-system.mjs, github-evidence.mjsBuilds cv.md interactively, imports files from documents/, extracts GitHub PR/commit evidence, and updates system-layer files without touching user data
Career-Ops two-layer data contract and anti-fabrication pipeline
  1. Job input and discovery layer (Untrusted External Content)

    • scan.mjs / scan-ats-full.mjs (55+ parser modules, 100+ pre-configured companies)
    • check-liveness.mjs and detect-reposts.mjs (flags postings re-listed 2+ times in 90 days)
    • Treats external JDs, forms, and emails strictly as data to block prompt injection
  2. Two-layer data contract and trust boundary (DATA_CONTRACT.md)

    • Primary trust tier: cv.md, article-digest.md, config/profile.yml, modes/_profile.md
    • Derived narrative tier: interview-prep/story-bank.md (quantified claims require Provenance markers)
    • System layer: modes/_shared.md, AGENTS.md, *.mjs (updated safely by update-system.mjs)
  3. Anti-fabrication gates and terminal tracking layer

    • verify-cv-facts.mjs, verify-cv-structure.mjs, and cv-title-check.mjs
    • Playwright ATS PDF resumes, cover letters, and data/pdf-index.tsv manifest
    • data/applications.md, data/status-log.tsv, and Go Bubble Tea TUI dashboard

All personal data and CVs remain on the local machine (or inside an external CAREER_OPS_ROOT directory) and are never overwritten during system updates.

02Node.js 22.13+ runtime, npx init, and doctor.mjs check

Installation and verification

  • Not completed:

    Install Node.js ^22.13.0 || >=23.4.0 (as required by the engines field in package.json).

  • Not completed:

    Install Playwright Chromium for PDF resume rendering, cover letters, and browser liveness checks (postinstall attempts this automatically, or run npx playwright install chromium).

  • Not completed:

    Install Go to build or launch the terminal dashboard (dashboard/, built with Bubble Tea and Lipgloss).

This report inspected source files, mode definitions, and script logic only; it did not execute live portal scraping or generate personal resume files locally.

Route One: Initialize a workspace via npx

bash
npx @santifer/career-ops init
cd career-ops
claude

To clone the repository manually and install dependencies and Playwright Chromium:

bash
git clone https://github.com/career-ops-hq/career-ops.git
cd career-ops && npm install
npx playwright install chromium

Route Two: Run doctor.mjs diagnostics and seed personalization templates

Before running evaluations or scans, run the read-only diagnostic script to inspect the presence and personalization state of cv.md, config/profile.yml, modes/_profile.md, and portals.yml:

bash
node doctor.mjs --json
node doctor.mjs --json --init-templates

03Zero-token scanning, anti-fabrication gates, and pipeline diagnostics

Core capabilities

Zero-token job portal scanning

node scan.mjs [--verify] / npm run scan:full

Poll 55+ ATS providers and filter expired postings

scan.mjs queries public Greenhouse, Ashby, and Lever APIs directly (0 token cost) and launches Playwright with --verify to drop closed listings; scan-ats-full.mjs checkpoints every 500 companies.

CV fact and structure verification gates

npm run cv:verify-facts / verify-cv-structure.mjs / cv-title-check.mjs

Block fabricated numbers and job-title drift before PDF export

generate-pdf.mjs halts when numbers or facts are absent from cv.md or article-digest.md; verify-cv-structure.mjs flags chronological reordering, and cv-title-check.mjs checks exact title parity.

Story-bank provenance verification

node story-provenance-check.mjs --summary

Prevent AI-estimated prep figures from drifting into ground truth

Verifies that quantified claims in interview-prep/story-bank.md carry an explicit Provenance marker (cv.md, user-stated, derived-unverified, or user-cannot-confirm).

Posting liveness and ghost-job detection

npm run liveness / npm run reposts / npm run role-clarity

Identify expired postings, 90-day reposts, and vague JDs

check-liveness.mjs records dead links as skipped_expired; detect-reposts.mjs flags roles re-listed 2 or more times across 2 or more scan dates within 90 days; role-clarity.mjs runs a 6-point clarity check.

Pipeline integrity and funnel analytics

npm run verify / npm run patterns / node stats.mjs --summary

Audit tracker health, conversion funnels, and per-ATS advance rates

verify-pipeline.mjs works with tracker-sync-check.mjs and fix-report-links.mjs to repair broken links and status drift; analyze-patterns.mjs reports interview rates by role family and ATS vendor.

Go TUI dashboard and non-destructive updates

npm run serve:dashboard / node update-system.mjs check

Browse the job pipeline and update system-layer files safely

The Go TUI provides 10 filter tabs and 8 sort modes; update-system.mjs updates system-layer files only, supporting apply --confirm, dismiss, and rollback.

Alongside interactive /career-ops slash commands (or /skill:career-ops in Pi and Oh My Pi), the repository includes standalone runners and operational utilities:

Script groupCommands or script filesKey behavior and output constraints
Standalone model runnersnpm run or, npm run gemini:eval, npm run ollama:eval, npm run openai:evalEvaluate JDs directly through OpenRouter, Gemini, local Ollama, or OpenAI-compatible endpoints without an interactive AI CLI
External data directory isolationCAREER_OPS_ROOT / CAREER_OPS_DATA_DIR or .career-ops-dataRedirects cv.md, portals.yml, data/, reports/, and output/ to an external directory cleanly separated from the code checkout
Network and visa cross-checksnode linkedin-join.mjs, node sponsor-check.mjs, node contact-lookup.mjsOffline-joins LinkedIn Connections.csv against target companies and checks the UK Home Office sponsor register (cached for 7 days by default)
Compensation gap and ROI calculatorsnode salary-gap.mjs, node negotiation-roi.mjsCompares desired, advertised, and actual compensation; converts a quantified story-bank.md achievement into annualized leverage only if the number appears verbatim in cv.md

04Two-layer data contract, Pro/Max billing guard, and provenance rules

Operating principles

Write customizations to _profile.md and _custom.md, never _shared.md

Under DATA_CONTRACT.md, target archetypes, narrative framing, negotiation scripts, and compensation targets belong in modes/_profile.md or config/profile.yml, while procedural house rules belong in modes/_custom.md. System updates via update-system.mjs overwrite modes/_shared.md, so personal data must never be stored there.

Personalize modes/_profile.md before running batch scans

doctor.mjs reports unedited personalization files under unpersonalized. Running evaluations before updating modes/_profile.md and modes/_brief.md from your own CV scores every posting against the original author's santifer archetypes and North Star.

Unset ANTHROPIC_API_KEY when using a Claude Pro or Max subscription

If ANTHROPIC_API_KEY is present in the shell environment, Claude Code bills per token over the API instead of using an active Pro or Max login. Remove the environment variable and run /login for interactive sessions; for headless claude -p batch workers, run claude setup-token once and export CLAUDE_CODE_OAUTH_TOKEN.

Enforce Provenance markers on quantified claims in story-bank.md

Because interview-prep/story-bank.md accumulates content from past AI-drafted prep notes, any scale or percentage figure not present in cv.md must be audited with node story-provenance-check.mjs --summary. Entries marked user-cannot-confirm are restricted to narrative texture and never restated as verified facts.

When reading external job postings, application forms, and recruiter emails, AGENTS.md enforces an Untrusted External Content boundary: scraped text is treated strictly as data and never as instructions. If a job description embeds prompt-injection text instructing an AI reviewer to ignore prior rules or inflate scores, the agent quotes the line as a Block G anomaly signal and continues without obeying it.

05Workspace setup, portal validation, scanning, and pipeline audit

Worked example

The following sequence sets up a local career-ops checkout with an isolated external data directory, validates portals.yml, runs a zero-token scan with Playwright liveness verification, and audits CV fact gates and tracker integrity.

1. Clone the repository, bind an external data directory, and run doctor.mjs

bash
git clone https://github.com/career-ops-hq/career-ops.git
cd career-ops && npm install
npx playwright install chromium

export CAREER_OPS_ROOT=~/career-ops-data
mkdir -p "$CAREER_OPS_ROOT"
cp templates/portals.example.yml "$CAREER_OPS_ROOT/portals.yml"
cp config/profile.example.yml "$CAREER_OPS_ROOT/config/profile.yml"

node doctor.mjs --json --init-templates

2. Validate portal configuration and run a liveness-verified scan

bash
npm run validate:portals
node audit-portals.mjs --summary
node scan.mjs --verify

3. Verify CV fact gates, story-bank provenance, and pipeline health

bash
npm run cv:verify-facts
node verify-cv-structure.mjs
node cv-title-check.mjs --summary
node story-provenance-check.mjs --summary
npm run verify
node stats.mjs --summary

06No-auto-submit rule, plugin path guard, and fact-check scope

Limitations and caveats

LimitationTechnical boundary and compliance requirement
Fact checks do not judge semantic rewordinggenerate-pdf.mjs and verify-cv-facts.mjs block numbers and named facts missing from cv.md or article-digest.md, but cannot yet judge whether a paraphrased bullet overstates scope (tracked in Issue #1411); review every PDF manually before sending
Strict prohibition on fabricated authorshipAGENTS.md forbids conflating tool usage with authorship ("used tool X" must never become "built tool X"); never claim authorship of a repository, library, or framework unless explicitly attributed in cv.md or article-digest.md
Claude plugin cache write protectionWhen installed as a Claude Code plugin under ~/.claude/plugins/cache/, marketplaces/, or synced/, the default data root redirects to ~/career-ops-data; pointing CAREER_OPS_ROOT inside a plugin install copy causes getCareerOpsRoot() to throw UnsafeDataRootError
UK sponsor register not-found semanticsIn sponsor-check.mjs, a not-found result against the UK Home Office register means unconfirmed (due to parent-entity licensing, legal vs. trading names, or snapshot lag), never "does not sponsor"
Trademark policy and third-party portal ToSRepository code is MIT-licensed, while the career-ops name and brand are governed by TRADEMARK.md; users must comply with Greenhouse, Lever, Workday, and LinkedIn Terms of Service

07Go TUI dashboard, scheduled scans, and official references

Next steps

  • Once data/applications.md accumulates evaluated roles, run npm run serve:dashboard to launch the Go Bubble Tea terminal UI with 10 filter tabs and 8 sort modes.

  • To schedule recurring scan and triage runs or evaluate postings with free and local models, consult docs/AUTOMATION.md, docs/RUNNING_ON_A_BUDGET.md, and docs/FREE_TIER.md.

  • To pair portfolio case studies with code-driven product launch or architecture animations, combine this workflow with the Huashu Art Motion Guide.

Source pinned at cd3793734fcd57693ddd97a20ccf0d3298b7d47e. Official reference files:

References