9.0 KiB
Mode: followup -- Follow-up Cadence Tracker
Read
voice-dna.md(if present) and apply it to every generated email/LinkedIn draft. This mode is standalone — it does NOT load_shared.md, so readvoice-dna.mddirectly. Follow-up drafts are conversational, so apply the full guardrail: banned words/phrases/patterns, no em-dashes, no negative parallelisms (§3-4) AND conversational voice — contractions, varied rhythm, direct "I"/"you" (§1-2). Never drop or soften a real metric fromcv.mdfor style.
Purpose
Track follow-up cadence for active applications. Flag overdue follow-ups, extract contacts from notes, and generate tailored follow-up email/LinkedIn drafts using report context.
Inputs
data/applications.md— Application trackerdata/follow-ups.md— Follow-up history (created on first use)reports/— Evaluation reports (for context in drafts)config/profile.yml— User profile (name, identity)cv.md— CV for proof points in drafts
Step 1 — Run Cadence Script
Execute:
node followup-cadence.mjs
Parse the JSON output. It contains:
| Key | Contents |
|---|---|
metadata |
Analysis date, total tracked, actionable count, overdue/urgent/cold/waiting counts |
entries |
Per-application: company, role, status, days since application, follow-up count, urgency, next follow-up date, extracted contacts, report path |
cadenceConfig |
Cadence rules (applied: 7 days, responded: 3 days, interview: 1 day) |
If no actionable entries, tell the user:
"No active applications to follow up on. Apply to some roles first with
/career-opsand come back when they're aging."
Step 2 — Display Dashboard
Show a cadence dashboard sorted by urgency (urgent > overdue > waiting > cold):
Follow-up Cadence Dashboard — {date}
{N} applications tracked, {N} actionable
| # | Company | Role | Status | Days | Follow-ups | Next | Urgency | Contact |
Use visual indicators:
- URGENT — respond within 24 hours (company replied)
- OVERDUE — follow-up is past due
- waiting (X days) — on track, follow-up scheduled
- COLD — 2+ follow-ups sent, suggest closing
Step 3 — Generate Follow-up Drafts
For each overdue or urgent entry only:
- Read the linked report (
reportPathfrom JSON) for company context - Read
cv.mdfor proof points - Read
config/profile.ymlfor candidate name and identity
Agency-mediated applications (#1596): when the entry's via field is set (the cadence JSON emits via: null for direct applications), the chase target is the agency contact (recruiter named in the notes/contacts), not the company — the recruiter owns the client relationship and has their own incentive to respond. Reference the role by the agency's framing.
When the end employer is unknown (company ?), this branch REPLACES the framework rules below — do not fall through to them. There is no company name to mention and nothing company-specific to reference, so instead:
- Sentence 1 references the role by the agency's framing (their listing title + the recruiter's name) plus when you applied — the application date stays in the opening exactly as the framework requires; only the company reference is replaced, never with a placeholder company name.
- Sentence 2's value-add draws on cv.md/report proof points that fit the role as listed — skip the "specific to THAT company" rule.
- Add the client-name ask: request the end employer's name as a natural part of the follow-up ("so I can prepare properly, could you share which company this role is with?") — that reveal is what unlocks cross-channel dedup in the tracker.
When via is set but the employer IS known, use the framework below unchanged except the recipient: address the recruiter, mention the client company by name.
Email Follow-up Framework (first follow-up, followupCount == 0)
Generate a 3-4 sentence email:
- Sentence 1: Reference the specific role + when you applied. Be specific — mention the company name and role title.
- Sentence 2: One concrete value-add from the report's Block B match or a proof point from cv.md. Quantify if possible.
- Sentence 3: Soft ask + availability. Offer a specific time window ("this week" or "next Tuesday").
- Sentence 4 (optional): Brief mention of a relevant recent project or achievement.
Rules:
- Professional but warm, NOT desperate
- NEVER use "just checking in", "just following up", "touching base", or "circling back"
- Lead with value, not with the ask
- Reference something specific to THAT company (from report Block A)
- Keep under 150 words
- Include a subject line
- Use the candidate's name from
config/profile.yml
Example tone:
Subject: Re: Senior PHP/Laravel Developer — IxDF
Hi [contact name or "team"],
I submitted my application for the Senior PHP/Laravel Developer role on April 7th. I wanted to share that my production Laravel app (Barbeiro.app — 120 models, 315 API endpoints, full test suite) closely mirrors the TDD-driven culture described in the posting.
I'd love to discuss how my 15 years of PHP experience and hands-on AI tooling workflow could contribute to IxDF's platform. Would any time this week work for a brief conversation?
Best, [Name]
LinkedIn Follow-up (if no email contact found)
Reuse the contacto framework: 3 sentences, 300 character max.
- Hook specific to company → proof point → soft ask
- Suggest the user run
/career-ops contacto {company}to find the right person first
Second Follow-up (followupCount == 1)
Shorter than first (2-3 sentences). Take a new angle:
- Share a relevant insight, article, or project update
- Don't repeat the first follow-up's content
- Still reference the role specifically
Cold Application (followupCount >= 2)
Do NOT generate another follow-up. Instead suggest:
"This application has had {N} follow-ups with no response. Consider:
- Updating status to
Discardedif the role seems filled- Trying a different contact via
/career-ops contacto- Keeping in
Appliedstatus but deprioritizing"
Step 4 — Present Drafts
For each draft, show:
## Follow-up: {Company} — {Role} (#{num})
**To:** {email or "No contact found — run `/career-ops contacto` first"}
**Subject:** {subject line}
**Days since application:** {N}
**Follow-ups sent:** {N}
**Channel:** Email / LinkedIn
{draft text}
Step 5 — Record Follow-ups
After the user reviews and says they've sent a follow-up, record it:
-
If
data/follow-ups.mddoesn't exist, create it (this exact header — the same one the web UI writes;followup-cadence.mjsparses these columns):# Follow-ups | num | appNum | date | company | role | channel | contact | notes | |---|---|---|---|---|---|---|---| -
Append a row with:
num= next sequential number in the follow-ups tableappNum= application number from trackerdate= today's date (YYYY-MM-DD)company= company namerole= role titlechannel= Email / LinkedIn / Othercontact= who it was sent tonotes= brief note (e.g., "First follow-up, referenced Barbeiro.app")
-
Optionally update the Notes column in
data/applications.mdwith "Follow-up {N} sent {YYYY-MM-DD}"
IMPORTANT: Only record follow-ups the user confirms they actually sent. Never record a draft as sent.
Pinned next dates & automatic seeding
data/follow-ups.md also supports pin lines that override the computed
schedule for a single application:
- next #42 2026-07-10 (set 2026-07-02)
#42 is the application number, the first date is the pinned NEXT follow-up
date, and (set …) is the day the pin was made. Pins take precedence over
the computed schedule until a follow-up is logged on or after the set-date;
the latest pin per application wins; deleting the line clears the pin.
Pins may be seeded AUTOMATICALLY when an application turns Applied —
node followup-seed.mjs <num> (run by the apply mode's Step 9) appends a
pin scheduling the first follow-up at apply date + the applied_first
cadence. Seeding is idempotent, and a stale pin left behind by a later
Rejected/Discarded transition is harmless because the cadence analysis
ignores non-actionable statuses.
Step 6 — Summary
After showing all drafts, summarize:
Follow-up Dashboard ({date})
- {N} applications being tracked
- {N} overdue — drafts generated above
- {N} urgent — respond today
- {N} waiting — next follow-up dates shown
- {N} cold — consider closing
Review the drafts above and tell me which ones you've sent so I can record them.
Cadence Rules Reference
| Status | First follow-up | Subsequent | Max attempts |
|---|---|---|---|
| Applied | 7 days after application | Every 7 days | 2 (then mark cold) |
| Responded | 1 day (urgent reply) | Every 3 days | No limit |
| Interview | 1 day after (thank-you) | Every 3 days | No limit |
These defaults can be overridden via node followup-cadence.mjs --applied-days N.