Skip to content

Loops · career

apply

Take one job posting and one resume to an application ready to send — an honest fit check, a tailored resume, a cover letter and the answers to the application form — with the candidate deciding whether to apply before any writing, and confirming every claim is true before anything is sent.

Use it when
Use when the user wants to apply for a job, says "help me apply for this", or wants a resume and cover letter prepared for one posting.
Comes with
The career pack
Where you decide
  • Fit (G6): you decide
  • Confirm (G6.1): you decide
Size
5 stages · 2 gates · up to 3 revision rounds
npx skilldrop-cli install --loop apply

Installs the loop as an invokable skill, plus every skill its stages run.

Other ways to install

Every loop in its pack, with their skills:

npx skilldrop-cli install --loop --pack career

The loop alone, without its stage skills (each stage falls back to an inline version):

npx skilldrop-cli install --loop apply --no-skills

In Claude Code, the career plugin includes it:

/plugin install career@skilldrop

The loop

%%{init: {'theme':'base','themeVariables':{'fontFamily':'Segoe UI, Helvetica, Arial','fontSize':'15px','lineColor':'#9AA5B1'},'flowchart':{'curve':'basis','rankSpacing':70,'nodeSpacing':50,'padding':16}}}%%
flowchart LR
    classDef gen    fill:#E8F0FE,stroke:#4C7DF0,stroke-width:1.5px,color:#1A3A8F;
    classDef review fill:#FDEAEA,stroke:#E05B5B,stroke-width:1.5px,color:#8A1F1F;
    classDef gate   fill:#FBE3A2,stroke:#D9971E,stroke-width:2px,color:#6B4500,font-weight:bold;
    classDef ship   fill:#E6F7EC,stroke:#34A853,stroke-width:2px,color:#0F6B33,font-weight:bold;

    fit["fit<br/><small>job-fit-analysis</small>"]:::gate
    tailor["tailor<br/><small>resume-tailor</small>"]:::gen
    letter["letter<br/><small>cover-letter</small>"]:::gen
    form["form<br/><small>application-form-answers</small>"]:::gen
    confirm["confirm<br/><small>output-hygiene</small>"]:::review
    G6{"G6 · human"}:::gate
    G6_1{"G6.1 · human"}:::gate
    DONE(["complete"]):::ship

    fit --> G6
    G6 == "PROCEED" ==> tailor
    tailor --> letter
    letter --> form
    form --> confirm
    confirm --> G6_1
    G6_1 == "READY" ==> DONE

    G6_1 -- "NOT READY (max 3)" --> tailor

Stages

#StageWhat it doesSkillsGate
1fit
gate
Say honestly where the candidate stands against the posting, then let them decide whether this application is worth writing.job-fit-analysisG6 — you decide
PROCEED · PROCEED WITH CONDITIONS · RECONSIDER · BLOCKED
2tailor
generate
Rewrite the resume for this posting from what the candidate has done and nothing else.resume-tailor—
3letter
generate
Write the letter from the tailored resume, the posting and the candidate's own reason for wanting the job.cover-letter—
4form
generate
Draft the application form's answers from the tailored resume, and hand back the declarations that are the candidate's alone.application-form-answers—
5confirm
verify
Strip what the machine left behind, then have the candidate confirm that every line in the documents is true and theirs, and that anything added from outside the resume is right.output-hygieneG6.1 — you decide
READY · NOT READY · BLOCKED

One application, start to send, for any job. It opens with a gate because the cheapest application is the one you decide not to write, and it closes with one because the candidate signs these documents and answers for them at interview. Both gates are human: an agent can say what the resume shows, but only the candidate knows what is true and what they want.

How to run this loop

  1. Check the fit and stop. Run job-fit-analysis on the posting, the resume and any other material of the candidate's: a LinkedIn summary, a portfolio, a project. Put its verdict, what could get the application rejected and its questions to the candidate, including whether anything outside the resume covers a gap, then wait at G6.
    • PROCEED: they are applying. Go on.
    • PROCEED WITH CONDITIONS: they are applying and have answered the questions. Save their answers to notes.md; from here on those answers are source material alongside the resume.
    • RECONSIDER: they are not applying. The loop ends here, and that is a good outcome.
  2. Tailor the resume. Run resume-tailor with the resume, the posting and notes.md if it exists. It works in the resume's own format, on a copy. Carry forward its three lists: "Not claimed", "Cut" and "Added from outside the resume".
  3. Write the letter. Run cover-letter with the tailored resume, the posting, notes.md and the candidate's reason for wanting the job if they gave one. Skip this stage when the posting says not to send a letter.
  4. Answer the form. When the application has a form with questions beyond uploading the documents, run application-form-answers with those questions and the tailored resume. Skip this stage when there is no form.
  5. Clean the documents. Run output-hygiene on the resume and the letter.
  6. Confirm at G6.1. Show the candidate the documents with four short lists: what the posting asks for that the documents do not claim; every fact added from outside the resume and where it came from; every line cut from the resume; and the form questions that are theirs alone to answer. Ask them to confirm every line is true. NOT READY returns to tailor with their corrections added to notes.md. The candidate sends the application; the loop never does.

Verdicts

Defined in contracts/terminals.json. G6 emits PROCEED, PROCEED WITH CONDITIONS, RECONSIDER or BLOCKED. G6.1 emits READY, NOT READY or BLOCKED. RECONSIDER leaves the loop: the candidate's time goes to a better posting.

Non-interactive runs

With no person present, neither gate can be satisfied. Run fit, deliver the analysis and emit BLOCKED: need the candidate's decision to apply. Do not decide for them, and do not produce documents carrying their name that they have not confirmed.

When a stage's skill is not installed

Name the missing skill and skilldrop as its source, do the minimal inline version of that stage under the same rule (nothing the candidate didn't supply), and record that it ran degraded. Never skip G6.1.

Run log (opt-in)

Only when the environment variable SKILLDROP_LOOP_LOG is set to a file path: after each gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is sent anywhere. When the variable isn't set, or you can't read it, skip this section.

printf '%s\n' '{"ts":"2026-10-05T14:03:00Z","loop":"apply","stage":"fit","gate":"G6","verdict":"PROCEED","round":1}' >> "$SKILLDROP_LOOP_LOG"

Fields: ts (UTC), loop, stage, gate (null for a stage without one), verdict (the gate's exact word), and round (1 for the first attempt, counting returns under the cap). The log holds verdicts only: never the posting, the resume or the candidate's name.

Quality bar

Anti-patterns to avoid

Source

LOOP.md · loop.json on GitHub · Why loops