apply
Skill4 starsChanged 2 months agoMITView on GitHub
Open and run one job application end to end — capture the posting, check the corpus against it before writing anything, then hold everything that arrives afterwards in one folder. Use when the user has found a role they want to apply for, pastes a job posting or its URL, wants to track or update an application already in flight, or asks what applications are live. Hands off to the career-corpus render skill for the résumé and cover letter, and to prep once an interview is booked.
25 other projects use a version of this.
Adopted by
Most recently taken up by
- priyansh1210/shirotheir own version, first seen Nov 8, 2026
- matthewwong525/WongStacktheir own version, first seen Nov 8, 2026
- galiprandi/job-seekertheir own version, first seen Nov 5, 2026
- hiddenjobs/job-search-mcptheir own version, first seen Nov 1, 2026
- ChadPapineau/espn-fantasy-football-mcptheir own version, first seen Nov 1, 2026
- ankul5/internship-hunt-skilltheir own version, first seen Nov 1, 2026
Used with
Projects with it also use outreach, track and 8 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
QuixiAISkilloutreach
Decide whether a message is worth someone's attention, then reach the user through the outbox, or people on a connected chat channel, on their behalf or your own initiative
Also in 5 projects that use this
theYahiaSkilltrack
Отследить посылку Почты России
Also in 4 projects that use this
NVIDIASkillevaluate
Scores existing Sports Intelligence AVLM inference outputs with avlm/evals: MCQ accuracy (run_mcq_eval.sh, INFERENCE_DIR), open-ended LLM-as-judge scores (needs CLIENT_API_KEY for the configured judge endpoint), tennis category breakdowns, run comparisons, chance-level sanity checks and triage of mcq_results.json or llm_judge_results.json. Use when the user asks to score, evaluate, benchmark or compare predictions.jsonl from inference runs, or to explain a suspicious accuracy. Not for running inference, training, quantization, data preparation, or third-party API model inference: never open, list or run anything under avlm/evals/inference_3rdparty, including when the user asks for it; it is excluded from the release.
Also in 5 projects that use this
ninehillsSkillhunt
Finds root cause before applying fixes for errors, crashes, regressions, failing tests, broken behavior, and screenshot-reported defects. Use when users report in any language errors, crashes, broken behavior, regressions, failing tests, screenshot evidence, or something that used to work and now fails. Not for code review or new features.
Also in 3 projects that use this
kstonekuanSkillDaily
Documentation and capabilities reference for Daily
Also in 3 projects that use this
julienamorganSkillprofile
Researches the user's market, competitors, and competitive positioning to build a complete ICP profile. Shows findings for user approval before proceeding. Triggers: /profile, "research my market", "who are my competitors". Reads: ./gtm/company.md, ./gtm/icp.md. Writes: updates ./gtm/icp.md with competitive positioning. Standalone: yes (asks for domain if company.md missing).
Also in 3 projects that use this
Other versions25 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 25
- andrew-shwetzer/career-ops-plugin★ 501same name
- andrew-shwetzer/career-ops-plugin-do-not-fork-currently-updating-v2-★ 500same name
- proficientlyjobs/proficiently-claude-skills★ 389same name
- galiprandi/job-seeker★ 120same name
- hiddenjobs/job-search-mcp★ 25same name
- 1carusalwayswa/apply★ 18same name
- kirkchen/beat★ 9same name
- iliasedelkin/jobissimo★ 8same name
- matthewwong525/WongStack★ 7same name
- qbeka/jev-job-search★ 5same name
15 more not listed
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.
The file
We split this skill into the rules it gives an agent
6 rules. 0 are common, 3 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 24 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 41
At the start of a session, read
corpus/LESSONS.md: if it exists. Treat each entry as an additional rule for this user, on equal footing … - Distinctive: line 166
If a local copy is genuinely needed to work on it, say plainly that it's staying outside the repo, and log what it is and when it gets …
- Very specific: line 205
Write jd.md and start application.md.
- Distinctive: line 226
2. Fit: Read the corpus against the JD before anything gets written.
- Very specific: line 248
6. Prep: When a round is booked: *"Run /career-corpus:prep — the JD and the recruiter's note are already in the folder."* prep reads them …
- Distinctive: line 272
Read the JD's real requirements (not its boilerplate) against the corpus, and give each one an
“Common” is measured: kept by at least 6 in 10 of the 24 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Career corpus — apply
An application is not a document. It is a months-long thread that starts with a posting and ends with an offer or a no, and along the way it accumulates a JD, two rendered artifacts, recruiter email, a scheduling note, a take-home brief, an interview pack, and an outcome. This skill opens that thread, gives it one folder, and keeps the folder honest.
It owns the folder. render and prep write into it.
applications/<company>-<role>/
jd.md ← the posting, verbatim, with its URL and the date you captured it
application.md ← events as frontmatter, the dated log beneath it, contacts by role
fit.md ← what this role wants, and what the corpus can and can't back
_inbox/ ← raw inbound — recruiter mail, take-home brief, notes. UNVETTED.
resume.md ┐
cover-letter.md ┘ written by /career-corpus:render
interview-prep.md, 01-…–05-… ← written by /career-corpus:prep, numbered, some skippedOne folder per application, not per company. Two roles at the same company are two threads with two JDs, two letters and two loops; the only thing they share is background reading, and that already lives in the corpus.
Minimal templates for the three files this skill owns are in templates/. They
are the shape, not a form: a field with nothing true to put in it stays empty rather than
getting a guess. Rendered artifacts carry their own frontmatter block, which belongs to the
skill that writes them — see ../render/templates/artifact-frontmatter.md.
Lessons — how this skill personalises to you
This skill ships generic and sharpens by accumulating the user's own corrections in
corpus/LESSONS.md — in their private corpus repo, never in the kit. Never edit this
SKILL.md to record a lesson.
- At the start of a session, read
corpus/LESSONS.mdif it exists. Treat each entry as an additional rule for this user, on equal footing with this skill's hard rules. - After a correction that generalises, append one dated line: the mistake, and the rule to apply next time. Route it first — a rule that would still hold if the corpus were about someone else belongs to the method, not this file. Either way the rule lives in a file: a rule nobody can diff is a rule nobody can review, port, or undo.
- A lesson leaves this file only on the user's explicit say-so, entry by entry, by the two
exits its header states. A struck entry —
~~<the entry>~~ retired YYYY-MM-DD: <one clause of why>— is never applied again. Delete an absorbed one only once nothing local remains in it, trimming it to that residue if any does.
Where this sits
The kit has two lanes. bootstrap → interview → compact builds the corpus. apply →
render → prep spends it, and hands back to interview at the end. This skill is the entry
point to the second lane.
The trigger is "I found a job" — not "write me a résumé", which is render on its own.
Hard rules
Capture the posting before it rots, in the employer's own words. [CAPTURE-POSTING]
Postings are pulled, edited and 404'd within weeks, and prep needs the employer's own words
months later to map a story bank to their criteria. jd.md holds the text verbatim, with
the source URL, the capture date and the capture method at the top. Summarise in fit.md, never
into jd.md: a paraphrase silently becomes the thing you prepare against. Verbatim means what
a reader of the rendered page sees, and it is checked, not assumed — diff what you wrote against
what the browser returned before committing. Stage 1 says how.
_inbox/ here means what corpus/_inbox/ means: unvetted, and never rendered from and
never cited as fact. [INBOX-NOT-EVIDENCE] Folder location is a truth claim — the same rule
the interview skill applies to raw material applies here, and it bites harder, because
inbound application material is fluent and confident and written by someone with an
incentive. A recruiter's description of the team's scope, the role's remit, or how the last
person did is a claim by a stranger selling a job. It can shape what you ask and what you
prepare for. It can never become a fact in a letter or an answer. If something in there is a
fact about the user, it earns its way into the corpus through interview, like everything
else.
Never source a claim about the candidate from applications/. [NOT-FROM-APPLICATIONS]
render reads the folder rather than asking the user to paste it again; the bar is on claims
about the user, not on the folder: jd.md is what it tailors to and fit.md is most of the
selection work, but anything here that reads like a claim about the user is already a rendering
(another application's résumé, this one's earlier draft, a line fit.md quoted). Follow the
pointer back to the corpus story and render the claim from there; render's [CLAIM-SOURCE]
states the full rule.
No individual's name in a filename or a folder name. [NO-NAMES-IN-FILENAMES] Roles in
filenames, names in the body if the user wants them. Filenames get screenshotted, screen-shared
and tab-completed in front of other people — including, eventually, in front of someone from
that company.
State is data; prose is for the reader. [STATE-IS-DATA] Anything deriving a thread's
state — a status check, this skill on re-entry — reads events: in application.md's
frontmatter and never the log body. Parsing prose fails in the unsafe direction: nothing can
tell this thread has no events from this thread has events I couldn't read, so one
malformed line makes a sent application look like it is still being written, and every check
gated on having reached sent goes quiet at the same moment. No regex fixes that, because with
prose as the surface the ambiguity is real. So: the frontmatter is authoritative for tooling,
the body for why. This is not the second copy [NO-ROLLUP] forbids — it is the only
machine-readable copy, and nothing parses the body.
The grammar is closed on purpose: <YYYY-MM-DD> <event>, one plain string per line, never a
mapping — narrow enough to read with one anchored expression, so nobody has to guess at it and
no YAML parser is needed. Comments are legal, whole-line and trailing: a user annotating why a
date is an estimate or what a pin covers must not be committing a syntax error, or the
annotation moves to some other file, away from the value it explains.
The folder is the memory; the log is dated and append-only. [LOG-APPEND-ONLY] Don't
rewrite history in application.md when a stage changes — add a line. What you believed on the
12th matters when you're working out on the 30th why nobody replied. Append-only forbids
editing what is already there; it does not license paragraphs. One dated line per event, and
don't log history to prevent an error the current state already prevents: a corrected fact
needs no note of what it used to be, because the corrected file is the enforcement, and a
recurrence shows up as a visible contradiction that costs one question to settle. A claim
deliberately left out is the exception that isn't one — that is a live constraint rather than
history, and it belongs beside the fact it constrains under render's [OBEY-DECISIONS].
Sibling conventions in this kit prune dead material on every revision; this one never does.
An application log is potentially evidence of what a user decided and why, so it compresses and
folds, and it does not delete.
The state is at the top; the chronology is below it. [STATE-FIRST] A reader must never
have to reconstruct where does this stand by working forward through a log. events: is at
the top of the file and ends in the current stage, so the state is already first — and no
other surface restates it: not the heading, not the paragraph beneath it, not a badge or a
date beside either. The heading tempts most, because it is the most visible line in the file,
but a stage in it is a rollup however much it reads as a courtesy ([NO-ROLLUP]), and it goes
stale the next time the thread moves. What the paragraph beneath the heading carries instead is
the part that is genuinely not derivable: what the thread is waiting on, and whose move it is
next.
Entries that no longer bear on the next decision move into a collapsed <details> block, which
folds on GitHub and stops dead material from reading as live.
Store inputs and events; never store a rollup. [NO-ROLLUP] The test is whether it can be
recomputed from what's already on disk. An open-application count, a "3 live, 1 stalled" summary
line, a status: field beside a log that already ends in the current stage — all recomputable,
so all of them rot silently and then lie. Read the folders and compute those each time.
The same goes for folders: applications/ stays flat, because a sent/ or closed/ subfolder
is a second copy of the stage events: holds and goes stale the first time a thread isn't
moved, and moving a thread breaks the repo paths pointing into it, which in a submitted
artifact's sources: can never be repaired ([PIN-THE-INPUTS]).
So application.md carries no status: field: its events: list is the status — the
stage being the furthest pipeline event reached, since inbound and routed land after
interviewed all the time and reading the last line written would pull a thread backwards —
and a field beside it is a second copy on its own schedule. And application-level state
lives in application.md's frontmatter, artifact-level state in each artifact's own — no
separate manifest file, because a file whose only job is to repeat another file's state goes
stale without anything noticing.
Pin what cannot be reconstructed later, at the moment it is true. [PIN-THE-INPUTS] The
other half of [NO-ROLLUP]'s split, and the part that gets skipped: the corpus commit a
render drew on, the hash of what was actually sent, the URL a posting was captured from. Lose
one and it is gone — the posting 404s, the corpus moves on, and nothing on disk remembers. A
pin is not a rollup; it records an input.
Keep this folder in the private corpus repo and nowhere else. [FOLDER-IS-SENSITIVE] It is
the most sensitive thing in the repo — other people's real names, private correspondence, and
sometimes an employer's confidential material. Never paste its contents anywhere the user
didn't ask for, and don't commit an employer's take-home brief to anything public.
_inbox/ is git-ignored by default — bootstrap writes that rule, and it is the reason
inbound can be filed here at all without thinking about it each time. For an employer's
confidential material, prefer a reference over a copy: the link, or the path to where it
already lives, with the date, in application.md. That material is not the user's to store.
If a local copy is genuinely needed to work on it, say plainly that it's staying outside the
repo, and log what it is and when it gets deleted. A brief committed once is in history in
every clone, and deleting the file later doesn't take it back — see PRIVACY.md in the kit.
Surface, don't decide. [SURFACE-DONT-DECIDE] Whether to apply with a named gap, whether a
requirement is boilerplate, whether a stalled thread is dead — all the user's call. Give them
the read and the reason, not the verdict.
Not every doubt is a blocker. [NOT-EVERY-DOUBT-IS-A-BLOCKER] Most uncertainty is not a
blocker. The test is whether being wrong would be expensive or hard to undo — if it would not,
say it once, in a clause, and carry on. A one-line heads-up is the whole deliverable, not a
decision record, not a reconciliation of two forms that disagree, not a checkbox that outlives
the question it was asking. Each escalation reads as diligence on the day it is written, and
the cost lands on every later reader: a folder that argues with itself, and a house style the
next session copies. Three things still earn a gate: editing a frozen artifact, putting an
unsourced claim in front of an employer, and anything the user has said is theirs to decide.
This is the narrower rule underneath [SURFACE-DONT-DECIDE] — that one stops a session taking
the user's decision, this one stops it reporting the same doubt in four places.
One of render's rules binds this skill hardest, because this skill owns the folder the copies
land in:
- A constraint has one home. (
[CONSTRAINT-HAS-ONE-HOME]) A limit on a claim lives in the corpus file that owns the claim, and an application thread never repeats it. Nothing keeps a copy true: correct the corpus later and the copy goes on stating the old position with full confidence. Grep the corpus before writing a constraint into an application thread.fit.mdis the exception, because it names the file each ceiling came from and is regenerated rather than maintained. Assessment may cite a constraint; a log of what happened may not.
Stages
Re-entrant by design. Run it again on an existing folder and it reads the current state, files
whatever is new, and tells you where the thread stands. Don't recreate what's there. A thread
whose application.md has a log and no events: block predates the frontmatter: offer to
migrate it, and follow MIGRATING.md — assisted, never automatic.
1. Open. Get the posting. If it's a URL, render it in a browser; if it's pasted text, take it
as given; if it's a screenshot, transcribe it. Derive company and role from the posting, not
from the user's shorthand — <company>-<role> in kebab case, short enough to tab-complete.
Write jd.md and start application.md.
Capturing from a URL, because the obvious tools fail quietly:
- Never a tool that answers a prompt about the page. A fetch tool that runs the page through
a model (Claude Code's
WebFetchis one) returns a paraphrase however the prompt is worded, and "verbatim, do not summarise" gets back a tidy summary with headings the employer never wrote. - Render the page and take the description element's
innerText, with whatever browser automation is to hand. That is what a human reads, with nothing summarised or invented, and boards that render on the client need a browser anyway. - Take
innerTextwhole. A hand-written DOM walker that keeps list structure drops what it doesn't expect: nested sections collapse, paragraph bodies vanish. Restore bullets afterwards if you want them. - Not regex over raw HTML. The end of the description gets guessed rather than found, and form markup leaks inside the markers.
- Diff before committing. Word level is enough: split both texts to one word per line, drop
blank lines,
diff. An empty diff is what makes "verbatim" a claim a later reader can check. - Record the method in
capture_method:, and any method refused with its reason, so the next session does not retry it.
2. Fit. Read the corpus against the JD before anything gets written. This is the step that earns the skill; see below.
3. Render. Hand off: "Run /career-corpus:render for this application." Don't write the
résumé or the letter here — render carries the faithful-rendering rules and this skill
doesn't repeat them.
4. Sent. Log the date and what actually went out, including anything the form asked for
that the folder doesn't hold (a portfolio link, a salary expectation, a "why us" box typed
into a text field). Applications get answered weeks later and nobody remembers what they
claimed in the box. Record the files themselves in application.md's sent: block, which is
a separate question from the prose and is asked, never guessed — [SENT-NAMES-WHAT-WENT]. This
is also where a generated artifact enters git: git add -f what actually went out, because the
freeze is the moment it stops being rebuildable — [PIN-NOT-ARCHIVE]. Read
SENT.md before writing the sent event — it carries those two rules and
[PIN-NOT-SELF], which bind only here — and again whenever a check reports on a sent: block,
a lifecycle: value or a pin.
5. Inbound. Everything that arrives goes in _inbox/ with a date, and the log gets a line.
Recruiter mail, rejections, scheduling, the take-home brief, the "we've moved you to the next
round" note.
6. Prep. When a round is booked: "Run /career-corpus:prep — the JD and the recruiter's
note are already in the folder." prep reads them from here rather than asking again.
7. Close. Record the outcome and the date. Then the part people skip: a rejection with a
reason in it is corpus material. So is anything the loop exposed. Route it to
/career-corpus:interview and say so explicitly — this is the highest-signal queue the corpus
ever gets, and it evaporates within a week.
Asked "what's live?" — run the kit's checker from the corpus repo root rather than hand-rolling the computation:
python3 "${CLAUDE_PLUGIN_ROOT}/tools/application_status.py"It reads the events: block of each applications/*/application.md and reports stage, age and
what has gone quiet — computed, never stored. Its NEEDS ATTENTION block is conformance rather
than reporting: every line in it is a stated rule being broken. A thread with a log and no
events: is reported as unmigrated, never as a thread with no events. Read its output back to
the user in their terms and add the next action per thread, which the tool deliberately refuses
to compute — that one is a judgement, and [SURFACE-DONT-DECIDE] says whose.
The fit check — fit.md
Read the JD's real requirements (not its boilerplate) against the corpus, and give each one an evidence state, which is exactly one of three:
backed— a story file is evidence for it. Name the file. A requirement with a named file behind it needs no further work.thin— there's something adjacent, but it would fold under a second question.no-corpus-evidence— nothing in the corpus speaks to it.
Call the third one no-corpus-evidence and never missing, because those are different
claims and only one of them is yours to make. A requirement the corpus can't back may be one
the user never did, or one they did and never recorded — absent versus unwritten — and the
two need opposite responses: don't apply, versus book an interview session. This file records
what it can see and asks; picking between them is a call about someone's career, which the
surface-don't-decide rule [SURFACE-DONT-DECIDE] says is theirs. Say which you suspect and
why, as a question.
The third state is the point, and "don't apply yet" is a valid result. A requirement with
nothing behind it doesn't get solved by rendering harder at it; it gets solved by an
interview session, or by deciding to apply anyway with the gap named and a plan for the
question. Both are fine. Papering over it with the nearest adjacent story is not — that story
gets one follow-up question in the room and collapses, and everything either side of it gets
discounted with it.
Say which requirements you judged to be real and which you discarded as boilerplate, so the user can disagree. Every posting asks for ten years of a five-year-old technology.
A judgement in here is only as good as what you computed it from. When a line of fit.md
rests on a rendered artifact rather than on something the user said — a résumé bullet, an older
cover letter — it inherits that artifact's errors, and a gap that is really a stale bullet reads
exactly like a gap in the corpus. Confirm the input before the conclusion hardens into a
section, because once it is written down the next reader treats it as a finding. Say which
inputs a judgement rests on where it isn't obvious.
Where the corpus is thin, the useful output is a pointer, not a verdict: "nothing backs
'led a platform migration' — the closest is corpus/<company>/<story>.md, and an interview
session on <arc> would probably produce it."
The event vocabulary
A thread is a dated list of events, named from a fixed set so it can be read at a glance six
weeks later. Every event is written in two places at once: a line in events: for anything
that reads state, and a line in the log for the reader who wants to know why — [STATE-IS-DATA].
Nine events:
| Event | What it marks |
opened | The posting was captured and the folder created. |
fit-checked | fit.md was written or revised, and what the user decided off the back of it. |
rendered | An artifact was produced or re-rendered. |
sent | The application went out. Record what actually went out, including the form-only fields this folder doesn't hold. |
inbound | Something arrived and was filed in _inbox/. Name the file. |
scheduled | A round was booked. |
interviewed | A round happened. |
outcome | Offer, rejection, or the user withdrawing. Say which, and quote any reason given. |
routed | Something this thread exposed went back to the corpus queue. |
Something that fits none of them is usually two events. A fixed vocabulary is also what lets a
reader — or a check — see at a glance that a thread was never sent, or was interviewed
without ever being routed.
What "good" looks like
Six weeks after applying, the user opens one folder and has the whole thread: what the posting actually said, what they claimed, what they were asked, who they spoke to and when, and what they still can't back. Nothing in it has been quietly upgraded from "a recruiter said" to "true". And when the loop ends — either way — what it exposed goes back into the corpus instead of into the bin.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
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.

