#!/usr/bin/env node /** * cv-sync-check.mjs — Validates that the career-ops setup is consistent. * * Checks: * 1. cv.md exists * 2. config/profile.yml exists and has required fields * 3. No hardcoded metrics in _shared.md or batch/batch-prompt.md * 4. article-digest.md freshness (if exists) */ import { readFileSync, existsSync, statSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import { getCareerOpsRoot, getProfilePath, hasProfileOverride } from './path-resolver.mjs'; import { validateFlags } from './lib/cli-flags.mjs'; import { isMainModule } from './lib/is-main-module.mjs'; import { loadYaml } from './lib/yaml-document.mjs'; const CODE_ROOT = dirname(fileURLToPath(import.meta.url)); const DATA_ROOT = getCareerOpsRoot(); // ── CLI flags + help ──────────────────────────────────────────────── // // docs/SCRIPTS.md lists `node cv-sync-check.mjs` as a runnable command, but the // script read no arguments at all: a mistyped flag was ignored and the checks // ran anyway, so `--hlep` looked like a successful run of whatever the caller // meant (#3565). KNOWN_FLAGS is exactly --help/-h because that is every flag // this file parses. Unrecognized flags exit 1 naming the flag; --help/-h print // USAGE and exit 0. const KNOWN_FLAGS = ['--help', '-h']; const USAGE = `Usage: node cv-sync-check.mjs # run the cv.md / profile.yml / prompt checks node cv-sync-check.mjs --help|-h # print this usage block and exit`; // Numbers that look like candidate metrics ("170+ hours", "300+ tests") belong // in cv.md or article-digest.md. A time window ("less than 24 hours old", // "within 48 hours") is a rule, not a claim about the candidate. const METRIC_RE = /\b\d{2,4}\+?\s*(hours?|%|evals?|layers?|tests?|fields?|bases?)\b/gi; const WINDOW_BEFORE_RE = /\b(?:less than|fewer than|older than|within|every)\s*\**\s*$/i; const WINDOW_AFTER_RE = /^\s*\**\s*(?:old|ago)\b/i; export function hardcodedMetrics(content) { const found = []; String(content).split('\n').forEach((line, i) => { if (line.includes('NEVER hardcode') || line.includes('NUNCA hardcode') || line.startsWith('#') || line.startsWith('