Phase 2 packet
Build a Phase 2 outreach packet for a single greenlit role. Triggers on "build packet for X", "tailor CV for X", "Phase 2", "packet X", "/packet", or any request to prepare an application for a specific company / role. Pulls the full JD via the ATS redirect, identifies the right contacts, generates a JD-tailored CV (docx + PDF) per the discipline rules, drafts channel-appropriate outreach (Connect+Note + longer DM), and saves the packet under outreach/{slug}/. Stops before Phase 3 - waits for the user's explicit "send" approval.From its SKILL.md
npx -y skills add bgolubovski/exec-recruiter --skill phase-2-packetAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.4 KB, as published. Nobody here has run it
phase-2-packet
Build the Phase 2 outreach packet for a single role. Pull the JD, identify contacts, tailor the CV, draft outreach, save the packet, present in chat.
When to invoke
The user says: "build packet for X", "tailor CV for X", "Phase 2 for X", "packet X", "/packet X", or "let's go" after a Phase 1 greenlight summary.
Inputs
The user names a role by company or by slug. Resolve to:
company(string)role_title(string)linkedin_url(the/jobs/view/{id}/URL)slug(kebab-case, e.g.brevia-vp-product)
If the role is in the dashboard but no slug yet, generate one. If the role isn't in the dashboard, scaffold a minimal entry first.
Workflow
Step 1: Pull the full JD
Delegate to the jd-extractor agent (or run inline). The LinkedIn jobs page renders a skeleton in unauthenticated views; the real body lives behind the "Apply on company website" redirect. Recover it via:
- Navigate to the LinkedIn jobs URL in Chrome
- Find the Apply link's
href - Decode the
/safety/go/?url=...query param to recover the destination ATS URL - Navigate to the destination (Teamtailor, Workable, Greenhouse, Lever, Ashby, company-careers page)
- Extract the full JD body text including:
- About the role / mission
- Responsibilities / day-in-the-life
- Required experience / qualifications
- Comp band if stated
- Anti-bot screener words / phrases (look for
mention the word "..."orinclude "..." in your application) - Reporting line and sit-on-SLT signals
- Customer / partner names called out by name
- In-office requirement (number of days)
- Pre-employment check requirements (FCA, security clearance, criminal/credit checks)
Step 2: Sanity-check tier classification
If the JD body reveals signals that contradict the Phase-1 card-level triage (e.g., title says "Head of Product" but body says "individual contributor / chief of staff"), STOP. Surface the mismatch to the user with two options:
- A) Skip - reclassify as Skip, log reason
- B) Reframe and proceed - tailor for the actual scope (e.g., "I have been the CPO three times; force-multiplier IC at this scale-up is by choice")
- C) Apply low-effort - careers application only, no Connect+Note, no CV refresh
Do NOT proceed to Step 3 without the user's call.
Step 3: Identify contacts
Apply the contact-discovery cascade from ${CLAUDE_PLUGIN_ROOT}/config/channels.yaml:
- LinkedIn job poster (the "Meet the hiring team" panel)
- Hiring manager named in JD body (often "Reports to: ..." or specific name)
- 1st-degree connection at the company in product/eng leadership
- 2nd-degree with strong mutuals
- Founder / CEO for founder-led companies
- Recruiter-first (de-anon path) for recruiter-masked listings
For each candidate contact, check:
- Degree of connection (1st / 2nd / 3rd)
- Open Profile status (do they show a
Messagebutton without InMail paywall?) - Public LinkedIn URL
When the role's reporting-to-CTO is in another timezone or appears to be transitioning out (e.g., now CEO at a different company), consider parallel reach to both the CTO and the CEO of the hiring company.
Step 4: Tailor the CV
Delegate to the cv-tailor agent. Pass:
--role-slug- the kebab slug--baseline- path to the user's master CV (default:${CLAUDE_PLUGIN_ROOT}/templates/cv-baseline.docx, but the user may have replaced this with their own)- Replacements derived from the JD per the discipline:
- Headline-positioning fragment (one phrase that captures the role's mandate)
- Adjacency sentence (last sentence of executive summary, lands the role-specific analogue)
- One or two career-highlight cells (rename + body)
- Italic context line per relevant past role
- Geo-conditional header per
geo-rules.cv_header_templates - "Tailored for {company}, {role}" tag (the baseline carries no such line; the tailor script inserts it via its
--tailored-forflag)
The agent applies the discipline rules from outreach-style.yaml:
- Identity stable
- Max 2 of 6 highlight cells changed
- One phrase per past role's italic context line
- No em/en dashes anywhere
- Geo header conditional
Outputs Operator-FirstName-CV-{slug}.docx and .pdf in outreach/{slug}/.
Step 5: Draft outreach
Delegate to the outreach-drafter agent. Generate:
- Connect+Note (Premium 300 char or standard 280 char) for the primary contact, leading with one concrete JD hook + one pattern-match anchor
- Connect+Note for the backup contact (parallel reach)
- Longer DM (120-180 words) for use after a connection accepts, or if Open Profile path lands
Apply outreach-style.yaml rules: peer-to-peer, no banned phrases, no em/en dashes, signed off with first name.
For role-specific anti-bot screener words detected in the JD body, draft a Summary / cover-letter blurb that includes the word naturally (per outreach-style.yaml.screener_test_words.action).
Step 6: Save the packet
Create outreach/{slug}/ and write:
Operator-FirstName-CV-{slug}.docxOperator-FirstName-CV-{slug}.pdfjd.md- JD notes from${CLAUDE_PLUGIN_ROOT}/templates/jd.md.template, populatedoutreach.md- outreach drafts from${CLAUDE_PLUGIN_ROOT}/templates/outreach.md.template, populated
Step 7: Append to dashboard
Append a new role entry to the dashboard's ROLES = [...] array with:
id- one greater than the current maxslug- the kebab slugrole,company,location,comp,scorejdUrl- the canonical/jobs/view/{id}/URL (NOT the search URL)contact- primary contact name + rolecontactUrl- primary contact's LinkedIn URLchannels- planned channelssendDate: null- until Phase 3status: "drafted"note- long-form note capturing the score rationale, friction flags, and pattern match anchors
Step 8: Present in chat
Output:
- Score and tier
- JD URL + primary contact LinkedIn URL (per
feedback_packet_links.mdrule: ALWAYS show JD URL + contact URL in chat at greenlight, not just in saved files) - Connect+Note draft (verbatim, with char count)
- Friction flags worth confirming with the user before send
- Computer:// links to the saved CV PDF, DOCX, jd.md, outreach.md
Step 9: STOP
Do NOT proceed to Phase 3. Wait for the user's explicit "send" per role.
Approval gate
Before saving the packet, surface for the user:
- Tier classification post-JD-extraction (may have changed from Phase 1)
- Comp band alignment
- Geo friction
- Title-scope alignment (line-product vs IC vs specialist)
If any of these have shifted from the Phase-1 read, surface the shift before generating the CV. The user gets the call.
References
See ${CLAUDE_PLUGIN_ROOT}/skills/phase-2-packet/references/cv-tailoring-discipline.md for the canonical replacement-key pattern. See ${CLAUDE_PLUGIN_ROOT}/skills/phase-2-packet/references/contact-discovery-recipes.md for LinkedIn search patterns to identify contacts.