akbardevop/ai-job-agent/job-patterns

Claude Code and agent skill by akbardevop/ai-job-agent

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Read application-tracker.csv and outreach-log.csv, find non-obvious patterns in rejections / non-responses / interview rates / stage-of-loss, surface insights as markdown tables plus 3 concrete actionable takeaways. Proactively invoke this skill (do NOT answer conversationally) when the user asks "what's working", "what's not working", "analyze my rejections", "find patterns", "why am I getting rejected", "what's holding me back", "rejection analysis", "where am I losing", "analyze my pipeline"…

Install

npx vskill@latest install akbardevop/ai-job-agent/job-patterns

SKILL.md

Job Patterns

Diagnostic companion to /job-track and /job-dashboard. Reads the two CSV sources of truth (application-tracker.csv + outreach-log.csv), slices them along the dimensions that actually predict outcomes (ATS, time-to-rejection, geography, role-type, day-of-week, outreach response), and renders 4-5 markdown tables plus 3 concrete actionable insights.

Where /job-track says what the pipeline looks like, /job-patterns says why it looks that way and what to change.

Repo location

$AI_JOB_AGENT_ROOT → ~/.claude/skills/ai-job-agent/ → REPO_PATH marker file → ~/ai-job-agent/.

Status emoji (consistent with /job-track)

📄 applied · 📬 submitted · 💼 interview · 🎯 offer · ❌ rejected · 🚫 blocked · 🚪 withdrawn

Workflow

Step 1 — Resolve repo + read both CSVs
  1. Resolve $AI_JOB_AGENT_ROOT (env var → default skills path → REPO_PATH marker → ~/ai-job-agent/).
  2. Read $AI_JOB_AGENT_ROOT/application-tracker.csv (or $LOCAL_TRACKER).
  • Columns: date, company, role, status, location, source, applied_by, url, notes, contact, compensation, days_since, key
  1. Read $AI_JOB_AGENT_ROOT/outreach-log.csv (or $OUTREACH_LOG).
  • Columns: sent_at, company, role, to_name, to_email, to_title, to_linkedin, subject, body_file, message_id, status, replied_at, follow_up_count, last_follow_up_at, notes
  1. If application-tracker.csv is missing or has 0 rows, tell the user to run /job-apply or bash setup.sh and stop.
  2. If both files combined have fewer than 10 application rows, render this and stop:

> Not enough data yet (N applications). Patterns surface around 20-30 apps. Keep going for a week or two and re-run /job-patterns.

Step 2 — Compute the six signals

For each signal below, compute the slice → render the table.

Signal A — Rejection rate by ATS source/platform

Group application-tracker.csv by source (or infer from url host if source is empty). Bucket into: linkedin, greenhouse, lever, jobvite, ashby, workday, direct-email, other.

For each platform: count total apps, count rejections, count interviews, compute rejection rate and interview rate.

PlatformApps❌ Rejected💼 InterviewRejection %Interview %
greenhouse1814178%6%
lever127258%17%
linkedin2210445%18%
ashby41125%25%
direct-email61317%50%

Sort by rejection rate descending. Skip platforms with apps < 3 (too noisy) or list them in a separate "low-volume" footnote.

Signal B — Time-to-rejection histogram

For every row where status == rejected, compute days between date (applied) and the rejection (use notes for the rejection date if logged; else fall back to days_since column or skip the row).

Bucket into:

  • <24h = ATS keyword filter (resume didn't pass screen)
  • 1-3 days = recruiter screen kill (recruiter looked, said no)
  • 4-14 days = hiring manager kill (got past recruiter, lost to another candidate)
  • >14 days = ghosted / silent (never decisioned)
BucketLikely causeCount% of rejections
❌ <24hATS keyword filter938%
❌ 1-3 daysRecruiter screen kill521%
❌ 4-14 daysHiring manager kill417%
❌ >14 daysGhosted / silent625%

The biggest bucket is the user's biggest leak. Call it out explicitly.

Signal C — Geography signal

Group apps by location (normalize: "Remote", "Bay Area", "NYC", "Texas", "Other US", "International"). For each: app count, interview count, interview rate.

GeographyApps💼 InterviewsInterview %
Bay Area1400%
Remote18317%
Midwest8225%
NYC6117%

Sort by interview rate descending. Geographies with <3 apps go in a footnote.

Signal D — Role-type signal

Classify each row's role into a bucket via keyword match (case-insensitive):

  • software — software, swe, backend, frontend, full-stack, mobile, ml, ai, data, platform
  • electrical — electrical, ee, power, substation, circuits, hardware, firmware, embedded
  • research — research, scientist, phd, lab, grad
  • product/design — product, pm, design, ux
  • other — anything else
Role typeApps💼 Interviews❌ RejectedInterview %
software2441417%
electrical181136%
research62233%
product/design4030%

Sort by interview rate descending.

Signal E — Outreach response rate by company tier

Read outreach-log.csv. A row "replied" if replied_at is non-empty OR status ∈ {replied, interview_scheduled}.

If config/search-plan.md exists, read it and tag each company as Tier 1 / Tier 2 / Tier 3 based on the file's company list. If no search-plan, group by to_title instead (vp/director/manager/recruiter/engineer/other).

GroupSent✉️ RepliedResponse %
Tier 1 (target)8338%
Tier 2 (warm)11218%
Tier 3 (cold)1417%

Or, when no search-plan exists:

Recipient titleSent✉️ RepliedResponse %
VP / Director6350%
Hiring Manager9222%
Recruiter1218%
Engineer (peer)5240%

Sort by response rate descending.

Signal F — Day-of-week signal

For each application row, parse date to weekday. For each weekday: count apps + count interviews + compute interview rate. Same for outreach: weekday of sent_at + reply rate.

WeekdayApps sent💼 Interview %Outreach sent✉️ Reply %
Mon1225%633%
Tue1421%825%
Wed813%520%
Thu911%425%
Fri119%30%
Sat40%20%
Sun60%10%

Skip weekdays with apps < 2 (too noisy).

Step 3 — Render the 3 actionable insights

After the tables, output a section titled "What to change this week" with exactly 3 bullets. Each bullet must:

  1. Cite a specific number from one of the tables above (e.g., "Greenhouse 78% vs LinkedIn 45%").
  2. State the likely cause in one phrase (e.g., "your Greenhouse-tailored resume is weaker than the LinkedIn one").
  3. Propose one concrete change the user can do this week (e.g., "tailor a Greenhouse-specific resume variant — keywords, format, length — and re-run 5 Greenhouse apps with it").

Pick the 3 strongest signals — biggest gap, smallest p-value if you can eyeball it, biggest volume × biggest delta. Don't pad. If only 2 signals are strong, output 2 bullets and say "only 2 strong signals at this volume, more to come."

Example output:

### What to change this week
1. Greenhouse rejection rate is 78% vs LinkedIn 45% — your Greenhouse-tailored resume is weaker than the LinkedIn one (or you're not tailoring per-platform). Build a Greenhouse-specific variant this week and re-run your last 5 Greenhouse rejections with it.
2. 38% of rejections come within 24h — that's pure ATS keyword filter, not a recruiter looking. Run /resume-ats-optimizer against your top 3 target JDs and rewrite the bullets that are missing keywords. Don't apply to anything else until that's done.
3. Bay Area apps are 0/14 on interviews while Midwest is 2/8 — you're being filtered out as a non-local Mizzou student in the Bay Area pool. Either add a "willing to relocate, will pay own move" line to your Bay Area cover letter, or stop spending Bay Area applications and double down on Midwest + Remote where the conversion is happening.
Step 4 — Footer

End with a one-liner pointing to the next move:

Run /job-track to see the raw pipeline, /job-followup if you want to nudge the cold contacts, or paste a new job URL to apply with the lessons above.

Rules

  1. No narrative prose dumps. All findings go in tables. The only prose section is the 3-bullet "What to change this week."
  2. Show, don't editorialize. Don't say "Greenhouse is bad" — show 78% vs 45% and let the user conclude.
  3. Honest about volume. If a slice has <3 rows, footnote it as low-volume; don't draw conclusions from it.
  4. Cite specific numbers in every actionable insight. "Greenhouse 78%" beats "Greenhouse seems high."
  5. Re-runnable. Read-only on both CSVs. Never mutate application-tracker.csv or outreach-log.csv.
  6. Sparse data fallback. <10 apps → tell the user to wait, don't fabricate patterns.
  7. Status mapping is case-insensitive. Handle Rejected, rejected, REJECTED the same way.

Related

  • /job-track — flat view of the tracker, no analysis.
  • /job-dashboard — applications + outreach + follow-ups in one snapshot.
  • /job-followup — act on the cold-outreach signal once /job-patterns says response rates are low.
  • /resume-ats-optimizer — fix the ATS keyword filter problem when Signal B's <24h bucket is winning.
  • /tailor-resume — fix per-platform rejection deltas surfaced by Signal A.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
67
Repository forks
13
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/akbardevop/ai-job-agent/job-patterns/badge)](https://verified-skill.com/skills/akbardevop/ai-job-agent/job-patterns)

Something wrong with this skill or its page? Tell us.