IT Leader · AI Builder · US Air Force Veteran

Jason  Darrow

I don't just manage projects. I build them.
I was the developer behind billion-dollar platforms
and multi-million dollar programs before I ever
managed them. That background is what I bring to
AI now. The results have surprised even me.

See the Projects GitHub → LinkedIn →
Background
Financial Services Platform Delivery
Active Projects
2
Stack
Python · Next.js · Claude API · SQLite · AWS
Status
Actively Building
Projects

AI Job Search System

Complete

What I Built

A job search tool I built for myself — and the first real AI project I have built and actually use. It surfaces relevant listings, gives me the company intelligence I need to decide whether to apply, and then handles the time-consuming parts: selecting the right resume bullets and drafting a cover letter. I stay in the loop at every step.

The pipeline scrapes job boards across multiple titles and locations, then I review each listing and mark the roles I want to pursue. For those roles, the system pulls company background, news, and a Claude-generated match score that compares the job description against my full 59-bullet resume database. I use that score to decide whether to move forward. When I do, Claude selects the best-fit bullets and drafts both a tailored resume and a voice-matched cover letter — both as editable Word documents I review and refine before anything goes out.

The best roles rarely come from a job board. They come from a referral or a company careers page. So the tailoring step takes a role from either source — pulled from the scraper, or typed in by hand — and runs the identical pipeline on both.

Application tracking happens in Notion, not in this pipeline. Every role moves through a tracker I update by hand, status by status, application to offer. Human in the loop, on purpose.

How It Works

AI Job Search System architecture Inputs on the left feed a four-stage pipeline: discovery, intelligence, tailoring, and document generation. Three amber human review steps sit between the stages. Data files and generated documents appear on the right. A shared AI layer of the Claude API, prompt rules, and output guardrails supports stages two through four. INPUTS PIPELINE · AMBER STEPS ARE MINE DATA & OUTPUTS 1 · Discovery job_scraper.py — filter, dedupe YOU · mark roles Interested 2 · Intelligence enrich_jobs.py — company brief + AI match score 0-100 Claude YOU · pick a role 3 · Tailoring resume_tailor.py — select + rewrite Claude 4 · Documents resume + cover letter generators Claude YOU · review, edit, submit Notion tracker Interested → Applied → Interview → Offer JSearch API postings + full descriptions NewsAPI · DuckDuckGo company background Manual entry referrals, careers pages master_resume.json source of truth · 59 bullets job_listings.xlsx canonical + dated archive HTML report company briefs + match badges tailored_COMPANY.json bullets + match score Resume .docx Cover letter .docx SHARED AI LAYER · BEHIND EVERY CLAUDE BADGE ABOVE Claude API bullet selection · match scoring Prompt rules voice · anti-AI · grounded in real bullets Guardrails bullet counts · length · page estimate Every stage runs from the Streamlit dashboard, or standalone from the command line. Claude selects and rewords existing experience — it never invents any, and it never sends anything.
Four stages, three points where I take over. The amber steps are mine.

The Dashboard

Job Search Dashboard, Review tab, showing scraped roles ready to be marked Interested
The Review tab. 177 roles scraped, 13 marked Interested, 3 resumes tailored. Every stage runs from a tab in this panel, with script output streamed live into the page.
Python 3 Claude API Streamlit JSearch API (OpenWeb Ninja) NewsAPI DuckDuckGo python-docx pandas AWS S3 Git
View on GitHub →
# Launch the dashboard — runs the whole pipeline $ streamlit run dashboard.py ✓ Control panel live at localhost:8501 # ...or run each stage from the command line $ python3 job_scraper.py ✓ 42 jobs found · 18 passed filters ✓ Job descriptions captured for each posting ✓ Saved: job_listings.xlsx # Tailor resume to a specific role (JD auto-filled from Excel) $ python3 resume_tailor.py \ --company "Fidelity" \ --title "IT Delivery Manager" \ --description "..." ✓ Match score: 93 / 100 ✓ Bullets selected and summary rewritten # Generate submission-ready Word doc $ python3 resume_generator.py \ --input output/tailored_Fidelity.json ✓ Resume saved: Jason_Darrow_Resume_Fidelity.docx • Length: ~2 page(s) (76/80 lines). # Generate voice-matched cover letter $ python3 cover_letter_generator.py \ --company "Fidelity" \ --title "IT Delivery Manager" \ --description "..." ✓ Cover letter saved: CoverLetter_Fidelity.docx
Build Log — AI Job Search
0
Resume Database

Structured master resume in JSON — 59 bullets tagged by skill, strength scored, ready for AI selection.

Complete
1
Job Scraper

Config-driven job search via JSearch API (OpenWeb Ninja). Captures full job descriptions at scrape time. Filters by salary, recency, job type, and title allowlist. Outputs to dated Excel.

Complete
2
AI Resume Tailor

Claude API reads job description, selects best-fit bullets, rewrites summary, generates Word doc. 93/100 match score.

Complete
2.5
Company Intelligence

Enriches shortlisted roles with company background, recent news, and industry data via DuckDuckGo and NewsAPI. Claude API scores each role against the master resume (0–100 match) and displays the badge in the HTML report.

Complete
3
HTML Job Report

Generates a formatted HTML report of enriched listings with company briefs and one-click resume tailor commands.

Complete
4
Portfolio Site

This site — documenting the project, the journey, and the build. Hosted on AWS S3 with Route 53.

Complete
5
Streamlit Dashboard

Browser control panel for the whole pipeline. Each stage runs from a button with live logs; review and tailor without touching the terminal.

Complete
6
AI Cover Letter Generator

Claude API generates a voice-matched cover letter grounded in the same bullets selected for the tailored resume. Writing rules, anti-AI guardrails, and before/after examples embedded directly in the prompt. Outputs a submission-ready .docx.

Complete
7
Off-Pipeline Roles & Output Guardrails

Tailoring now accepts a role typed in by hand, not just one found by the scraper, and optionally writes it into the tracker so both sources land in one view. Added validation on the model's own output: bullet-count overruns are trimmed, over-length summaries and bullets are reported, and the generator estimates rendered page count and warns before a three-page resume goes out. The page estimate uses wrapped line counts calibrated against real output rather than a PDF conversion, so it adds no dependencies.

Complete
Second Project

Getting Things Done with AI

What I Built

A full-stack personal weekly planner — built from scratch because nothing I tried kept calendar, habits, and weekly goals in one place without a subscription. This runs on a Linux box in my home office and is accessible from any device on the network.

The app is an Outlook-style weekly organizer with a full time grid, all-day events, recurring events, and per-category color coding. Below the calendar sit three weekly planning cards: a free-text Weekly Summary, a Daily Routine habit tracker with checkboxes across all seven days, and three SMART Goals scoped to the current week. All data persists to a local SQLite database via a Next.js API layer. Theme switches between Light and Graphite. Built with Claude Code.

It also writes me a morning brief. Every weekday at 7 AM a cron job reads today's events from Google Calendar, unread mail from Gmail, and three Notion databases: tasks, my networking tracker, and my job tracker.

The design decision I would defend in a review is what the model is not allowed to do. It never chooses the priority. A fixed ladder written in Python ranks the day (a high-priority task outranks a live job stage, which outranks an interview on the calendar, and so on down to the first event of the morning). Only after Python has picked the winner is the model handed that one item and asked to phrase it. It also writes the prep notes and a short narrative paragraph, and it makes one batched pass over unread mail to decide what is worth surfacing. Four narrow calls, every one with a deterministic fallback, so a model that is down degrades the brief instead of breaking it.

The model is llama3.1:8b running on my own hardware through Ollama. There is no API bill, and nothing from my calendar or inbox leaves the network.

GTD Weekly Organizer — week view GTD Weekly Organizer — planning panel

How the Daily Brief Works

AI Weekly Organizer daily brief architecture A weekday cron job runs one Python script that reads Google Calendar, Gmail, and three Notion databases. A narrow regex plus one batched local-model call filters the inbox. A fixed priority ladder written in Python then decides which single item matters most, with no model involved. Only after that is a locally hosted Llama 3.1 model asked to phrase the sentence, write prep notes, and draft a narrative paragraph, each with a deterministic fallback. The result is one JSON file the Next.js planner renders as a Daily Brief card. Everything runs on a self-hosted Linux server with no subscription and no data leaving the home network. MY DATA · READ ONLY GREEN DECIDES · RED ONLY WRITES TRIGGER & APP DATA 1 · Collect data/daily_brief.py — one job, five reads Google Calendar today's events Gmail unread, primary inbox Notion Tasks · Network · Jobs Weekday cron 7:00 AM Eastern 2 · Filter the inbox narrow promo regex, then one batched model call when it is unsure it keeps the mail MODEL 3 · Decide what matters a fixed priority ladder in Python, no model involved HIGH task > live job stage > interview on the calendar > overdue task > urgent email > first event of the day PYTHON ONLY 4 · Write the words the sentence, prep notes, the narrative paragraph canned text if the model is unavailable MODEL 5 · Publish data/daily-brief.json — atomic replace, no history Daily Brief card Next.js planner reads GET /api/brief SQLite · gtd.db calendar, habits, goals ME · read it with the first coffee ALL OF THE ABOVE RUNS ON ONE LINUX BOX IN MY HOME OFFICE Ollama · llama3.1:8b four narrow calls, my hardware, no API Ubuntu · PM2 · cron restarts on reboot, no babysitting No subscription and no calendar or mail leaves the network The model never chooses the priority. Python ranks the day from a fixed ladder, then the model is handed the winner and asked only to phrase it. Every model call has a deterministic fallback, so a dead model degrades the brief instead of breaking it.
Green decides, red only writes. The priority ladder is plain Python; the model is handed the winner and asked to phrase it.
Next.js 16 TypeScript React Tailwind CSS SQLite Drizzle ORM Python 3 Ollama · Llama 3.1 Google Calendar API Gmail API Notion API PM2 cron Ubuntu Claude Code
View on GitHub →
# Run locally $ npm run dev ✓ Ready in 1305ms → http://localhost:3000 # Deploy to Linux server under PM2 $ rsync -av --exclude node_modules --exclude .next \ gtd-app/ darrowj@homelab:~/gtd-app/ $ ssh darrowj@homelab \ "cd ~/gtd-app && npm install && npm run build && pm2 start npm --name gtd -- start" ✓ App running — accessible from any device on the network → http://homelab:3000
Build Log — Getting Things Done with AI
1
Full Calendar UI + SQLite Persistence

Week view and Day view with time grid (6 AM–10 PM), all-day band, recurring events (daily / weekly on chosen days), overlapping event layout, and per-category color coding. Event modal with all-day toggle, repeat weekday chips, reminder settings, and "save this occurrence vs. save all" for recurring edits. Planning panel with Weekly Summary, Daily Routine habit tracker, and SMART Goals — all scoped per week. Light and Graphite theme toggle. All data persists to SQLite via Next.js API routes and Drizzle ORM.

Complete
2
Linux Deploy

Synced to Ubuntu home server, running under PM2 with a startup hook. Accessible from any device on the local network, live and in daily use.

Complete
3
Daily Brief — Calendar, Gmail, Notion, Local LLM

A Python job (data/daily_brief.py) reads today's events from Google Calendar, unread mail from Gmail, and the job and network trackers from Notion, all over OAuth and REST. A deliberately narrow regex hard-drops obvious marketing, then one batched model call sorts the rest, biased to keep when it is unsure. A fixed priority ladder in Python then picks the single most important item, with no model involved. Only then is a locally hosted llama3.1:8b via Ollama asked to phrase that sentence, write prep notes, and draft a narrative paragraph. Four narrow calls in total, each with a deterministic fallback. Output is a single JSON file written by atomic replace and read by the planner at GET /api/brief. Installed on a weekday 7:00 AM cron. If the model is down the card says so, and the planner still works.

Complete
4
Brief Filters

Networking filter (intent detection plus a ±7 day follow-up window) and email noise filter (rule-based promo drop, then an Ollama keep/discard pass) are both live. Job-posting filter polish is the current work.

In Progress
5
Calendar Sync + Reminders

Pull live Google Calendar events into the planner grid itself, not just the brief. Reminder delivery by push and email. Editable routine items.

Planned
Background

About Me

I taught myself to code, starting with C-shell scripting, awk and sed, then Perl, while working as an RF technician at CellularOne. That turned into a full stack developer role at Click2Learn.com, building eLearning software for Fortune 1000 clients. From there I became a web application architect at Bank of America, building systems responsible for billions in managed assets. Later I moved into IT Delivery Manager at Voya Financial, overseeing programs from $250K to $3M.

Instead of just sending resumes right away, I decided to build the tool I wished existed, an AI system that finds relevant jobs, tailors my resume to each one, and tracks my progress. That became the first of several projects I'm actively building, including a weekly planner app I run my own schedule on today. This site documents all of them.

I'm learning AI by doing, not watching. Every week something new gets built, committed to GitHub, and shipped. The results have been genuinely surprising.

🎓
Education

MS Information Systems — Bentley College (Distinction)
BS MIS — Northeastern University (Magna Cum Laude)

📋
PMP · CSM Certified

Project Management Professional
Certified ScrumMaster

🛩️
US Air Force Veteran

Senior Airman
Honorable Discharge

🥋
BJJ Black Belt

Brazilian Jiu-Jitsu —
the hardest thing I've ever done

Get In Touch

Let's Talk

I'm currently open to IT Delivery Manager, Program Manager, and AI-Enabled Delivery roles in the Greater Boston area and remote.

If you're building something interesting with AI, or know someone who needs a delivery leader who can actually build — I'd love to hear from you.