Job Analysis Processor

Automatically scores job opportunities (0-10 scale) against your CV using OpenAI GPT-4o-mini. Records are classified into alerts, suggestions, applications, and unclassified emails.

Processing Pipeline

1. Email arrives at john.js@critchley.biz2. newparser_jobserve.py processes the email3. js_alert_parser.py extracts structured job data from HTML4. Email classified as: alert, suggestion, application, or unclassified5. For alerts/suggestions: should_skip_job() pre-filter runs FIRST (see below)6. If not skipped: CV sent to OpenAI with scoring prompt7. Scored jobs stored in ~/.jobserve.gdbm; applications stored in SEPARATE ~/.jobserve_applications.gdbm8. job_analysis_report.py generates HTML and deploys to web server

Pre-Filter: should_skip_job()

BEFORE calling the OpenAI API, should_skip_job() checks the parsed job for known blockers. If triggered, the job gets score=0 and a reason string WITHOUT spending an API call.Current skip rules:• Security clearance required — if description mentions SC/DV/CTC clearance as a requirement• Unreachable location — checks against a list of locations too far for daily commute (Scotland, Northern Ireland, etc.)This saves significant OpenAI costs by filtering out obviously unsuitable jobs locally.

Key Files

newparser_jobserve.py

Main handler for JobServe emails. Functions: classify_job(email_message), should_skip_job(parsed_job), analyze_job(parsed_job), store_result()

js_alert_parser.py

HTML parser extracts: job_title, company, location, salary, work_type (full-time, contract, etc.), description, employment_business, job_url, reference, posted_date

job_analysis_report.py

Report generator with three sections:• Scored Jobs - AI-ranked opportunities (from ~/.jobserve.gdbm)• Job Applications - Application confirmations (from ~/.jobserve_applications.gdbm)• Unclassified Emails - Debug table for non-matching emails

Classification Logic

Email Subject Analysis:• 'Job Alert' or similar → job_type='alert'• 'Job Suggestion' or similar → job_type='suggestion'• 'Job Application' or 'Application Confirmation' → job_type='application' → stored in APPLICATIONS DB• Other → unclassified={}

OpenAI Scoring Prompt

MODEL: gpt-4o-miniSYSTEM PROMPT KEY POINTS:• BE DISCRIMINATING: Use full 0-10 range, avoid grade inflation• Scores 0-3: Poor fit or critical blockers• Scores 4-6: Moderate fit with gaps• Scores 7-8: Strong fit with minor gaps• Scores 9-10: Exceptional fitCRITICAL BLOCKERS (score 0-2):• Job requires ACTIVE security clearance, candidate has none• Job location requires daily commute >2.5 hours and not remote/hybrid• Candidate fundamentally lacks core required skills (not nice-to-have)LOCATION ASSESSMENT:• Bristol area: Home base• Bath, Swindon, local: Commutable• London, Reading, Guildford: 2-3 hours, acceptable for 2-3 days/week hybrid• Birmingham, Cardiff: 1-1.5 hours, good for hybrid• Scotland/Northern England/daily onsite: NOT SUITABLE

Deduplication

Uses Message-ID as unique key. If same Message-ID seen twice, existing record is skipped (idempotent).

Database Cleanup

Triggered by job_analysis_report.py::process_job_analysis():• Scored jobs older than 14 days: Deleted from ~/.jobserve.gdbm, UIDL returned for email deletion• Applications older than 28 days: Deleted from ~/.jobserve_applications.gdbm, UIDL returned for email deletion• Unclassified emails: Kept indefinitely for debugging

Configuration

• MODEL: gpt-4o-mini• CV_PATH: Environment variable, defaults to ~/CV/cv_llm_optimized.md• OpenAI key: ~/.openai• Jobs DB: ~/.jobserve.gdbm• Applications DB: ~/.jobserve_applications.gdbm

Reports

Live at https://www.critchley.biz/JobAnalysisClick score to view detailed AI reasoningColor-coded by score (see popit3/report-generation for details)

version2