santifer/career-ops · warning

pending TSVs in tracker-additions/ (not merged)

Error message

${pendingTsvs} pending TSVs in tracker-additions/ (not merged)

What it means

A warning from verify-pipeline.mjs (Check 6) reporting that batch/tracker-additions/ contains TSV files that have not been merged into data/applications.md. The TSV-inbox workflow requires running merge-tracker.mjs after each batch of evaluations; unmerged TSVs mean the tracker is out of sync with completed evaluations.

Solutions

  1. Run `node merge-tracker.mjs` to merge all pending TSVs into the tracker.
  2. Re-run `node verify-pipeline.mjs` afterwards to confirm the inbox is empty.
  3. If a TSV is malformed (missing header, ambiguous score), fix it per the header rules then re-merge — merge-tracker skips invalid files loudly.
  4. Add merge-tracker.mjs to the end of every batch script/prompt so the inbox never accumulates.

Example fix

// before: leaving the batch script at evaluation only
node batch-eval.mjs
// after
node batch-eval.mjs && node merge-tracker.mjs && node verify-pipeline.mjs
Defensive patterns

Strategy: validation

Validate before calling

const pending = existsSync(ADDITIONS_DIR)
  ? readdirSync(ADDITIONS_DIR).filter(f => f.endsWith('.tsv'))
  : [];
if (pending.length > 0) await run('node merge-tracker.mjs');

Prevention

When it happens

Trigger: Running `node verify-pipeline.mjs` while batch/tracker-additions/*.tsv files exist — i.e. evaluations were produced (each writing one TSV) but `node merge-tracker.mjs` was never run, or merge was interrupted before consuming them.

Common situations: A batch run crashed after writing TSVs but before merging; forgetting the 'run merge-tracker.mjs after each batch' rule; parallel workers left TSVs behind after a failed reservation release; cleaning git status and skipping the merge step.

Related errors


AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-16). Data as JSON: /api/errors/71012cc3bad2397d. Report an issue: GitHub.

Appendix: source

Thrown at verify-pipeline.mjs:220

let badRows = 0;
for (const line of lines) {
  if (!line.startsWith('|')) continue;
  if (isSeparatorRow(line) || isHeaderRow(line)) continue;
  const parts = line.split('|');
  if (parts.length <= MAX_IDX) {
    error(`Row with too few columns (need ${MAX_IDX} data cols): ${line.substring(0, 80)}...`);
    badRows++;
  }
}
if (badRows === 0) ok('All rows properly formatted');

// --- Check 6: Pending TSVs ---
let pendingTsvs = 0;
if (existsSync(ADDITIONS_DIR)) {
  const files = readdirSync(ADDITIONS_DIR).filter(f => f.endsWith('.tsv'));
  pendingTsvs = files.length;
  if (pendingTsvs > 0) {
    warn(`${pendingTsvs} pending TSVs in tracker-additions/ (not merged)`);
  }
}
if (pendingTsvs === 0) ok('No pending TSVs');

// --- Check 7: Bold in scores ---
let boldScores = 0;
for (const e of entries) {
  if (e.score.includes('**')) {
    warn(`#${e.num}: Score has markdown bold: "${e.score}"`);
    boldScores++;
  }
}
if (boldScores === 0) ok('No bold in scores');

// --- Check 8: Stale report-number sentinels (GC) ---
// reserve-report-num.mjs drops NNN-RESERVED.md files in reports/ when a
// number is claimed.  If the process crashed before writing the real report
// and deleting the sentinel it will linger.  Sentinels older than 4 h are

View on GitHub (pinned to e7abd431fc)