Reusable Engine

tailor-resume

Extracted the resume tailoring core from AutoApply AI and shipped it as a standalone engine. 190 automated tests, four distribution surfaces (CLI, Streamlit, MCP, PyPI), and hosted on Fly.io. The strongest engineering move was modularization - now the same pipeline powers multiple products.

190 automated tests 4 distribution surfaces Single-page output enforced No fabrication guarantee Fly.io + PyPI + Streamlit
Python MCP server Streamlit FastAPI LaTeX FAISS / pgvector Fly.io PyPI

Why Extract It

The resume tailoring logic inside AutoApply AI was the most reusable piece of the system - and the hardest to test, because it was embedded in the extension flow. Extracting it into a standalone package with a clean interface (parse → gap analysis → render) made it testable in isolation, independently deployable, and usable outside the AutoApply context.

The extraction also proved the architecture was right: a pipeline with clear boundaries at each stage is easier to extract than one with implicit dependencies. The 190 tests came from finally having a module boundary to test against.

Pipeline Architecture

Step 1: Parse Artifacts

Any resume format in: blob (pasted text), LaTeX, Markdown, LinkedIn PDF, uploaded PDF, DOCX. Three-tier PDF extraction (pdfminer.six for CMR fonts, pypdf for Word-generated, stdlib fallback). OT1 normalization post-processes garbled characters from CMR font decoding. Output: a typed Profile object.

Step 2: Gap Analysis

JD decomposition extracts must-haves and maps them to 10 signal categories (testing_ci_cd, orchestration, ml_ai_platform, etc.). FAISS retrieval finds the strongest matching evidence from the Profile. The ATS Score Estimate (0-100) gates whether to proceed - below 50 means no resume produced, honest ceiling reported.

Step 3: Render LaTeX

Claude rewrites bullets using the STAR formula: "Accomplished X as measured by Y by doing Z." A 3-pass iterative loop converges on a single-page output - the page limit is enforced as a constraint, not a suggestion. PII is injected at render time (never baked into templates). No fabrication: Claude only reframes evidence you provide.

Four Distribution Surfaces

The same pipeline, four interfaces - no code duplication:

CLI + PyPI

pip install tailor-resume then tailor-resume --artifact PATH:FORMAT --jd JD_PATH. Zero-config default: core pipeline runs on stdlib only. Cloud features (Pinecone, Supabase) are opt-in extras.

Streamlit + MCP Server

Browser-based UI at tailor-resume-ai.streamlit.app - paste your work history and JD, get a tailored PDF. MCP server on Fly.io exposes 4 typed tools (extract_profile, analyze_gap, render_latex, run_pipeline) for direct use inside Claude Code or any MCP-compatible agent.

Claude Code Skill

The /tailor-resume skill is the interactive mode - conversational, multi-pass, with clarification loops when evidence is weak. This is the highest-quality surface because it can ask for missing metrics rather than guessing. Used by me for actual job applications.

Quality Signal

190 tests with no API keys required - all LLM calls are mocked at the boundary. The test suite includes regression tests (files named _regression) that capture behavioral quirks as characterization tests. Changing them is a deliberate act, not an accident.

ATS-aware claim discipline: the honest ceiling concept means the system will tell you when a role is out of reach given your actual experience - rather than producing a resume that technically passes keyword matching but misrepresents you in a screen. That's the design choice that makes it useful for real job searching rather than just demos.

Integration Roadmap

Tier 1 is complete: CLI, PyPI, Streamlit, MCP server, Fly.io hosted API. Tier 3 targets direct integration into AutoApply AI - a "Tailor for this job" button in the Chrome extension that calls the tailor-resume API, updates the vault, and re-generates form answers with the new tailored resume as context. JobScout will surface tailor-resume recommendations on job cards via the best-match vault API.