job-patterns
Skill61 starsChanged 6 months agoMITView on GitHub
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", "why no responses", or invokes /job-patterns. Prefer this over `/job-track` or `/job-dashboard` when the user wants diagnosis, not status.
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 30
Read $AI_JOB_AGENT_ROOT/application-tracker.csv (or $LOCAL_TRACKER).
- Very specific: line 34
If application-tracker.csv is missing or has 0 rows, tell the user to run /job-apply or bash setup.sh and stop.
- Distinctive: line 35
If both files combined have fewer than 10 application rows, render this and stop:
- Very specific: line 112
Read outreach-log.csv. A row "replied" if replied_at is non-empty OR status ∈ {replied, interview_scheduled}.
- Very specific: line 114
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.
- Distinctive: line 151
After the tables, output a section titled "What to change this week" with exactly 3 bullets.
- Distinctive: line 175
No narrative prose dumps: All findings go in tables.
- Distinctive: line 176
Show, don't editorialize: Don't say "Greenhouse is bad" — show 78% vs 45% and let the user conclude.
- Distinctive: line 177
Honest about volume: If a slice has <3 rows, footnote it as low-volume.
- Very specific: line 179
Re-runnable: Read-only on both CSVs. Never mutate application-tracker.csv or outreach-log.csv.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
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
- Resolve
$AI_JOB_AGENT_ROOT(env var → default skills path → REPO_PATH marker →~/ai-job-agent/). - 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
- Columns:
- 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
- Columns:
- If
application-tracker.csvis missing or has 0 rows, tell the user to run/job-applyorbash setup.shand stop. 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.
| Platform | Apps | ❌ Rejected | 💼 Interview | Rejection % | Interview % |
| greenhouse | 18 | 14 | 1 | 78% | 6% |
| lever | 12 | 7 | 2 | 58% | 17% |
| 22 | 10 | 4 | 45% | 18% | |
| ashby | 4 | 1 | 1 | 25% | 25% |
| direct-email | 6 | 1 | 3 | 17% | 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)
| Bucket | Likely cause | Count | % of rejections |
| ❌ <24h | ATS keyword filter | 9 | 38% |
| ❌ 1-3 days | Recruiter screen kill | 5 | 21% |
| ❌ 4-14 days | Hiring manager kill | 4 | 17% |
| ❌ >14 days | Ghosted / silent | 6 | 25% |
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.
| Geography | Apps | 💼 Interviews | Interview % |
| Bay Area | 14 | 0 | 0% |
| Remote | 18 | 3 | 17% |
| Midwest | 8 | 2 | 25% |
| NYC | 6 | 1 | 17% |
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 type | Apps | 💼 Interviews | ❌ Rejected | Interview % |
| software | 24 | 4 | 14 | 17% |
| electrical | 18 | 1 | 13 | 6% |
| research | 6 | 2 | 2 | 33% |
| product/design | 4 | 0 | 3 | 0% |
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).
| Group | Sent | ✉️ Replied | Response % |
| Tier 1 (target) | 8 | 3 | 38% |
| Tier 2 (warm) | 11 | 2 | 18% |
| Tier 3 (cold) | 14 | 1 | 7% |
Or, when no search-plan exists:
| Recipient title | Sent | ✉️ Replied | Response % |
| VP / Director | 6 | 3 | 50% |
| Hiring Manager | 9 | 2 | 22% |
| Recruiter | 12 | 1 | 8% |
| Engineer (peer) | 5 | 2 | 40% |
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.
| Weekday | Apps sent | 💼 Interview % | Outreach sent | ✉️ Reply % |
| Mon | 12 | 25% | 6 | 33% |
| Tue | 14 | 21% | 8 | 25% |
| Wed | 8 | 13% | 5 | 20% |
| Thu | 9 | 11% | 4 | 25% |
| Fri | 11 | 9% | 3 | 0% |
| Sat | 4 | 0% | 2 | 0% |
| Sun | 6 | 0% | 1 | 0% |
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:
- Cite a specific number from one of the tables above (e.g., "Greenhouse 78% vs LinkedIn 45%").
- State the likely cause in one phrase (e.g., "your Greenhouse-tailored resume is weaker than the LinkedIn one").
- 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
- 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.
- 38% of rejections come within 24h — that's pure ATS keyword filter, not a recruiter looking. Run
/resume-ats-optimizeragainst your top 3 target JDs and rewrite the bullets that are missing keywords. Don't apply to anything else until that's done.- 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-trackto see the raw pipeline,/job-followupif you want to nudge the cold contacts, or paste a new job URL to apply with the lessons above.
Rules
- No narrative prose dumps. All findings go in tables. The only prose section is the 3-bullet "What to change this week."
- Show, don't editorialize. Don't say "Greenhouse is bad" — show 78% vs 45% and let the user conclude.
- Honest about volume. If a slice has <3 rows, footnote it as low-volume; don't draw conclusions from it.
- Cite specific numbers in every actionable insight. "Greenhouse 78%" beats "Greenhouse seems high."
- Re-runnable. Read-only on both CSVs. Never mutate
application-tracker.csvoroutreach-log.csv. - Sparse data fallback. <10 apps → tell the user to wait, don't fabricate patterns.
- Status mapping is case-insensitive. Handle
Rejected,rejected,REJECTEDthe 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-patternssays 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.
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- dilolabs/nosia★ 213same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository14 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- job-applySkill
- job-coachSkill
- job-cvSkill
- job-dashboardSkill
- job-evaluateSkill
- job-followupSkill
- job-interviewSkill
- job-outreachSkill
- job-recapSkill
- job-setupSkill
- job-statusSkill
- job-trackSkill
- job-triageSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

