Understanding the Role of `data/status-log.tsv` as an Append-Only Ledger for Status Transitions in Career-Ops

data/status-log.tsv is the immutable append-only ledger that records every job-application status change with precise timestamps, serving as the temporal source of truth while data/applications.md tracks only current states.

In the santifer/career-ops open-source job-application tracking system, understanding how status history is preserved is critical for accurate pipeline analytics. The ledger pattern separates current state from state history, enabling reliable velocity metrics and audit trails that manual tracking cannot provide.

What Makes data/status-log.tsv an Append-Only Ledger

The file enforces append-only semantics: rows are never modified in place. Each entry represents a single state transition with six tab-separated fields:


{tracker#}\t{date}\t{from}\t{to}\t{source}\t{note}

The from and to fields use - as a sentinel when the prior or target state is unknown. This structure is formally defined in DATA_CONTRACT.md and enforced by tooling.

Immutability Guarantees Audit Integrity

Corrections do not overwrite history. Instead, they append new rows with source: correction. This preserves the original record while acknowledging the fix—essential for debugging data quality issues without destroying evidence.

How the Ledger Integrates with the Career-Ops System

Recording Transitions: set-status.mjs

The set-status.mjs CLI script is the canonical interface for ledger updates. It synchronizes both the tracker and the log:


# Mark report #42 as Applied on the actual submission date

node set-status.mjs 42 Applied --on 2024-09-12

This command:

  1. Updates data/applications.md with the new status
  2. Appends to data/status-log.tsv:

42	2024-09-12	-	Applied	set-status	Submitted via LinkedIn

The source field is automatically populated as set-status when using the CLI.

Computing Velocity Metrics: funnel-velocity.mjs

The funnel-velocity.mjs script reads the ledger to calculate realistic stage-to-stage timing, comparing your pipeline speed against market benchmarks:

node funnel-velocity.mjs --summary

Sample output:


Applied→Responded median: 5.2 days
Applied→Interview  median: 12.1 days

These metrics depend on the ledger's exact transition dates—not the date you ran the command, which may differ significantly.

Building Company Evidence: company-history.mjs

The company-history.mjs script merges the ledger with tracker data, follow-ups, and scan history to generate per-company evidence cards. The temporal precision of the ledger makes these reports defensible during interview discussions.

Reading and Writing the Append-Only Ledger Programmatically

Minimal Node.js Parser

import { readFileSync } from 'fs';
import { join } from 'path';

const logPath = join(__dirname, 'data', 'status-log.tsv');
const rows = readFileSync(logPath, 'utf-8')
  .trim()
  .split('\n')
  .map(line => {
    const [tracker, date, from, to, source, note] = line.split('\t');
    return { tracker: Number(tracker), date, from, to, source, note };
  });

console.log(rows.slice(0, 3)); // show first three entries

Adding Retroactive Corrections

For entries recorded with wrong dates, append a correction rather than editing:

node set-status.mjs 42 Interview --on 2024-09-20 --source correction --note "Corrected applied date"

This creates a new ledger row while the original remains intact.

Data Governance and Source Validation

The source column values are restricted by VALID_SOURCES in funnel-velocity.mjs. Unrecognized sources are treated as "unknown" and excluded from funnel calculations. This prevents corrupted data from skewing velocity metrics.

The modes/tracker.md documentation explicitly warns against manual ledger editing, directing users to node set-status.mjs to maintain data integrity.

Why the Append-Only Ledger Pattern Matters

  • Accurate "days-in-stage" metrics: Uses actual transition dates, not command execution dates
  • Defensible velocity reports: node funnel-velocity.mjs produces benchmark-comparable numbers
  • Historical integrity: Retroactive fixes preserve original records for audit
  • Debugging capability: Full lineage of status changes available for data quality investigation

Summary

  • data/status-log.tsv is the immutable append-only ledger for status transitions in Career-Ops
  • Six-column TSV format tracks: tracker number, date, from-status, to-status, source, and optional note
  • set-status.mjs is the required CLI for writing—manual edits violate the data contract
  • funnel-velocity.mjs consumes the ledger for realistic pipeline speed calculations
  • Corrections append only, ensuring audit trails without destroying history

Frequently Asked Questions

What happens if I edit status-log.tsv manually?

Manual edits break the append-only invariant and violate DATA_CONTRACT.md. The modes/tracker.md documentation instructs users to always use node set-status.mjs. Manual changes may cause funnel-velocity.mjs to exclude entries with unrecognized sources or produce incorrect metrics.

How does the ledger handle initial status entries?

When a new application has no prior state, the from field contains - as a sentinel value. This distinguishes true initial entries from transitions where the prior state was genuinely unknown due to data quality issues.

Can I bulk-import historical data into the ledger?

Yes, by formatting entries as valid TSV rows and using --source correction or a custom source defined in funnel-velocity.mjs's VALID_SOURCES. However, the canonical pattern is to script calls to set-status.mjs with appropriate --on dates to preserve validation logic.

How does the ledger differ from applications.md?

applications.md holds the current state only—useful for quick human scanning. status-log.tsv holds the temporal history—required for analytics. They are complementary: the tracker shows where you stand; the ledger shows how you got there and how long each stage took.

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 →