agentleFS
CodesWhatCodesWhat/careerrat/.agents/skills/tailor-application/SKILL.md

tailor-application

Skill4 starsChanged 9 days agoMITView on GitHub

Generate finished, honest role-specific resumes, cover letters, short answers, and non-message outreach artifacts from a saved JD, source resume facts, candidate evidence bank, writing style, and form defaults after the job passes the CareerRat gate. Reject unresolved placeholders. Use email-comms for email replies, follow-ups, thank-yous, scheduling, negotiation, and recruiter-message threads.

2 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

48 rules. About 0 are common, 21 are distinctive, and 27 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈21

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 27

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read the current session context for the evaluate-job output block.

    line 12
  2. Distinctive:

    If the gate output is present, echo the full block:

    line 15
  3. Very specific:

    If the gate output is missing, run evaluate-job now before proceeding.

    line 25
  4. Very specific:

    If FIT is stretch (score < candidate/targeting.yml#fit_bands.med_min, default 65), warn: "FIT is stretch — tailoring will require stronger …

    line 26
  5. Very specific:

    If GATE: CUT is present, halt and explain.

    line 29
  6. Distinctive:

    Read in this order:

    line 34
  7. Distinctive:

    When present, extract and note:

    line 63
  8. Very specific:

    Check whether workspace/writing-samples/ contains any files newer than candidate/writing-style.md (compare modification timestamps).

    line 77
  9. Very specific:

    If new samples are present: run npm run calibrate:style.

    line 80
  10. Very specific:

    If no new samples: read candidate/writing-style.md as-is.

    line 82
  11. Distinctive:

    Prefer a file from the same role-family (same family key in filename or metadata).

    line 90
  12. Very specific:

    If no prior tailored file exists, start from candidate/SOURCE_RESUME.md.

    line 92
  13. Distinctive:

    Use the found file as a structural template only — section order, heading names, approximate length.

    line 94
  14. Very specific:

    Evidence: every non-obvious claim must map to a claims[] entry in candidate/evidence.yml.

    line 106
  15. Very specific:

    Honesty: never claim any tool listed under honesty.yml#tools.do_not_claim.

    line 109
  16. Very specific:

    Use only tools listed under honesty.yml#tools.confirmed unless the user explicitly confirms a new one mid-session (write-back rule below).

    line 110
  17. Very specific:

    Compensation: never include the candidate's current compensation anywhere.

    line 120
  18. Very specific:

    Use form-defaults.yml#expected_base only when a comp figure is explicitly required in a form field — not in resume prose.

    line 121
  19. Distinctive:

    Names: all names must be real — actual candidate name, actual company names.

    line 123
  20. Distinctive:

    No placeholders in artifact prose.

    line 124
  21. Distinctive:

    Only omit the cover letter when the application has no way to accept one (no field and no email/attachment channel).

    line 138
  22. Distinctive:

    Before drafting, fix the cover letter's angle across four dimensions.

    line 143
  23. Very specific:

    Fetch the form: Run careerrat questions workspace/jobs/<saved-job>.md — deterministic, zero AI cost.

    line 167
  24. Very specific:

    Use apply-job's screening-answer posture: form-defaults.yml#screening_answers first, then profile / honesty / evidence and the tailored …

    line 176
  25. Very specific:

    Persist durable answers: When the user resolves a NEEDS YOU or confirms an answer to a recurring disclosure-style question, write it to …

    line 187
  26. Very specific:

    All cover-letter and short-answer text follows the same constraints as the resume: no unresolved placeholders, no forbidden wording, no …

    line 193
  27. Distinctive:

    Do not mark any artifact as upload-ready or build-ready until this exits 0.

    line 216
  28. Very specific:

    Treat these as invalid placeholders: [Company], [Role], {candidate}, <insert metric>, TODO, TBD, lorem ipsum, NEEDS YOU, and any similar …

    line 227
  29. Very specific:

    Real names, never placeholders — go generic when unknown: Always use the candidate's real name …

    line 258
  30. Very specific:

    Read candidate/profile.yml#candidate.toolchain (set at onboarding via ingest-profile).

    line 269
  31. Distinctive:

    After the PDF generates (if soffice is available), eyeball it: confirm 1–2 pages, correct font, all black, 0 non-ASCII characters, hyphen …

    line 289
  32. Very specific:

    If you do fall back to this, eyeball the .pdf before marking it the upload artifact (1–2 pages, correct font, all black, ASCII, hyphen …

    line 302
  33. Very specific:

    No scripted Word-automation path (AppleScript/COM) ships.

    line 306
  34. Distinctive:

    Never force a build dependency not detected at onboarding.

    line 314
  35. Distinctive:

    Before marking any artifact complete, confirm:

    line 319
  36. Very specific:

    No occurrence of the candidate's current compensation (profile.yml# compensation.current_base or any dollar figure matching it) appears …

    line 321
  37. Distinctive:

    If a violation is found, remove it and re-run STEP 7.

    line 327
  38. Distinctive:

    If the user stated any new honesty boundary during this session (e.g.

    line 331
  39. Distinctive:

    Preferred timing: run this before STEP 5 drafting so rejection patterns can inform keyword and narrative choices.

    line 346
  40. Distinctive:

    If the role-family has prior tracked applications, run:

    line 350
  41. Distinctive:

    After artifacts pass placeholder lint (STEP 7) and ATS-safe validation, render print-quality output on request or when the user needs a …

    line 365
  42. Very specific:

    Use --out <path> to override the output location, --title "..." to set the document title (defaults to the file's stem).

    line 389
  43. Distinctive:

    Export a convenience copy to the job's Documents folder: After every PDF renders (resume and cover letter), copy it there unconditionally, …

    line 392
  44. Very specific:

    Use the real company name for the folder and filename (no brackets — truly unknown company → unknown).

    line 401
  45. Very specific:

    If the user intends to apply: hand off to apply-job.

    line 418
  46. Distinctive:

    If the user only wanted the artifacts: confirm files are ready and list their paths.

    line 421
  47. Very specific:

    Do not submit from within this skill.

    line 422
  48. Distinctive:

    After any write at this step, run the verify+snapshot gate again:

    line 448

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

tailor-application

Runs under AGENTS.md. These contracts bind without being restated here: Privacy Invariant (current_base never outbound), Honesty Firewall, Placeholder/Bracket Ban, Gate Write-back, Domain-Neutral Rule, Browser Automation Contract, Activity Pulse logging, Tracker verify+snapshot, and Sent-Clears-Draft. Inline reminders at point-of-use are intentional; standalone restatements point back to the relevant AGENTS.md section. Bare candidate/, workspace/, config/, and .internal/ paths below are symbolic; resolve them per AGENTS.md's Path Resolution rule.

STEP 0 — Prerequisites: gate check

Read the current session context for the evaluate-job output block. Confirm it contains GATE: KEEP or GATE: REVIEW for this role.

  • If the gate output is present, echo the full block:

    GATE: KEEP|REVIEW - <reason>
    FIT: <band> <score> - <why>
    COMP: <verdict> - <reason>
    COMP ANCHOR: <expected salary to state> - <rationale>
    ACTION: <action>
  • If the gate output is missing, run evaluate-job now before proceeding.
  • If FIT is stretch (score < candidate/targeting.yml#fit_bands.med_min, default 65), warn: "FIT is stretch — tailoring will require stronger narrative framing. Proceed?" Wait for explicit confirmation before continuing.
  • If GATE: CUT is present, halt and explain; do not proceed without explicit user override.

STEP 1 — Load gate files

Read in this order:

  1. candidate/honesty.yml — note tools.confirmed, tools.do_not_claim, education.add_education_section, claims.do_not_fabricate
  2. candidate/evidence.yml — note claims[], allowed_wording[], forbidden_wording[]
  3. candidate/targeting.yml — note role_buckets, degree_policy, fit_bands
  4. candidate/form-defaults.yml: note expected_base, work_authorization
  5. candidate/profile.yml — note candidate.toolchain, candidate.domain, compensation.expected_base (outbound-safe); do not read or echo compensation.current_base — it is private and must not appear in any artifact

Classify the role-family for this job: match the JD title and responsibilities against targeting.yml#role_buckets patterns, using the same logic as evaluate-job. If targeting.yml#role_families is present, use those patterns; otherwise derive families from role_buckets names; fall back to the outcome- analysis defaults only when both are absent. Record the resolved family (e.g. fde, solutions, driver, dispatcher, finance) — it drives file paths in later steps.

STEP 2 — Load learning context

Run:

careerrat learnings read "<role>"

The helper classifies the role-family from targeting.yml and prints the learning file to stdout. If no file exists for this family it prints a skip note to stderr and exits 0 — a missing file is normal, never an error.

When present, extract and note:

  • Positioning that has landed well for this track
  • Bullet phrasings that resonate with reviewers
  • Keywords that appear to match
  • Objections or gaps previously surfaced
  • Comp signals and recurring reject reasons

These inform STEP 5 framing — every application to this track should be sharper than the last. Learning files describe real outcomes; they do not authorize fabricating new claims.

STEP 3 — Calibrate writing style

Check whether workspace/writing-samples/ contains any files newer than candidate/writing-style.md (compare modification timestamps).

  • If new samples are present: run npm run calibrate:style; wait for it to complete; then read the updated candidate/writing-style.md.
  • If no new samples: read candidate/writing-style.md as-is.

Note tone, voice, sentence rhythm, and any explicit prohibitions before drafting.

STEP 4 — Seed from closest existing tailored file

Scan workspace/tailored/ for the closest existing tailored resume:

  1. Prefer a file from the same role-family (same family key in filename or metadata).
  2. Fall back to the same company if present.
  3. If no prior tailored file exists, start from candidate/SOURCE_RESUME.md.

Use the found file as a structural template only — section order, heading names, approximate length. Do not copy its content verbatim; every claim must be re-evaluated against the current JD and evidence.

STEP 5 — Tailor resume

Draft the tailored resume into workspace/tailored/<Company> — <Role>.md.

Rules (all non-negotiable):

  • Keywords: mirror the JD's language and role-level signals. Apply keyword and positioning lessons from the learning file (STEP 2).
  • Evidence: every non-obvious claim must map to a claims[] entry in candidate/evidence.yml. If a claim has no evidence entry, remove it or ask the user to provide evidence before including it.
  • Honesty: never claim any tool listed under honesty.yml#tools.do_not_claim. Use only tools listed under honesty.yml#tools.confirmed unless the user explicitly confirms a new one mid-session (write-back rule below).
  • Education: include an Education section only if honesty.yml#education.add_education_section is true and the claimed degree matches claims[]. Never fabricate or upgrade a credential.
  • Wording: apply evidence.yml#allowed_wording[] and refuse any term in forbidden_wording[].
  • Obfuscation: replace internal codenames with the allowed public wording per allowed_wording[].
  • Length: target 1–2 pages. Cut low-signal bullets before adding new ones.
  • Compensation: never include the candidate's current compensation anywhere. Use form-defaults.yml#expected_base only when a comp figure is explicitly required in a form field — not in resume prose.
  • Names: all names must be real — actual candidate name, actual company names. No placeholders in artifact prose.

STEP 6 — Cover letter and short answers

Always produce a cover letter whenever the application accepts one. It is a second keyword-matching surface for the ATS and a free chance to reinforce fit, so it is the default, not an optional extra. Produce one when any of the following is true:

  • The application form has a cover-letter field — required OR optional (an optional field still means it accepts one; fill it)
  • The application is sent by email or as an attachment, so a cover letter can ride along
  • The JD explicitly requests one
  • The FIT band is stretch (< 65) and narrative framing would materially help

Only omit the cover letter when the application has no way to accept one (no field and no email/attachment channel). Do not ask — decide and act.

Angle — automatic by default; the user can steer

Before drafting, fix the cover letter's angle across four dimensions. Derive each automatically from the material already on hand — never interrogate the user for them. If the user offered an angle, hook, emphasis, or tone in their request, use it to override the matching dimension(s); otherwise infer and proceed.

DimensionAuto-derive fromUser can override with
Why this company/roleJD mission/product, a workspace/research/<slug>.md artifact if present, targeting.yml keep signals"lead with why I want to work there", a stated reason
Their problemJD responsibilities, named challenges, and the role's reason to exist"they're struggling with X", a named pain point
My approach / proofthe evidence.yml claims that best map to their problem — must trace to a real claim; never invent an angle to fit"emphasize my <evidenced> work", a chosen project
Tonewriting-style.md register + the JD/company formality"make it warm", "keep it crisp", a stated voice

Open on the single strongest why+problem pairing as the hook; support it with one or two evidenced proof points; carry the tone throughout. When you present the draft, state the chosen angle in one line so the user can redirect — but never wait for permission to draft. A stronger user-supplied angle always wins over the inferred one; an angle with no backing evidence is an Evidence Gap to surface, not a narrative to fabricate.

Form questions — fetch the real list, answer every one

Short answers start from the actual application-form questions, not guesses inferred from the JD:

  1. Fetch the form. Run careerrat questions workspace/jobs/<saved-job>.md — deterministic, zero AI cost; supports Greenhouse and Ashby postings and writes the normalized list to workspace/jobs/<saved-job>.md.questions.json. For any other ATS, ask the user to paste the form's questions and capture them in the same shape with careerrat questions workspace/jobs/<saved-job>.md --paste. If neither is possible, fall back to questions stated in the JD and say so in the packet summary.
  2. Answer every fetched question in one answers artifact, workspace/tailored/<Company> — <Role> — answers.md: one section per question (verbatim label, required ones marked), the drafted first-person answer beneath. Use apply-job's screening-answer posture: form-defaults.yml#screening_answers first, then profile / honesty / evidence and the tailored artifacts. Entries with type: "file" are attachment slots (resume, cover letter) — list them at the top as attachments; never write prose for them.
  3. Never fabricate. A question whose truthful answer would require guessing a number/date/clearance/tool depth, revealing current compensation, or contradicting honesty.yml gets the literal marker NEEDS YOU: <one-line reason> as its body. The marker is a flag on this one job, not a stop: keep building the rest of the packet and tell the user which questions are waiting. The placeholder lint (STEP 7) still blocks on NEEDS YOU, so the packet cannot be exported or marked upload-ready until the user supplies the answer.
  4. Persist durable answers. When the user resolves a NEEDS YOU or confirms an answer to a recurring disclosure-style question, write it to candidate/form-defaults.yml#screening_answers (normalized question fragment → exact answer) so it is never asked again — and note it in candidate/interview-notes.md when it is a legal/disclosure answer.

All cover-letter and short-answer text follows the same constraints as the resume: no unresolved placeholders, no forbidden wording, no unevidenced claims, no do_not_claim tools, privacy invariant on comp. Apply writing-style.md tone rules.

Outreach and referral notes (non-message, non-email): follow the same artifact rules. For email replies, follow-ups, thank-yous, scheduling, and negotiation threads, hand off to email-comms instead.

STEP 7 — Placeholder lint

Run:

careerrat lint-placeholders workspace/tailored/

Fix every finding before continuing. The command exits 1 on any hit.

The one exception is NEEDS YOU. That marker is a per-job flag, not a stop, so a NEEDS YOU finding does not halt the tracker stamp or the activity log below. Fix every other finding first. The artifact is still never marked upload-ready while the marker remains.

Do not mark any artifact as upload-ready or build-ready until this exits 0.

Then log the tailored artifacts to the Activity Pulse feed (the dashboard's live timeline — see Activity Pulse in AGENTS.md). One event per tailoring run:

careerrat activity append --type tailored --actor agent \
  --title "Tailored application — <Company>" --summary "<what was built, e.g. 'résumé + cover letter'>" \
  --company "<Company>" --role "<Role>" --app-id <application id> --write

Treat these as invalid placeholders: [Company], [Role], {candidate}, <insert metric>, TODO, TBD, lorem ipsum, NEEDS YOU, and any similar template residue. (NEEDS YOU is the STEP 6 unanswered-question marker — resolving it with the user, not deleting it, is the fix.)

Also run careerrat fact-check <draft-path> --company "<Company>" --role "<Role>" on every saved résumé, cover letter, answers and outreach draft. It exits 1 when the draft adds a number, tool, employer or name that is absent from the source résumé and evidence. Fix the draft from evidence, or leave a NEEDS YOU marker; never add the fact to evidence just to pass the check.

Stamp the tracker row — both paths (apply-job and standalone). After lint exits 0, or its only findings are NEEDS YOU markers, write the produced artifact paths back to the application row in a single tracker.json write before proceeding to STEP 8 or STEP 12:

applications[<id>].artifacts.resume      = "workspace/tailored/<Company> — <Role>.md"
applications[<id>].artifacts.coverLetter = "<cover letter path or inline text, if produced>"
applications[<id>].artifacts.answers     = "workspace/tailored/<Company> — <Role> — answers.md" (when form answers were produced)
applications[<id>].artifacts.resumeNote  = "<one-line tailoring approach>"

Then run the AGENTS.md verify+snapshot gate:

careerrat tracker --verify && careerrat tracker

Both must exit 0 before continuing. Do not skip this on the standalone-artifacts path — without it, the dashboard has no durable record that tailored materials exist.

Real names, never placeholders — go generic when unknown. Always use the candidate's real name (candidate/profile.yml#candidate.preferred_name → full_name) on every artifact, and real company/role/contact from the saved JD and tracker.json record. If a detail is genuinely unknown, write it generically — never leave a bracketed token and never block on it. A cover letter with an unknown addressee opens Hello, or Dear Hiring Team, (only name a team if it's actually known), not Dear [Hiring Manager]. An unknown metric is omitted, not bracketed. Brackets in output are a build failure, not a TODO.

STEP 8 — Build (renderer-detected)

Read candidate/profile.yml#candidate.toolchain (set at onboarding via ingest-profile). Branch on its value:

Primary PDF path is STEP 11b (careerrat export … --pdf), which renders through the repo's bundled Playwright Chromium — reliable and zero-setup. The toolchain branches below are the environment fallback and the DOCX path: use them when the bundled export can't run, or to produce a .docx. Note that soffice on a raw .md (path b) does NOT reliably render Markdown — prefer STEP 11b for any PDF you intend to upload.

a. pandoc:

pandoc "workspace/tailored/<Company> — <Role>.md" -o "workspace/tailored/<Company> — <Role>.docx"
soffice --headless --convert-to pdf "workspace/tailored/<Company> — <Role>.docx"

soffice is the optional PDF-conversion companion; if it is not installed, mark the artifact as .docx upload and skip the PDF step.

After the PDF generates (if soffice is available), eyeball it: confirm 1–2 pages, correct font, all black, 0 non-ASCII characters, hyphen bullets. If any check fails, fix the source and rebuild.

b. libreoffice: For PDF, prefer STEP 11b (careerrat export … --pdf) — soffice opens a raw .md as plain text and will not render Markdown structure reliably. Use LibreOffice only as a last-resort fallback when the bundled export can't run:

soffice --headless --convert-to pdf "workspace/tailored/<Company> — <Role>.md"

If you do fall back to this, eyeball the .pdf before marking it the upload artifact (1–2 pages, correct font, all black, ASCII, hyphen bullets).

c. word: No scripted Word-automation path (AppleScript/COM) ships. Prefer the pandoc path (b) to produce the .docx if pandoc is available; otherwise open the .md in the candidate's editor and convert manually, marking the artifact as pending manual build.

d. markdown-only: Skip build entirely. Mark the .md file as the upload artifact.

Never force a build dependency not detected at onboarding. Never install pandoc or soffice on behalf of the user without explicit consent.

STEP 9 — Privacy check

Before marking any artifact complete, confirm:

  1. No occurrence of the candidate's current compensation (profile.yml# compensation.current_base or any dollar figure matching it) appears anywhere in the resume, cover letter, short answers, or outreach artifacts.
  2. Any compensation figure present is sourced from form-defaults.yml#expected_base and appears only in a required form field, not in prose.

If a violation is found, remove it and re-run STEP 7.

STEP 10 — Honesty gate write-back

If the user stated any new honesty boundary during this session (e.g. "never claim Terraform", "remove that certification claim", "add Kubernetes to do-not-claim"):

  • Write-and-report for additions that tighten a boundary (one new tool to do_not_claim, one claim to forbid), applied directly and logged with an Undo: run careerrat gate do-not-claim "<tool>" --write or careerrat gate do-not-fabricate "<claim>" --write, then echo the CLI confirmation.
  • Confirm-first for anything that loosens a boundary (removing a confirmed tool, broad claim rewrites): propose the exact candidate-config change, get a yes, then write through the owning DB-aware command.

The gate must not live only in chat. After writing, re-check the resume for compliance with the new boundary and fix if needed.

STEP 11 — Outcome analysis check (optional, non-blocking)

Preferred timing: run this before STEP 5 drafting so rejection patterns can inform keyword and narrative choices. If the session has already reached this point without the check, run it now as a final review.

If the role-family has prior tracked applications, run:

npm run analyze:outcomes -- --summary

Scan for rejection patterns in this family or fit band. If a known reject signal appears in the current resume framing, flag it and offer to adjust before handing off.

Skip if no prior applications exist (exit 0 or no output). Do not block on this step.

STEP 11b — Export (optional)

After artifacts pass placeholder lint (STEP 7) and ATS-safe validation, render print-quality output on request or when the user needs a file for upload/print:

careerrat export workspace/tailored/<Company> — <Role>.md --pdf --ats   # the copy you upload to an ATS
careerrat export workspace/tailored/<Company> — <Role>.md --pdf          # brand/print copy (Geist)
careerrat export workspace/tailored/<Company> — <Role>.md --pdf --docx

Default the upload/submission PDF to --ats. It renders in a standard, widely-installed font stack (Arial/Helvetica/Courier) with no embedded Geist — ATS résumé parsers extract text from a common system face far more reliably than from an embedded variable brand font. Drop --ats only for a copy meant for human eyes (portfolio, print, direct email to a person) where the brand face is wanted.

--ats also prints an ATS parseability score (0-100) with any fixable issues, such as missing section headings, unreachable contact info, sparse text, or a structural problem like a table or embedded image. It's advisory, not a gate: review it and fix what's cheap to fix, but a lower score never blocks handoff.

PDF needs no setup — it uses the Playwright Chromium bundled with the repo. DOCX auto-detects pandoc, then LibreOffice/soffice, then falls back to a built-in OOXML writer. Zero new dependencies in either case.

Use --out <path> to override the output location, --title "..." to set the document title (defaults to the file's stem).

Export a convenience copy to the job's Documents folder. After every PDF renders (resume and cover letter), copy it there unconditionally, under the job folder (Artifact Contract: organized by company, job, then round):

~/Documents/careerrat/<Company>/job-<application-id>/<Company> - Resume.pdf
~/Documents/careerrat/<Company>/job-<application-id>/<Company> - Cover Letter.pdf   # if produced

Use the real company name for the folder and filename (no brackets — truly unknown company → unknown). If a prior round's file with the same name is at that job root, move it to ~/Documents/careerrat/<Company>/job-<application-id>/archive/ first so the root only shows what's live. workspace/tailored/ remains the source of truth; Documents is a convenience copy for quick access. Plain-text artifacts (short answers, outreach notes) export as .txt to the same job folder.

STEP 12 — Hand off

Confirm final artifact locations:

workspace/tailored/<Company> — <Role>.md
workspace/tailored/<Company> — <Role>.docx   (if built)
workspace/tailored/<Company> — <Role>.pdf    (if built)
  • If the user intends to apply: hand off to apply-job. apply-job will re-verify the gate, fill the form, and handle submission per automation.yml#submit (auto by default, manual to stop for the user).
  • If the user only wanted the artifacts: confirm files are ready and list their paths.
  • Do not submit from within this skill. Submission is owned by apply-job.
  • Learnings write-back is owned by track-outcomes, not this skill. Read it via careerrat learnings read "<role>" (STEP 2); appends are track-outcomes' job. After an outcome is known (rejection, advance, offer), run track-outcomes — it owns appending to candidate/learnings/<role-family>.md. Do not write to that file here.

Clear any satisfied recruiter-materials comm CTA — same write as the artifact stamp (or a dedicated write if the artifact stamp already ran). Before confirming artifacts to the user, scan communications[] for any thread on this role where status: needs-reply and nextAction references providing materials, a resume, or a cover letter. If such a thread exists, include these fields in the SAME tracker.json write:

thread.status        = "waiting"
thread.nextActionDue = null
thread.nextAction    = "Await recruiter response"   # rewrite to reflect what's next
thread.messages[]   += { date: "<today>", kind: "note",
                          body: "Tailored resume + cover letter ready for send — pending email-comms dispatch" }

Writing the app row alone does NOT clear a live comm CTA. Both records must land in the same write. A ghost comm CTA is a broken contract (see AGENTS.md "Completed-action clears its CTA (hard)").

After any write at this step, run the verify+snapshot gate again:

careerrat tracker --verify && careerrat tracker

Both must exit 0 before reporting completion to the user.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.