Canonical Application States and Alias Handling in Career-Ops
Career-Ops enforces a strict set of eight canonical application states defined in templates/states.yml, normalizing multilingual user inputs through the validateStatus() function in merge-tracker.mjs to ensure data consistency across batch processing pipelines.
The Career-Ops repository (santifer/career-ops) manages job application tracking through a centralized status system. Canonical application states serve as the single source of truth for both automated batch scripts and the dashboard interface, ensuring consistent reporting regardless of whether inputs arrive in English, Spanish, or marked-down formats.
What Are Canonical Application States?
Canonical application states represent the fixed vocabulary that Career-Ops uses to track job application progress. These states are declared centrally in [templates/states.yml](https://github.com/santifer/career-ops/blob/main/templates/states.yml) (lines 9–56) and function as the single source of truth for the entire system.
The repository defines exactly eight canonical states:
evaluated— Initial assessment complete (aliases:evaluada,condicional,hold,verificar)applied— Application submitted (aliases:aplicado,enviada,aplicada,applied,sent)responded— Employer replied (aliases:respondido)interview— Interview scheduled or completed (aliases:entrevista)offer— Job offer received (aliases:oferta)rejected— Application declined (aliases:rechazado,rechazada)discarded— Manually removed from active tracking (aliases:descartado,descartada,cerrada,cancelada)SKIP— Intentionally skipped entries (aliases:no_aplicar,no aplicar,skip,monitor,geo blocker)
Every entry written to applications.md must resolve to one of these IDs, regardless of the original input format.
How Alias Resolution Works in merge-tracker.mjs
When batch workers generate TSV files in batch/tracker-additions/, they may use localized labels, markdown formatting, or shorthand aliases. The validateStatus() function in merge-tracker.mjs (lines 34–78) handles normalization through a five-step pipeline:
- Strips markdown — Removes bold markers (
**) and trailing date text - Normalizes case — Converts the string to lower-case for comparison
- Checks canonical states — Validates against the
CANONICAL_STATESarray - Maps aliases — If not a direct match, looks up the value in the internal alias map
- Falls back safely — Returns
"Evaluated"as the default state while emitting a warning for unrecognized inputs
This guarantees that applications.md contains only canonical values, preventing data drift between writer scripts and the reader dashboard.
The Validation Pipeline
The validateStatus() function implements strict normalization before writing to the tracker. It accepts raw strings from TSV inputs and applies regex cleaning to handle user-generated variations.
Fallback Behavior
When validateStatus() encounters an unrecognized status—one that matches neither a canonical state nor a defined alias—it automatically assigns the Evaluated state and logs a warning. This prevents pipeline failures while flagging data quality issues for manual review.
Working with Aliases: Practical Examples
Career-Ops supports multilingual workflows through its alias system. Below are concrete implementations showing how raw inputs transform into canonical states.
Processing Spanish Aliases in TSV Inputs
Batch scripts often generate TSV rows using Spanish terminology. When merge-tracker.mjs processes these files, it maps aliases automatically.
Consider this raw TSV entry:
12 2024-06-13 Acme Corp Software Engineer 4.2/5 Aplicado ✅ [12](reports/12-acme-software-engineer-2024-06-13.md) Initial eval
The validateStatus('Aplicado') call normalizes this to the canonical Applied state, writing the following to applications.md:
| 12 | 2024-06-13 | Acme Corp | Software Engineer | 4.2/5 | Applied | ✅ | [12](reports/12-acme-software-engineer-2024-06-13.md) | Initial eval |
Using the validateStatus Helper Directly
You can import and use the validation logic in custom scripts:
import { validateStatus } from './merge-tracker.mjs';
const rawStatus = '**Enviada**'; // bold-markdown variant
const canonical = validateStatus(rawStatus);
console.log(canonical); // → "Applied"
The function handles markdown stripping, case normalization, and alias mapping in a single call.
Extending the Alias Map
To support new terminology, modify the aliases object inside merge-tracker.mjs (around line 58):
const aliases = {
// existing entries ...
'enviado': 'Applied', // new alias for Applied
'pendiente': 'Evaluated', // new alias for Evaluated
};
After adding entries, any TSV containing "enviado" or "pendiente" automatically maps to the appropriate canonical state.
Key Files and Their Responsibilities
| File | Role | Location |
|---|---|---|
templates/states.yml |
Defines the canonical state list and default aliases | [templates/states.yml](https://github.com/santifer/career-ops/blob/main/templates/states.yml) |
merge-tracker.mjs |
Reads pending TSVs, normalizes states via validateStatus(), merges into tracker |
merge-tracker.mjs |
batch/tracker-additions/ |
Directory holding TSV files generated by batch evaluation scripts | batch/tracker-additions/ |
applications.md |
Human-readable markdown table displaying canonical statuses | Root or data/applications.md |
These components enforce a single source of truth across the Career-Ops pipeline, supporting multilingual inputs while maintaining strict data consistency.
Summary
- Canonical application states are defined in
templates/states.ymland represent the only valid values written to the tracker. - Alias resolution occurs in
merge-tracker.mjsthrough thevalidateStatus()function, which strips markdown, normalizes case, and maps multilingual inputs. - Fallback protection ensures unrecognized statuses default to "Evaluated" rather than breaking the pipeline.
- Extensibility is achieved by adding entries to the alias map in
merge-tracker.mjs, allowing customization without modifying core state definitions.
Frequently Asked Questions
What happens if I use an unrecognized status alias?
Career-Ops falls back to the Evaluated state and emits a warning. The validateStatus() function in merge-tracker.mjs (lines 34–78) treats any unrecognized input as requiring initial evaluation, ensuring the pipeline continues while flagging data quality issues.
Where are the canonical application states defined?
The canonical list resides in [templates/states.yml](https://github.com/santifer/career-ops/blob/main/templates/states.yml) (lines 9–56). This file serves as the single source of truth for both the batch processing scripts and the dashboard interface, defining eight possible states from evaluated to SKIP.
How does Career-Ops handle multilingual status inputs?
The system supports Spanish and English variants through a hard-coded alias map within validateStatus(). Inputs like Aplicado, enviada, or rechazada automatically map to their English canonical equivalents (Applied, Rejected) during the merge process, enabling multilingual batch workflows without requiring translation layers.
Can I add custom aliases for existing states?
Yes. Modify the aliases object in merge-tracker.mjs around line 58 to include new key-value pairs. For example, adding 'enviado': 'Applied' allows TSV files containing "enviado" to resolve correctly to the Applied canonical state without changing the underlying states.yml definition.
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 →