How the Pattern Analysis Script Identifies Rejection Patterns and Improves Targeting

The analyze-patterns.mjs script parses data/applications.md and individual markdown reports to classify outcomes as positive, negative, or self-filtered, extracts hard-stop blockers like geo-restrictions and stack-mismatches, and generates quantifiable recommendations to tighten targeting filters and optimize your job search strategy.

The santifer/career-ops repository includes a sophisticated pattern analysis tool that transforms raw application history into data-driven targeting improvements. By processing your tracker file and generated reports, the script identifies exactly which rejection patterns waste your evaluation effort and proposes concrete configuration changes to improve your hit rate.

How the Script Ingests and Normalizes Application Data

The analysis pipeline begins by loading the central tracker and individual report files.

Parsing the Tracker and Report Files

The parseTracker function (lines 52-70) reads data/applications.md and converts each line into a structured object containing the report link, score, and status. For every entry, parseReport (lines 73-106) reads the linked markdown file to extract the Machine Summary block, table fields (archetype, seniority, remote policy, team size), the scoring table, and the "gaps" table listing hard-stop and soft-gap observations.

Classifying Outcomes and Enriching Metadata

Raw status strings are cleaned via normalizeStatus and mapped to canonical definitions from templates/states.yml. The classifyOutcome function (lines 75-81) then buckets each application into positive, negative, self_filtered, or pending outcomes.

Each entry is enriched with calculated buckets. The classifyRemote function categorizes remote policies into global remote, regional remote, hybrid/onsite, or geo-restricted, while classifyCompanySize groups companies into startup, scale-up, or enterprise tiers.

Detecting Rejection Blockers from Gap Analysis

The core rejection-pattern detection happens in the extractBlockerType function (lines 36-45), which examines every gap extracted from the reports.

Categorizing Hard-Stop Blockers

For each gap, the script determines if it represents a geo-restriction, stack-mismatch, seniority-mismatch, onsite-requirement, or other blocker. Soft gaps marked as nice or soft are deliberately ignored to focus only on deal-breakers. A blockerCounts frequency map tallies each blocker type across the entire enriched dataset (lines 38-46), revealing which rejection reasons dominate your pipeline.

Extracting Tech-Stack Gaps

For negative and self-filtered outcomes, the script performs additional tech-stack extraction (lines 100-114) to identify specific technologies mentioned in gap descriptions. This surfaces whether missing Python, JavaScript, Go, or other skills are systematically blocking your applications.

Generating Data-Driven Targeting Recommendations

Based on the aggregated blocker analysis, the script derives actionable recommendations with specific thresholds.

Geo-Restriction and Stack-Mismatch Thresholds

If geo-restriction blockers appear in 20% or more of applications, the script recommends tightening location filters in portals.yml (lines 24-32). Similarly, when stack-mismatch blockers hit 15% or higher, it lists the top missing technologies and suggests adding negative filters to your search configuration (lines 34-43).

Score Thresholds and Archetype Optimization

The script calculates the lowest score among all positive outcomes to propose a minimum viable score threshold before generating PDFs (lines 45-52). It also identifies the best-performing archetype and remote-policy combinations, advising you to double down on high-conversion categories while eliminating policies showing 0% conversion rates (lines 54-71).

Running the Pattern Analysis

Execute the script from the repository root to generate the analysis.

Run a full JSON analysis to get machine-readable output:

node analyze-patterns.mjs

Generate a human-readable summary table:

node analyze-patterns.mjs --summary

Verify the Machine Summary parser integrity:

node analyze-patterns.mjs --self-test

The default JSON output includes metadata, funnel statistics, blocker analysis with percentages, and specific recommendations targeting your portals.yml configuration.

Summary

  • The parseTracker and parseReport functions ingest data from data/applications.md and individual markdown reports to build a structured dataset.
  • extractBlockerType classifies hard-stop rejection reasons into geo-restrictions, stack-mismatches, and other blockers while ignoring soft gaps.
  • Recommendation thresholds trigger at 20% for geo-restrictions and 15% for stack-mismatches, proposing specific filters for portals.yml.
  • The script calculates minimum viable score thresholds from positive outcomes and identifies high-converting archetypes to optimize your targeting strategy.

Frequently Asked Questions

How does the script distinguish between soft preferences and hard rejection blockers?

The extractBlockerType function (lines 36-45) examines gap classifications from the report parser. It explicitly filters out gaps tagged as nice or soft, processing only hard-stop observations that represent actual rejection reasons such as geo-restrictions or mandatory onsite requirements.

What specific thresholds trigger the targeting recommendations?

The script implements quantified thresholds: geo-restriction recommendations trigger when 20% or more of applications hit location limits, while stack-mismatch advice appears at 15% frequency. These thresholds ensure recommendations reflect statistically significant patterns rather than isolated incidents.

Can I run this analysis if I haven't generated individual markdown reports yet?

No. The parseReport function requires the individual markdown reports referenced in data/applications.md to extract the Machine Summary blocks and gap tables. Without these generated reports, the script cannot perform blocker classification or outcome analysis.

How does the script determine the minimum score threshold for future applications?

The script analyzes the score distribution of all positive outcomes (successful applications) and identifies the minimum score in that cohort (lines 45-52). It then recommends setting your minimum viable score slightly above this floor to avoid wasting effort on applications unlikely to convert, based on your historical success data.

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 →