.agents/skills/role-intake/SKILL.md
Turn a job posting URL or pasted JD into a structured role.md file inside applications/<app_id>/. Extracts company, role, JD text, inferred lane (founding/AI eng/FDE/full-stack/local), required vs nice-to-have skills, fit notes against Mason's profile, and an honest truthfulness-gap list. Use whenever Mason shares a job link, pastes a JD, or asks "is this worth applying to?".
npx skillsauth add MLGalusha/job-tracker role-intakeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill converts a raw job posting (URL, pasted JD, or both) into the structured applications/<app_id>/role.md file that every downstream drafting skill reads. It's also the natural entry point for "is this worth applying to?" triage.
job-sourcer skill hands off a discovered candidate rolefit_summary backIf Mason just mentions a company without a specific posting ("I should look at Cognition"), that's not role-intake — that's either job-sourcer or a manual conversation. Ask.
Before this skill runs, an application must exist in the tracker. If one doesn't:
application-logger to create it via pnpm log application_created. That will produce an app_id and an applications/<app_id>/ directory.app_id.Never write role.md to a directory that doesn't already exist. Never invent an app_id.
| Input | How to get it |
|---|---|
| app_id | From application-logger (just created) or resolved via fuzzy match against data/applications.json |
| Company name | From the URL's domain, from Mason, or from the JD text |
| Role title | From the JD or from Mason |
| JD text | If URL provided: delegate to a subagent with WebFetch to pull and clean it (keeps main context lean). If pasted: use as-is. |
| Canonical URL | The company's own careers page if possible, not LinkedIn/Indeed |
Canonicalization rule: if the URL is on LinkedIn, Indeed, Wellfound, or any aggregator, have the subagent try to find the same posting on the company's own careers page (Ashby, Greenhouse, Lever, or their own site) and use that as the canonical URL. Fall back to the aggregator only if the company listing isn't findable. Mason wants to apply through company sites.
Delegate to an Explore subagent with a tight prompt:
"Fetch this job posting URL and return: (1) the canonical company careers-page URL for this same role if you can find it (not the aggregator link), (2) the full JD text cleaned of navigation/chrome/boilerplate, (3) the company name, (4) the role title, (5) location/remote policy, (6) stated salary band if any. Report in under 400 words. URL: <url>"
Reading JD URLs in the main context wastes tokens. Always delegate.
Read in this order (use Read tool, these are small files):
profile/skills.md — for Tier A (claimable) and Tier B (familiar) listsprofile/preferences.md — for target lanes, skip lanes, location/remote rules, credentials notesprofile/projects/*.md — only if the JD mentions something specific where you need evidence (e.g. "AI pipeline experience" → read voices-that-remain.md)profile/comp.md — for the comp-band fit checkDo not read every profile file every time. Read targeted.
From the JD, pull two lists:
Be literal. If the JD says "3+ years of React," that's a required 3-year count — Mason does not have 3 years of professional React, period. Do not soften that into "React experience."
Go item by item through Required and produce one of four verdicts per item:
| Verdict | Meaning |
|---|---|
| ✅ Claimable | Tier A in skills.md or backed by a projects/*.md file. Safe to put on the resume. |
| 🟡 Partial | Tier B or analogous experience (e.g. JD wants "Postgres" → Mason has Postgres in VTR, fine; JD wants "8 years Postgres" → Mason does not). Note the gap. |
| 🔴 Gap | Mason cannot claim this at all. Must be honest about it on the resume (omit) and flag it for interview-prep. |
| ⚠️ Hard filter | A disqualifier like "PhD required" or "5+ years at a FAANG" — these don't become gaps, they become don't-apply decisions. |
If there are ≥1 hard filters, the recommended_action is "skip — hard filter" and the rest of the analysis is still written for the record but no drafting skills should run.
Lane — which of Mason's target lanes does this role fit?
founding — founding engineer at pre-seed/Series Aai-engineer — AI engineer at AI-native companyfde — forward-deployed / solutions engineer at an AI labfullstack-ai — full-stack at an AI-native startuplocal-raleigh — Raleigh/RTP local role regardless of laneoff-lane — doesn't fit any lane (should usually be skipped)Fit score — a single integer 1–10. Rubric:
Show your reasoning — two to four sentences, not just a number.
Write applications/<app_id>/role.md using the template below. Overwrite if it exists (but confirm with Mason if the existing file has Mason's hand edits — look for non-template sections).
If you did substantial research beyond the JD (e.g. pulled in founder tweets, funding stage, etc.), consider logging a note_added event via the application-logger skill. For pure JD intake, no log event is needed — the role.md file itself is the artifact.
Report concisely:
Keep it short. Mason should be able to decide in <30 seconds.
# <Company> — <Role Title>
**app_id:** <app_id>
**URL (canonical):** <company careers page URL>
**URL (source):** <original URL if different>
**Location / remote:** <from JD>
**Posted:** <date if known>
**Stated salary:** <band or "not disclosed">
**Source:** <hn | workatastartup | linkedin | referral | ...>
---
## Lane
**<lane>** — <one sentence why>
## Fit score: <n>/10
<2-4 sentences of reasoning — what matches, what doesn't, why the number>
## Recommendation
**<apply | apply if slow week | skip — hard filter | skip — off-lane | skip — comp below floor>**
<one sentence why>
---
## Required (from JD)
- [✅ | 🟡 | 🔴 | ⚠️] Requirement 1 — verdict note
- [...] Requirement 2 — verdict note
- ...
## Nice-to-have (from JD)
- [✅ | 🟡 | 🔴] Nice-to-have 1 — verdict note
- ...
## Truthfulness gaps (things to NOT put on the resume, DO put on the study guide)
- Gap 1 — what the JD wants, what Mason has that's closest, why it's still a gap
- Gap 2 — ...
## What to lead with on the resume / cover letter
- Project 1 and why it maps to this role
- Specific skill/tool from Tier A that this JD prioritizes
- The agent-directed angle only if this company signals it's agent-friendly
## Company notes (sparse — leave full research to company-research skill)
- Funding stage: <if obvious from JD>
- Team size: <if obvious>
- Hiring thesis signal: <is this company explicitly agent-friendly? AI-native? degree-filtered?>
- Anything surprising or worth flagging
---
## JD text (canonical, cleaned)
<full JD text, cleaned of nav/boilerplate, preserved verbatim so downstream skills can search it>
applications/<app_id>/ exists first.data/events.jsonl directly. Read data/applications.json instead (it's the derived view).profile/preferences.md — Mason has explicit guidance on how hard vs soft degree requirements are treated. A hard "required" is a skip; a soft "preferred" is fine to apply past.profile/comp.md. If stated salary is below the floor, verdict is skip — comp below floor even if the fit is otherwise good.Mason: "https://www.ycombinator.com/companies/acme/jobs/xyz-founding-engineer"
application-logger first: creates app_id 2026-04-09-acme-founding-engineer, scaffolds folder.skills.md + preferences.md + projects/voices-that-remain.md (relevant because JD mentions AI pipelines).founding, fit = 9/10.applications/2026-04-09-acme-founding-engineer/role.md.Mason: pastes JD for a senior role at a big tech company that requires 8 years of experience and a PhD
application-logger if Mason wants it tracked (skipped applications are still worth tracking — you learn from them).role.md with recommended_action: skip — hard filter.Mason: "https://..." (small agency, quotes $55k)
comp.md floor of $70k.role.md, verdict skip — comp below floor.resume-tailor).company-research).applied — that's application-logger when Mason actually applies.data/ files directly.data-ai
Turn a job posting URL or pasted JD into a structured role.md file inside applications/<app_id>/. Extracts company, role, JD text, inferred lane (founding/AI eng/FDE/full-stack/local), required vs nice-to-have skills, fit notes against Mason's profile, and an honest truthfulness-gap list. Use whenever Mason shares a job link, pastes a JD, or asks "is this worth applying to?".
testing
Generate a tailored resume for a specific job application by combining Mason's profile, the role.md analysis, and the resume-base template. Every claim must trace back to profile/skills.md (Tier A/B), profile/projects/*.md, or profile/wins.md. Use whenever Mason wants a resume for a specific role he's decided to apply to.
testing
Draft a cold email or warm-intro-request message to a specific person at a target company. Produces applications/<app_id>/outreach/<slug>.md and logs a communication_sent event. Runs after company-research. Enforces the One-Take Rule — refuses to draft without a grounded decision from company.md. This is the highest-payoff channel per 2026 hiring research.
testing
Periodically scan a curated list of target company job boards for new postings that match Mason's lanes, and append candidate roles to a sourced-jobs queue for triage. Reads profile/target-companies.md and profile/preferences.md. Produces data/sourced-jobs.jsonl and a short daily digest. Use when Mason says "check for new jobs" or when running on a schedule.