AI Job Search System: Persistent Agentic Automation Pipeline
Project Overview
This project is a persistent AI-assisted job-search system built around a simple principle: reasoning, state, collection, configuration, and presentation should not all live in one chat or one application.
The system combines ChatGPT with Gmail, Google Drive, Supabase/Postgres, canonical resume routing, and a Google Sheets dashboard. It is designed to keep durable application state outside individual agent runs, reconcile new evidence safely, and leave consequential actions under human control.
I use AI heavily as an implementation partner. The portfolio claim here is not that I independently hand-coded every component; it is that I actively design, operate, validate, troubleshoot, and iterate the workflow and can explain the architecture and tradeoffs behind it.
The Problem
A normal conversational job-search workflow breaks down once it needs to remember and reconcile real operational state:
- the same posting can arrive from multiple sources;
- applications move through multiple recruiting stages;
- email confirmations and lifecycle updates arrive asynchronously;
- resume selection depends on the actual role;
- source data can be incomplete or stale;
- repeated runs must not duplicate work;
- a dashboard should be useful to a person without becoming a second source of truth;
- an AI agent should not silently submit applications or invent unsupported candidate facts.
The project evolved from solving each of these problems individually into a layered architecture with explicit authority boundaries.
End-to-End System Map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Job Sources / Alerts
|
| Current: Gmail alert ingestion
| Evolution: lean scheduled collector layer
v
Collection & Normalization
|
v
Supabase / Postgres
Canonical jobs, applications, lifecycle events, cutoffs, issues
|
+-------------------------+
| |
v v
Google Drive Gmail
Agent config, policy, Application confirmations
workflow modules, resumes and recruiting lifecycle events
| |
+------------+------------+
|
v
ChatGPT Job Search Agent
Resolve -> Evaluate -> Route Resume
Reconcile -> Rank -> Prepare Action
|
v
Human Review
Apply / Skip / Follow Up / Correct State
|
v
Google Sheets Dashboard
One-way presentation from Supabase
The important design choice is the separation: collection collects, Postgres persists, Drive configures, ChatGPT reasons, Gmail supplies external evidence, and the Sheet presents.
Layer 1: Canonical Configuration in Google Drive
The agent does not rely on a single giant prompt copied between chats. Its operating rules are stored in a canonical Google Drive workspace and separated into configuration, policy, schema, and workflow modules.
Examples of responsibilities include:
- candidate profile boundaries;
- target career lanes and geography;
- resume-family routing;
- job evaluation policy;
- database/state semantics;
- email-ingestion behavior;
- posting-resolution rules;
- deterministic output behavior;
- dashboard projection rules.
The root agent specification defines precedence and failure behavior so a missing dependency does not encourage the agent to improvise a different source of truth.
Why this matters
This makes the workflow portable and inspectable. A new agent run can reload the current operating rules from a durable workspace rather than depending on whatever happened to remain in chat context.
Layer 2: Supabase/Postgres as Authoritative State
The runtime source of truth is Supabase/Postgres, not the Google Sheet and not chat memory.
The state model separates:
- Jobs: durable posting identities and evaluation state
- Applications: current recruiting status for roles actually pursued
- Application Events: append-oriented recruiting evidence from email
- Control: independent ingestion cutoffs/cursors
- Issues: reusable workflow failures and fixes
The database also separates job state from application lifecycle state. For example, a job remains an applied job while the associated application can advance through assessment, interview, offer, rejection, or other supported stages.
Reliability decisions
- Canonical job identities prevent duplicate records from source rediscovery.
- Independent cutoffs prevent one failed ingestion stream from corrupting another.
- Important writes occur before cutoff advancement.
- Unknown fields remain unknown instead of being filled with guesses.
- Presentation markers are separate from ranking and canonical state.
Layer 3: Gmail as an External Event Stream
Gmail provides two different kinds of evidence:
- Job alerts used to discover candidate postings.
- Application messages used to establish submissions and later recruiting events.
The workflow treats email subjects and snippets as discovery signals rather than authoritative evidence. Candidate messages are read individually before they are allowed to mutate application state.
Application lifecycle messages can be matched using requisition identifiers, job identity, thread continuity, or sufficiently specific company/role context. When a message cannot be matched safely, it can be retained as unresolved evidence without changing the current application.
This design avoids turning every recruiter email or generic notification into a false status update.
Layer 4: ChatGPT as the Orchestration and Reasoning Layer
ChatGPT sits above the durable state and configuration layers.
A normal run can:
- load the current agent instructions and candidate configuration;
- ingest new job-alert observations;
- resolve postings against employer/ATS evidence;
- deduplicate and reconcile known jobs;
- evaluate realistic fit;
- route the correct canonical resume family;
- rank the active unapplied opportunity pool;
- ingest application confirmations and lifecycle events;
- surface next actions;
- update canonical state;
- refresh the user-facing dashboard.
The agent is therefore not the database. It is a reasoning/orchestration layer operating against explicit state and evidence boundaries.
Layer 5: Resume Routing
The workflow maintains separate resume families for:
- Security Operations
- Technical Operations
- Technical Delivery
Each lane also has an AI/LLM/agentic variant. The agent defaults to the normal version and selects the AI variant only when the role materially warrants it.
That creates deterministic routing rather than manually deciding between multiple filenames for every application.
The resume files remain canonical artifacts in Google Drive, while the database stores which resume was selected or actually used when that fact is known.
Layer 6: Google Sheets as a Presentation Layer
The Google Sheet is intentionally not the database.
Supabase projects one-way into a dashboard containing:
- current applications;
- recruiting activity;
- outstanding actions;
- application momentum;
- pipeline summary metrics.
Manual Sheet edits are never read back into runtime state. If I report a correction or application outcome, the canonical database is updated first and the dashboard is then rebuilt from that state.
This separation removed a class of synchronization problems where a human-readable spreadsheet and machine state could silently disagree.
Collection-Layer Evolution: From CyberScraper to a Lean Collector
The earlier CyberScraper project combined acquisition, normalization, local persistence, application tracking, market views, and a browser UI in one application.
That project proved useful patterns around heterogeneous ATS sources, normalization, source health, deduplication, automated testing, and GitHub Actions CI. It also made the cost of an overly integrated architecture clear.
Development of the full CyberScraper application is paused. The next direction is deliberately narrower: a lean collection and normalization layer whose job ends when clean observations reach canonical Supabase state.
The intended flow is:
1
2
3
4
5
6
7
8
9
10
11
12
Employer / ATS Sources
|
v
Lean Collector
Scheduled acquisition + normalization
|
v
Supabase/Postgres
|
v
Job Search Agent
Resolution + evaluation + application workflow
GitHub Actions is the natural scheduling/automation surface for that collection layer because it keeps deterministic acquisition separate from interactive agent reasoning. This is an architecture direction in progress, not a claim that the replacement collector is already a finished production service.
Human-in-the-Loop Boundaries
The workflow deliberately stops short of autonomous application submission.
The agent may research, evaluate, reconcile, rank, and prepare information, but it is not allowed to silently:
- submit an application;
- send outreach;
- create an external account;
- accept legal attestations;
- upload documents to an application form;
- invent citizenship, clearance, work authorization, proficiency, salary, or other unsupported facts.
That constraint is both a safety decision and an architecture decision. The system automates high-volume reasoning and state maintenance while leaving consequential external actions to the user.
Failure Isolation and Recoverability
One of the most important design lessons was to avoid treating the entire agent run as one all-or-nothing procedure.
Examples:
- A dashboard refresh failure should not invalidate a successful database reconciliation.
- A lifecycle-email parsing failure should not automatically corrupt job-alert ingestion.
- A missing optional recovery tool should not cause the system to invent posting facts.
- Presentation-state failures should leave the underlying job or event recoverable for the next run.
The result is a workflow that can degrade partially without silently changing its source of truth.
What I Own vs. What AI Assists With
AI tools are heavily involved in implementation, refactoring, research, and debugging. I do not present that as traditional solo software engineering.
My direct contribution is strongest in:
- defining what the workflow should do;
- deciding which system owns which state;
- identifying where prior designs are too complex or fragile;
- setting evidence and safety boundaries;
- structuring agent configuration and policy;
- testing real runs and identifying failure modes;
- reviewing output for unsupported assumptions;
- deciding when to simplify architecture;
- iterating the system as requirements change.
This is the type of work I want to continue doing: using AI to move quickly while still understanding and controlling the operational system around it.
Skills Demonstrated
- Agentic workflow design
- Tool-connected AI systems
- Human-in-the-loop automation
- Persistent state and source-of-truth design
- Supabase/Postgres data modeling concepts
- Gmail and Google Drive workflow integration
- Resume-routing and policy design
- Evidence validation and reconciliation
- Deduplication and idempotent workflow concepts
- Failure isolation and recoverability
- Technical documentation
- AI-assisted development with ChatGPT, Codex, and Claude Code
- Architecture simplification and iterative system design
Current Direction
The system continues to evolve toward a cleaner separation between deterministic collection and AI reasoning. The goal is not to automate every possible action; it is to make the repetitive parts reliable, preserve trustworthy state, and use AI where judgment and synthesis provide the most value.