evals/evals.json
{
"skill_name": "cv-linkedin",
"evals": [
{
"id": 0,
"prompt": "Please improve my CV at /tmp/eval-cv-linkedin-0/cv.md. My LinkedIn data export is unzipped at /tmp/eval-cv-linkedin-0/linkedin-export/.",
"description": "Backend engineer CV with weak verbs ('helped', 'worked on', 'was responsible for'), pure-task bullets with no outcome of any kind (no numbers, no scope, no named system), no summary, no GitHub link in contact section, and a flat skills dump with no categories. The accompanying LinkedIn export has a weak headline, empty Summary (About), and vague Position descriptions. Skill must detect 'Engineer' role, add summary using the engineer template, replace weak verbs, add [OUTCOME] placeholders on pure-task bullets (offering scope/named-system options, not just a metric), restructure skills into category groups, add GitHub placeholder, and produce a linkedin-improvements.md with stronger headline options, a written About section, and improved experience descriptions drawn from CV content.",
"setup": "mkdir -p /tmp/eval-cv-linkedin-0/linkedin-export && cat > /tmp/eval-cv-linkedin-0/cv.md << 'EOF'\nJohn Smith\njohn.smith@email.com | +1 555-0100 | New York, NY\n\nEXPERIENCE\n\nSoftware Developer — Acme Corp (2021–2024)\n- Helped with backend API development using Python and Django\n- Worked on improving system performance\n- Was responsible for database migrations using Alembic and PostgreSQL\n- Assisted the team with code reviews on GitHub\n- Participated in sprint planning and backlog grooming\n\nJunior Developer — StartupXYZ (2019–2021)\n- Involved in building the customer-facing mobile app in React Native\n- Worked on bug fixes across the codebase\n- Helped with writing unit tests with pytest\n- Participated in on-call rotation\n\nEDUCATION\nComputer Science, State University, 2019\n\nSKILLS\nPython, JavaScript, SQL, Git, Django, React Native, PostgreSQL, Alembic, pytest\nEOF\ncat > /tmp/eval-cv-linkedin-0/linkedin-export/Profile.csv << 'EOF'\nFirst Name,Last Name,Maiden Name,Address,Birth Date,Headline,Summary,Industry,Zip Code,Geo Location,Twitter Handles,Websites,Instant Messengers\nJohn,Smith,,,,Software Developer at Acme Corp,,Computer Software,,\"New York, NY\",,,\nEOF\ncat > /tmp/eval-cv-linkedin-0/linkedin-export/Positions.csv << 'EOF'\nCompany Name,Title,Description,Location,Started On,Finished On\nAcme Corp,Software Developer,Backend work in Python.,\"New York, NY\",Jan 2021,Dec 2024\nStartupXYZ,Junior Developer,Mobile app work.,\"New York, NY\",Jun 2019,Dec 2020\nEOF\ncat > /tmp/eval-cv-linkedin-0/linkedin-export/Education.csv << 'EOF'\nSchool Name,Start Date,End Date,Notes,Degree Name,Activities\nState University,2015,2019,,Computer Science,\nEOF\ncat > /tmp/eval-cv-linkedin-0/linkedin-export/Skills.csv << 'EOF'\nName\nPython\nDjango\nGit\nEOF",
"expected_output": "cv-improved.md written with: role detected as Engineer; a generated engineer-pattern summary mentioning backend/Python; all weak verbs replaced (at least 6 bullets rewritten); [OUTCOME: e.g. ...] placeholders with at least two non-number options (scope phrase / named system / number) appended to pure-task bullets — all 9 input bullets are pure task; skills restructured into category groups (Languages, Frameworks, Databases, Tools at minimum); GitHub placeholder added in contact section; 'Changes Made' header present. linkedin-improvements.md written with: stronger headline options including a stack keyword, a fresh About section derived from CV content, and experience descriptions for the Acme Corp role drawn from the CV's stronger material.",
"files": [],
"assertions": [
{
"id": "role-detected-as-engineer",
"text": "The 'Changes Made' block or summary states the detected role is Engineer (or Software Engineer / Developer)"
},
{
"id": "cv-improved-written",
"text": "cv-improved.md is created and contains at least one '## Experience' or '## Work History' or '## EXPERIENCE' section header (not just an empty file)"
},
{
"id": "summary-added-with-engineer-template",
"text": "cv-improved.md contains a Summary or Profile section that mentions backend development, Python, or Django and follows an engineer-pattern pitch (seniority + domain + outcome)"
},
{
"id": "weak-verbs-replaced",
"text": "The phrases 'helped with', 'worked on', 'was responsible for', 'assisted', 'participated in', and 'involved in' do not appear in the experience bullets of cv-improved.md"
},
{
"id": "outcome-placeholders-with-non-number-options",
"text": "At least 7 bullets in cv-improved.md contain a '[OUTCOME: e.g.' placeholder, and the hint text inside lists at least two non-number options (e.g. a scope phrase and a named system) — not just a single metric suggestion"
},
{
"id": "skills-restructured-into-categories",
"text": "The Skills section in cv-improved.md is organized into named categories (e.g. Languages, Frameworks, Databases, or Tools) rather than a flat comma-separated list"
},
{
"id": "github-placeholder-added",
"text": "cv-improved.md contains a GitHub placeholder or note in the contact section, since no GitHub link was present in the original"
},
{
"id": "original-not-overwritten",
"text": "The original file /tmp/eval-cv-linkedin-0/cv.md still contains 'Helped with backend API development' (original content unchanged)"
},
{
"id": "linkedin-improvements-written",
"text": "linkedin-improvements.md is created at /tmp/eval-cv-linkedin-0/linkedin-improvements.md AND contains at least one suggested headline that is more specific than 'Software Developer at Acme Corp'"
},
{
"id": "linkedin-about-written-from-cv",
"text": "linkedin-improvements.md contains a suggested About section that references Python, Django, or PostgreSQL — drawn from CV content since the export's Summary was empty"
},
{
"id": "content-preserved-alembic",
"text": "cv-improved.md mentions Alembic or PostgreSQL in the experience section — original technologies from the CV are preserved, not replaced with hallucinated alternatives"
}
]
},
{
"id": 1,
"prompt": "Can you improve my resume? It's at /tmp/eval-cv-linkedin-1/resume.md. Skip LinkedIn for now.",
"description": "Product Manager CV with strong bullets and metrics already present, but missing a summary section entirely. Skills section lacks PM-specific methodology terms (A/B testing, user research, OKRs) even though they appear in bullets. Role must be detected as PM, summary must follow PM template, skills should be restructured with PM category groups. No linkedin-improvements.md should be produced because the user explicitly said skip LinkedIn — the LinkedIn export prerequisite must be waived when the user opts out.",
"setup": "mkdir -p /tmp/eval-cv-linkedin-1 && cat > /tmp/eval-cv-linkedin-1/resume.md << 'EOF'\nMaria Garcia\nmaria.garcia@email.com | Austin, TX\n\nWORK EXPERIENCE\n\nSenior Product Manager — DataFlow Inc (Mar 2022–Present)\n- Launched DataFlow Analytics from 0 to $4.2M ARR in 18 months by partnering with sales to define enterprise pricing tiers\n- Ran 3 rounds of user research (22 interviews) that directly shaped the Q3 roadmap and reduced time-to-value from 14 days to 3 days\n- Drove A/B testing programme of 8 experiments per quarter, lifting trial-to-paid conversion by 19%\n- Aligned cross-functional team of 3 engineers, 1 designer, and 1 data scientist around a shared quarterly OKR\n\nProduct Manager — RetailTech Co (Jun 2019–Feb 2022)\n- Defined and shipped a self-serve checkout feature adopted by 62% of the user base within 90 days of launch\n- Prioritised backlog for a 5-person squad using data from Mixpanel and user feedback sessions\n- Partnered with engineering to reduce sprint cycle time from 3 weeks to 1 week through process changes\n- Delivered 3 integrations (Shopify, Salesforce, Zendesk) that each contributed >$200k ARR\n\nEDUCATION\nB.A. Economics, University of Texas at Austin, 2019\n\nSKILLS\nProduct Management, Roadmapping, Stakeholder Management, Jira, Figma, Mixpanel\nEOF",
"expected_output": "cv-improved.md written with: role detected as Product Manager; a new Summary section following the PM template (product type + business impact credential); Skills section expanded to include PM methodology terms present in bullets (A/B testing, user research, OKRs, cross-functional) and reorganised into PM-appropriate categories (Product Methodology, Analytics & Research, Tools); all strong quantified bullets preserved unchanged. No linkedin-improvements.md created.",
"files": [],
"assertions": [
{
"id": "role-detected-as-pm",
"text": "The 'Changes Made' block or summary states the detected role is Product Manager or PM"
},
{
"id": "summary-added-with-pm-template",
"text": "cv-improved.md contains a new Summary or Profile section that references product management experience, a product type (B2B SaaS, enterprise, or retail), and a business or user impact signal"
},
{
"id": "skills-expanded-with-pm-terms",
"text": "The Skills section in cv-improved.md includes A/B Testing, user research, or OKRs — terms present in the experience bullets but absent from the original skills list"
},
{
"id": "strong-bullets-preserved-verbatim",
"text": "The exact phrase '$4.2M ARR' appears in cv-improved.md in a bullet that also contains '18 months' — confirming the quantified bullet was preserved verbatim and not paraphrased or split"
},
{
"id": "linkedin-file-not-created",
"text": "The file /tmp/eval-cv-linkedin-1/linkedin-improvements.md does NOT exist — LinkedIn was skipped by the user"
},
{
"id": "original-not-overwritten",
"text": "The original /tmp/eval-cv-linkedin-1/resume.md still exists with its original content unchanged"
},
{
"id": "summary-contains-metric",
"text": "The new Summary section in cv-improved.md contains a specific number, dollar amount, or concrete product signal (not just generic language like 'proven track record' or 'results-driven')"
}
]
},
{
"id": 2,
"prompt": "Improve my CV at /tmp/eval-cv-linkedin-2/cv.md. My LinkedIn data export is at /tmp/eval-cv-linkedin-2/linkedin-export/.",
"description": "Engineer CV with 'Senior Software Engineer' title at MegaCorp but the LinkedIn export's Positions.csv has 'Software Engineer' for the same company — title inconsistency the skill must catch by comparing CSV against CV. The export's Summary (About) is weak and first-person ('I am a software engineer...'). Positions.csv has vague descriptions ('Worked on backend services') while the CV has strong quantified bullets. Tests inconsistency detection, engineer-pattern About rewrite leveraging CV metrics, and LinkedIn description improvement using CV content.",
"setup": "mkdir -p /tmp/eval-cv-linkedin-2/linkedin-export && cat > /tmp/eval-cv-linkedin-2/cv.md << 'EOF'\nAlex Johnson\nalex.johnson@protonmail.com | +1 206-555-0199 | Seattle, WA\ngithub.com/alexjdev | linkedin.com/in/alexjohnson-dev\n\nPROFILE\nSenior backend engineer with 7 years of experience in Java and distributed systems. Specialised in high-throughput microservices and event-driven architectures.\n\nEXPERIENCE\n\nSenior Software Engineer — MegaCorp (Jan 2020–Present)\n- Architected a microservices platform handling 50k requests/second across 12 services\n- Cut P99 API latency from 850ms to 95ms by introducing a Redis caching layer\n- Led a team of 5 engineers to deliver a real-time fraud detection system on schedule\n- Reduced infrastructure costs by $180k/year through reserved instance optimisation\n\nSoftware Developer — OldCo (Mar 2017–Dec 2019)\n- Built ETL pipelines in Java processing 10M records per night\n- Maintained and refactored a 200k-line legacy monolith, reducing defect rate by 28%\n- Helped onboard 3 new developers with documentation and pairing sessions\n\nEDUCATION\nB.Eng. Software Engineering, University of Washington, 2017\n\nSKILLS\nJava, Spring Boot, Redis, Kafka, PostgreSQL, AWS, Docker, Kubernetes, SQL, Git\nEOF\ncat > /tmp/eval-cv-linkedin-2/linkedin-export/Profile.csv << 'EOF'\nFirst Name,Last Name,Maiden Name,Address,Birth Date,Headline,Summary,Industry,Zip Code,Geo Location,Twitter Handles,Websites,Instant Messengers\nAlex,Johnson,,,,Software Engineer at MegaCorp,I am a software engineer with experience in Java and Spring Boot. I enjoy solving problems and working with teams.,Computer Software,,\"Seattle, WA\",,,\nEOF\ncat > /tmp/eval-cv-linkedin-2/linkedin-export/Positions.csv << 'EOF'\nCompany Name,Title,Description,Location,Started On,Finished On\nMegaCorp,Software Engineer,Worked on backend services.,\"Seattle, WA\",Jan 2020,\nOldCo,Developer,Maintained legacy systems.,\"Seattle, WA\",Mar 2017,Dec 2019\nEOF\ncat > /tmp/eval-cv-linkedin-2/linkedin-export/Education.csv << 'EOF'\nSchool Name,Start Date,End Date,Notes,Degree Name,Activities\nUniversity of Washington,2013,2017,,B.Eng. Software Engineering,\nEOF\ncat > /tmp/eval-cv-linkedin-2/linkedin-export/Skills.csv << 'EOF'\nName\nJava\nSpring Boot\nSQL\nAgile\nEOF",
"expected_output": "cv-improved.md with minor targeted changes: 'Helped onboard' bullet rewritten with a strong verb (no OUTCOME placeholder needed since '3 new developers' is already a scope signal). linkedin-improvements.md must: flag the 'Senior Software Engineer' (CV) vs 'Software Engineer' (LinkedIn) title inconsistency for the MegaCorp role; suggest engineer-pattern headlines with Java/distributed-systems keywords; rewrite the About section removing first person and expanding beyond 'I enjoy solving problems'; provide MegaCorp experience bullets using the CV's strong quantified content; note Redis, Kafka, Docker, Kubernetes as skills to add to LinkedIn.",
"files": [],
"assertions": [
{
"id": "title-inconsistency-flagged",
"text": "linkedin-improvements.md flags the inconsistency between 'Senior Software Engineer' (CV) and 'Software Engineer' (LinkedIn) for the MegaCorp role"
},
{
"id": "engineer-headline-suggested",
"text": "linkedin-improvements.md suggests at least 2 headline options that include Java or distributed systems or microservices keywords and follow the engineer headline template (not just 'Software Engineer at MegaCorp')"
},
{
"id": "about-first-person-removed-with-metric",
"text": "The suggested About section in linkedin-improvements.md does not start with 'I am' or 'I ' and references at least one specific metric from the CV (50k requests/second, P99 latency, $180k, or 28%)"
},
{
"id": "experience-description-improved",
"text": "linkedin-improvements.md suggests replacing 'Worked on backend services' with bullets drawn from the CV's quantified content (latency cut, cost reduction, or fraud detection system)"
},
{
"id": "missing-skills-flagged",
"text": "linkedin-improvements.md identifies Redis, Kafka, Docker, or Kubernetes as skills to add to LinkedIn (present in CV but absent from LinkedIn skills list)"
},
{
"id": "cv-improved-written",
"text": "cv-improved.md is created and the 'Helped onboard' bullet uses a stronger verb (not 'Helped')"
},
{
"id": "no-outcome-placeholder-on-complete-bullets",
"text": "cv-improved.md contains zero '[OUTCOME' or '[METRIC' placeholders — every bullet in this CV already carries a number, scope, or named system, so the skill must leave them alone instead of piling on placeholders"
}
]
},
{
"id": 3,
"prompt": "Review my CV at /tmp/eval-cv-linkedin-3/cv.md and improve my LinkedIn. Export is unzipped at /tmp/eval-cv-linkedin-3/linkedin-export/.",
"description": "Engineering Manager CV that is already well-written with team size and delivery metrics. LinkedIn export is severely incomplete: generic headline with no context, empty Summary (About), no Positions descriptions. Tests EM role detection, EM-pattern summary check, EM-specific LinkedIn headline templates, and full About section generation from CV content. Also tests that 'Featured skills' quick win recommends EM-appropriate top-3 skills.",
"setup": "mkdir -p /tmp/eval-cv-linkedin-3/linkedin-export && cat > /tmp/eval-cv-linkedin-3/cv.md << 'EOF'\nClaire Martin\nclaire.martin@email.com | London, UK\n\nPROFILE\nEngineering manager with 6 years leading backend and platform teams in B2B SaaS. Known for building high-trust, high-delivery teams. Track record of scaling engineering orgs through hypergrowth while maintaining quality and low attrition.\n\nEXPERIENCE\n\nEngineering Manager — ScaleUp (Apr 2021–Present)\n- Grew engineering team from 4 to 18 across 3 squads (backend, platform, data) in 18 months\n- Reduced attrition from 34% to 8% year-over-year by introducing structured career ladders and quarterly 1:1 goal reviews\n- Delivered 4 consecutive quarters on roadmap commitments with a team CSAT of 4.6/5\n- Partnered with CTO to define technical strategy for migrating monolith to microservices, unblocking 3 dependent product streams\n- Hired and onboarded 11 engineers; established a structured interview process that cut time-to-hire from 9 weeks to 4 weeks\n\nSenior Software Engineer — OldPlace (Jan 2018–Mar 2021)\n- Architected real-time notification system handling 2M events/day using Kafka and Go\n- Led technical design for API gateway consolidation, reducing external integrations from 14 to 5\n- Mentored 4 junior engineers; 2 were promoted within 18 months\n\nEDUCATION\nM.Sc. Computer Science, Imperial College London, 2017\n\nSKILLS\nEngineering Management, Team Leadership, Hiring & Onboarding, Career Development, Technical Strategy, Go, Kafka, Python, Agile, JIRA\nEOF\ncat > /tmp/eval-cv-linkedin-3/linkedin-export/Profile.csv << 'EOF'\nFirst Name,Last Name,Maiden Name,Address,Birth Date,Headline,Summary,Industry,Zip Code,Geo Location,Twitter Handles,Websites,Instant Messengers\nClaire,Martin,,,,Engineering Manager,,Computer Software,,\"London, UK\",,,\nEOF\ncat > /tmp/eval-cv-linkedin-3/linkedin-export/Positions.csv << 'EOF'\nCompany Name,Title,Description,Location,Started On,Finished On\nScaleUp,Engineering Manager,,\"London, UK\",Apr 2021,\nOldPlace,Senior Software Engineer,,\"London, UK\",Jan 2018,Mar 2021\nEOF\ncat > /tmp/eval-cv-linkedin-3/linkedin-export/Education.csv << 'EOF'\nSchool Name,Start Date,End Date,Notes,Degree Name,Activities\nImperial College London,2015,2017,,M.Sc. Computer Science,\nEOF\ncat > /tmp/eval-cv-linkedin-3/linkedin-export/Skills.csv << 'EOF'\nName\nEngineering Management\nPython\nAgile\nEOF",
"expected_output": "cv-improved.md with minimal changes (CV is already strong) — Changes Made should explicitly state 0 bullets rewritten or that no rewrites were needed. linkedin-improvements.md must: suggest EM-pattern headlines (include team size and domain context, not just 'Engineering Manager'); generate a full About section (~150+ words) that references '34%', '8%', or '18' (the specific attrition and team growth numbers); provide experience descriptions for both roles using CV content; list 'Team Building' or 'Performance Management' as a suggested featured top-3 skill; mark adding the About section as Quick Win #1.",
"files": [],
"assertions": [
{
"id": "role-detected-as-em",
"text": "The 'Changes Made' block or summary states the detected role is Engineering Manager or EM"
},
{
"id": "em-headline-suggested",
"text": "linkedin-improvements.md suggests at least 2 headline options that include team size context or domain (B2B SaaS, platform, or similar) and follow the EM headline template"
},
{
"id": "about-references-specific-metrics",
"text": "The suggested About section in linkedin-improvements.md is at least 120 words AND references specific metrics from the CV: '34%' or '8%' or '18' (team growth from 4 to 18, or attrition reduction numbers)"
},
{
"id": "experience-descriptions-filled",
"text": "linkedin-improvements.md provides experience description bullets for the ScaleUp EM role derived from the CV's quantified content"
},
{
"id": "about-is-top-quick-win",
"text": "The Quick Wins section in linkedin-improvements.md lists adding the About section as the #1 priority"
},
{
"id": "cv-changes-zero-rewrites",
"text": "The 'Changes Made' section in cv-improved.md explicitly states 0 bullets rewritten or 'no rewrites needed' or 'none' — confirming the already-strong CV was not unnecessarily modified"
}
]
},
{
"id": 4,
"prompt": "My CV is at /tmp/eval-cv-linkedin-4/cv.md. LinkedIn export at /tmp/eval-cv-linkedin-4/linkedin-export/.",
"description": "Early-career full-stack engineer with a strong Projects section (OpenBudget — 340 GitHub stars). LinkedIn export Summary is generic ('Developer who likes building things. Always learning.'), Positions descriptions are empty, Skills.csv only lists JavaScript and React even though the CV has many more. Tests that the skill: detects Engineer role; promotes the Projects section in CV-improved since work experience is thin; generates headlines with stack keywords; rewrites the LinkedIn About using OpenBudget as the lead credential.",
"setup": "mkdir -p /tmp/eval-cv-linkedin-4/linkedin-export && cat > /tmp/eval-cv-linkedin-4/cv.md << 'EOF'\nLuca Rossi\nluca.rossi@gmail.com | Milan, Italy\n\nSUMMARY\nFull-stack developer passionate about building great user experiences. Fast learner who enjoys working with modern JavaScript frameworks.\n\nEXPERIENCE\n\nFull Stack Developer — FinanceFlow (Sep 2022–Present)\n- Built and shipped the customer dashboard in React and TypeScript, used daily by 3,000 paying customers\n- Integrated Plaid API for bank account linking, handling OAuth flows and webhook processing in Node.js\n- Reduced frontend bundle size by 41% through code splitting and lazy loading, cutting initial load time from 4.2s to 1.1s\n\nJunior Developer — AgencyX (Jun 2020–Aug 2022)\n- Built 14 client websites using React, Next.js, and Tailwind CSS\n- Implemented e-commerce checkout flows for 3 clients using Stripe; highest-volume site processed €180k/month\n- Set up CI/CD pipeline with GitHub Actions, cutting manual deployment time from 2 hours to 8 minutes\n\nPROJECTS\n\nOpenBudget (open source, 340 GitHub stars)\n- Personal finance dashboard built with Next.js, Prisma, and PostgreSQL; 1,200 monthly active users\n- Featured on Hacker News front page (top 10 for 6 hours)\n\nEDUCATION\nB.Sc. Computer Science, Politecnico di Milano, 2020\n\nSKILLS\nJavaScript, TypeScript, React, Next.js, Node.js, PostgreSQL, Tailwind CSS, Git, GitHub Actions, Stripe, Plaid\nEOF\ncat > /tmp/eval-cv-linkedin-4/linkedin-export/Profile.csv << 'EOF'\nFirst Name,Last Name,Maiden Name,Address,Birth Date,Headline,Summary,Industry,Zip Code,Geo Location,Twitter Handles,Websites,Instant Messengers\nLuca,Rossi,,,,Full Stack Developer,Developer who likes building things. Always learning.,Computer Software,,\"Milan, Italy\",,,\nEOF\ncat > /tmp/eval-cv-linkedin-4/linkedin-export/Positions.csv << 'EOF'\nCompany Name,Title,Description,Location,Started On,Finished On\nFinanceFlow,Full Stack Developer,,\"Milan, Italy\",Sep 2022,\nAgencyX,Junior Developer,,\"Milan, Italy\",Jun 2020,Aug 2022\nEOF\ncat > /tmp/eval-cv-linkedin-4/linkedin-export/Education.csv << 'EOF'\nSchool Name,Start Date,End Date,Notes,Degree Name,Activities\nPolitecnico di Milano,2017,2020,,B.Sc. Computer Science,\nEOF\ncat > /tmp/eval-cv-linkedin-4/linkedin-export/Skills.csv << 'EOF'\nName\nJavaScript\nReact\nEOF",
"expected_output": "cv-improved.md with: summary rewritten to remove 'passionate about' and 'fast learner', replacing with engineer-pattern pitch that mentions a specific technology (React, TypeScript, or Node.js) or metric; GitHub placeholder added since no GitHub link is in the original contact. linkedin-improvements.md must: suggest headlines with full-stack / React / TypeScript / Node.js keywords; generate an About section that mentions OpenBudget within the first 60 words (leading with the standout credential); flag the LinkedIn About as severely weak; recommend adding TypeScript, Next.js, Node.js to LinkedIn skills; mark 'Add GitHub profile link' as a top quick win.",
"files": [],
"assertions": [
{
"id": "generic-summary-removed-specific-added",
"text": "The phrases 'passionate about' and 'fast learner' do not appear in the cv-improved.md summary AND the rewritten summary includes a specific technology (React, TypeScript, or Node.js) or a concrete metric"
},
{
"id": "github-placeholder-added",
"text": "cv-improved.md adds a GitHub link or placeholder in the contact section, and the skill flags this as important given the user has a notable open-source project"
},
{
"id": "engineer-headline-suggested",
"text": "linkedin-improvements.md suggests headlines that include React, TypeScript, Node.js, or full-stack keywords — more specific than 'Full Stack Developer'"
},
{
"id": "about-opens-with-openbudget",
"text": "The suggested LinkedIn About section mentions OpenBudget within the first 60 words — leading with the standout credential rather than burying it"
},
{
"id": "missing-skills-added",
"text": "linkedin-improvements.md recommends adding TypeScript, Next.js, or Node.js to LinkedIn skills (present in CV but absent from LinkedIn's skills list)"
},
{
"id": "cv-improved-written",
"text": "cv-improved.md is created and the original cv.md is not modified"
}
]
},
{
"id": 5,
"prompt": "Please review my CV at /tmp/eval-cv-linkedin-5/cv.pdf. Skip LinkedIn for now.",
"description": "Tests that when a PDF CV is provided, the skill activates PDF reading capability and logs it explicitly using the Phase 1 instructions (check for document-skills:pdf, log the method used). The PDF contains a backend engineer profile for Sophie Turner at CloudSoft GmbH with weak verbs and unquantified bullets. The primary assertion is that the skill logs PDF reading with the specific named method, and that the output preserves real content from the PDF (Sophie Turner, CloudSoft) rather than hallucinating. LinkedIn is skipped, so no export prerequisite applies.",
"setup": "mkdir -p /tmp/eval-cv-linkedin-5 && python3 << 'PYEOF'\nimport os\n\nstream = b\"\"\"BT\n/F1 12 Tf\n50 750 Td\n(Sophie Turner) Tj\n0 -16 Td\n(sophie.turner@email.com | Berlin, Germany) Tj\n0 -32 Td\n(EXPERIENCE) Tj\n0 -16 Td\n(Backend Engineer - CloudSoft GmbH 2020-2024) Tj\n0 -16 Td\n(- Worked on REST API development using Python and FastAPI) Tj\n0 -16 Td\n(- Helped improve system reliability and uptime) Tj\n0 -16 Td\n(- Was responsible for PostgreSQL database schema migrations) Tj\n0 -16 Td\n(- Participated in code reviews and sprint ceremonies) Tj\n0 -32 Td\n(Junior Developer - WebAgency 2018-2020) Tj\n0 -16 Td\n(- Assisted with building client websites in Django) Tj\n0 -16 Td\n(- Worked on fixing bugs across multiple projects) Tj\n0 -32 Td\n(EDUCATION) Tj\n0 -16 Td\n(B.Sc. Computer Science, TU Berlin, 2018) Tj\n0 -32 Td\n(SKILLS) Tj\n0 -16 Td\n(Python, FastAPI, Django, PostgreSQL, Docker, Git, Linux) Tj\nET\"\"\"\n\nobj1 = b\"1 0 obj\\n<< /Type /Catalog /Pages 2 0 R >>\\nendobj\\n\"\nobj2 = b\"2 0 obj\\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\\nendobj\\n\"\nobj3 = b\"3 0 obj\\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>\\nendobj\\n\"\nobj4 = b\"4 0 obj\\n<< /Length \" + str(len(stream)).encode() + b\" >>\\nstream\\n\" + stream + b\"\\nendstream\\nendobj\\n\"\nobj5 = b\"5 0 obj\\n<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>\\nendobj\\n\"\n\nheader = b\"%PDF-1.4\\n\"\npos = len(header)\noffsets = []\nparts = [obj1, obj2, obj3, obj4, obj5]\nfor p in parts:\n offsets.append(pos)\n pos += len(p)\n\nxref_pos = pos\nxref = b\"xref\\n0 6\\n0000000000 65535 f \\n\"\nfor o in offsets:\n xref += \"{:010d} 00000 n \\n\".format(o).encode()\n\ntrailer = b\"trailer\\n<< /Size 6 /Root 1 0 R >>\\nstartxref\\n\" + str(xref_pos).encode() + b\"\\n%%EOF\\n\"\npdf = header + b\"\".join(parts) + xref + trailer\n\nwith open('/tmp/eval-cv-linkedin-5/cv.pdf', 'wb') as f:\n f.write(pdf)\nprint('PDF created, size:', len(pdf))\nPYEOF",
"expected_output": "The skill logs that it read the CV as a PDF file — mentioning 'PDF' explicitly and stating whether it used document-skills:pdf or the Read tool directly. cv-improved.md is written to /tmp/eval-cv-linkedin-5/ with: 'Sophie Turner' and 'CloudSoft' preserved from the PDF content; role detected as Engineer; a new summary section; weak verbs replaced; [OUTCOME] placeholders on pure-task bullets (all 6 input bullets are pure task). LinkedIn skipped as requested.",
"files": [],
"assertions": [
{
"id": "pdf-reading-logged-with-method",
"text": "The skill's conversation output mentions 'PDF' explicitly AND also mentions either 'document-skills:pdf' or 'Read tool' — showing the specific method used, not just 'reading the file' generically"
},
{
"id": "cv-improved-written-from-pdf",
"text": "The file /tmp/eval-cv-linkedin-5/cv-improved.md is created despite the input being a PDF"
},
{
"id": "content-preserved-from-pdf",
"text": "cv-improved.md contains 'Sophie Turner' or 'CloudSoft' or 'FastAPI' — confirming real PDF content was read and preserved, not hallucinated"
},
{
"id": "role-detected-as-engineer",
"text": "The 'Changes Made' block in cv-improved.md states the detected role is Engineer (or Backend Engineer / Software Engineer)"
},
{
"id": "weak-verbs-replaced",
"text": "The phrases 'worked on', 'helped improve', 'was responsible for', 'participated in', and 'assisted with' do not appear in the experience bullets of cv-improved.md"
},
{
"id": "outcome-placeholders-added",
"text": "At least 5 bullets in cv-improved.md contain an [OUTCOME] placeholder — applied because all input bullets are pure task (no number, no scope, no named system)"
},
{
"id": "original-pdf-not-overwritten",
"text": "The original /tmp/eval-cv-linkedin-5/cv.pdf still exists and is a valid PDF (starts with %PDF-)"
}
]
},
{
"id": 6,
"prompt": "Please improve my CV at /tmp/eval-cv-linkedin-6/cv.md. My LinkedIn username is danconsa but I haven't done a data export yet.",
"description": "User provides a CV but no LinkedIn export — only a username, which the new flow does not accept. Skill must (a) explain that the LinkedIn data export is the required input now, (b) give specific instructions on how to request the export (URL or Settings & Privacy → Data Privacy → Get a copy of your data), (c) pause and wait for the user to come back with the export path — do NOT write linkedin-improvements.md, and do NOT proceed to invent LinkedIn analysis from the username alone.",
"setup": "mkdir -p /tmp/eval-cv-linkedin-6 && cat > /tmp/eval-cv-linkedin-6/cv.md << 'EOF'\nDaniel Concepcion\ndaniel@example.com | Barcelona, Spain\n\nEXPERIENCE\n\nSoftware Engineer — Ocado Technology (2022–Present)\n- Worked on backend services in Java and Spring Boot\n- Helped with Kafka stream processing\n- Was responsible for integration tests\n\nEDUCATION\nM.Sc. Computer Science, Universidad de Zaragoza, 2022\n\nSKILLS\nJava, Kotlin, Spring Boot, Kafka, PostgreSQL\nEOF",
"expected_output": "Skill responds with instructions for obtaining the LinkedIn data export (mentioning 'Get a copy of your data', 'download-my-data', or the Settings & Privacy → Data Privacy navigation path) and waits for the user to provide the export directory. The skill does NOT write linkedin-improvements.md and does NOT fabricate any LinkedIn analysis from the username alone. The CV may or may not be processed (acceptable to wait for both inputs, or to process just the CV if the user later clarifies they want to skip LinkedIn).",
"files": [],
"assertions": [
{
"id": "export-instructions-given",
"text": "The skill's response mentions either 'Get a copy of your data', 'download-my-data', or 'Data Privacy' — giving the user a concrete path to obtain the LinkedIn export"
},
{
"id": "username-not-treated-as-sufficient",
"text": "The skill does NOT proceed to write linkedin-improvements.md based on the username 'danconsa' alone — the file /tmp/eval-cv-linkedin-6/linkedin-improvements.md does not exist OR if it exists, it contains an explicit 'export not provided' / 'awaiting export' message rather than fabricated profile content"
},
{
"id": "no-fabricated-experience-descriptions",
"text": "If linkedin-improvements.md exists, it does NOT contain invented role descriptions for Ocado Technology beyond what is in the CV — verifying no hallucination from the bare username"
}
]
}
]
}
SKILL.md
---
name: cv-linkedin
description: >
Analyze and improve a CV and LinkedIn profile for software industry roles.
Use when the user asks to "improve my CV", "review my resume", "optimize my
LinkedIn profile", "help with my LinkedIn", "make my resume better", "create
a CV", "prepare my resume for job applications", "update my LinkedIn", or
anything about career documents for software engineers, developers, product
managers, product owners, engineering managers, tech leads, SREs, DevOps
engineers, data engineers, ML engineers, or other software-industry roles.
The user must provide a CV file path and a path to an unzipped LinkedIn data
export directory (obtained via LinkedIn's "Get a copy of your data" feature).
If either is missing, ask for both before proceeding and — if the export is
missing — walk the user through requesting it.
tools: Read, Write, Glob, TaskCreate, TaskUpdate, SkillInvoke(document-skills:pdf)
model: sonnet
---
# CV & LinkedIn Improver — Software Industry Edition
Analyze the user's CV and LinkedIn profile for a software industry role, then
produce an improved CV and a LinkedIn optimization guide. All advice is
role-aware: the expectations for a Staff Engineer differ from those for a
Senior Product Manager or an Engineering Manager.
---
## Task Tracking
Before doing any work, call `TaskCreate` for each phase below. Call `TaskUpdate` (status `in_progress`) when you begin a phase and `TaskUpdate` (status `completed`) when you finish it.
- Read CV
- Detect role type
- Read LinkedIn data export
- Analyze CV
- Analyze LinkedIn profile
- Write improved CV
- Write LinkedIn improvement guide
- Print summary
---
## Phase 0: Gather Inputs
Before doing anything else, confirm you have both of:
1. **CV file path** — path to their CV (plain text, Markdown, PDF text, or similar).
2. **LinkedIn data export directory** — path to a directory containing the CSV files from LinkedIn's official "Get a copy of your data" export (at minimum `Profile.csv`, `Positions.csv`, `Education.csv`, `Skills.csv`). May be a path to an unzipped directory or a path to the `.zip` itself — if a `.zip`, unzip it in place first.
Direct LinkedIn fetching is **not** supported by this skill: LinkedIn's User Agreement prohibits automated extraction, the live page only server-renders the top card (About / Experience / Education / Skills are lazy-loaded behind authenticated XHR calls), and cookie-based scraping risks account restrictions. The data export is LinkedIn's sanctioned alternative and gives complete, structured, source-of-truth data.
If either input is missing, **ask for both at once**. If the user does not yet have the LinkedIn export, give them this instruction verbatim and wait:
> To get your LinkedIn data:
> 1. Open <https://www.linkedin.com/mypreferences/d/download-my-data>
> 2. Choose **"Want something in particular?"** and tick at least: `Profile`, `Positions`, `Education`, `Skills`, `Certifications`, `Languages`, `Projects`.
> 3. Click **Request archive**, re-enter your password.
> 4. The fast archive arrives by email in ~10 minutes; download and unzip it.
> 5. Reply with the path to the unzipped folder (and your CV path).
**If the user explicitly says to skip LinkedIn** (e.g. "skip LinkedIn", "just the CV"), proceed with only the CV. Skip Phases 2 (Read LinkedIn export), 4 (Analyse LinkedIn), and 6 (Write LinkedIn guide). Note the skip in the final summary.
---
## Phase 1: Read the CV
Read the file at the path the user provided. If the file is not found, report the error and stop.
**PDF files (.pdf extension):**
- Log: "CV format: PDF — checking for document-skills:pdf skill."
- If the `document-skills:pdf` skill is available in your environment, invoke it to extract the CV text and then log: "Reading CV using document-skills:pdf skill."
- If it is not available, use the Read tool directly and log: "Reading CV as PDF using Read tool (document-skills:pdf not installed)."
**All other formats** (Markdown, plain text, Word, etc.): use the Read tool and log: "Reading CV as [format] using Read tool."
Parse the content into these sections (names vary — match by content, not heading label):
- **Contact**: name, email, phone, location, GitHub URL, portfolio/personal site, LinkedIn URL
- **Summary / Profile / Objective**: the opening pitch
- **Experience / Work History**: each role with title, company, dates, and bullet points
- **Education**: degrees, institutions, dates; also bootcamps and relevant MOOCs
- **Skills / Technical Skills**: keyword lists or grouped categories
- **Projects**: personal or open-source projects (especially relevant for engineers)
- **Certifications**: cloud certs (AWS, GCP, Azure), Kubernetes (CKA/CKAD), Scrum, PMP, etc.
- **Publications / Talks**: conference talks, blog posts, papers (senior/staff level)
Note which sections are present, absent, or thin.
---
## Phase 1b: Detect Software Role Type
Classify the user's target role from their current title, past titles, and skills. This
classification drives all downstream advice — do not skip it.
**Engineer** — any variant of: Software Engineer, Developer, SRE, DevOps Engineer,
Data Engineer, ML Engineer, Platform Engineer, Security Engineer, Frontend, Backend,
Full-Stack, Mobile, Embedded, QA Engineer. Signals: programming languages in skills,
technical architecture bullets, GitHub link, system design language.
**Product Manager / Product Owner** — any variant of: PM, APM, Senior PM, GPM, Director
of Product, VP Product, Product Owner, Product Lead. Signals: roadmap, user research,
A/B testing, PRD, OKRs, go-to-market, stakeholder management language.
**Engineering Manager / Technical Leader** — any variant of: Engineering Manager, EM,
Staff/Principal/Distinguished Engineer, Tech Lead, VP Engineering, CTO, Director of
Engineering, Head of Engineering. Signals: reports/headcount numbers, hiring, performance
reviews, org-level impact, both people management AND technical decision language.
**Other software roles** (Designer, Data Scientist, Analyst, etc.) — apply general
advice; note the role and adapt as best as possible.
If the role cannot be determined from the CV, ask: "What type of role are you targeting?
(e.g. Software Engineer, Product Manager, Engineering Manager)"
---
## Phase 2: Read the LinkedIn Data Export
Read the CSVs from the export directory. See `references/linkedin-export-schema.md` for the exact column names, the `Month YYYY` date format, and the multi-line `Description` field gotcha (use a real CSV parser — do not split on commas yourself).
**Required CSVs** (skill stops with an error if any are missing):
- `Profile.csv` — single-row CSV. Extract `First Name`, `Last Name`, `Headline`, `Summary` (= LinkedIn About), `Industry`, `Geo Location`, `Websites`, `Twitter Handles`.
- `Positions.csv` — one row per role. Extract `Company Name`, `Title`, `Description`, `Location`, `Started On`, `Finished On` (empty string = current role).
- `Education.csv` — one row per entry. Extract `School Name`, `Start Date`, `End Date`, `Degree Name`, `Notes`, `Activities`.
- `Skills.csv` — one row per skill. Extract `Name`.
**Optional CSVs** (use if present, do not fail if absent):
- `Certifications.csv` — `Name`, `Authority`, `Started On`, `Finished On`, `License Number`, `Url`.
- `Languages.csv` — `Name`, `Proficiency`.
- `Projects.csv` — `Title`, `Description`, `Started On`, `Finished On`, `Url`.
- `Volunteering.csv` — `Company Name`, `Role`, `Started On`, `Finished On`, `Cause`, `Description`.
**Reading rules:**
- Use a real CSV parser. The `Description` and `Summary` fields commonly contain embedded newlines, commas, and quotes.
- LinkedIn export column names vary slightly across vintages. If a required column is not found by its expected name, look for the close variants documented in `references/linkedin-export-schema.md` (e.g. `Started On` vs `Start Date`).
- If the directory exists but a required CSV is missing or empty, list which file is missing and ask the user to re-export with the right categories ticked. Do not proceed to Phase 4.
- If the path the user provided is a `.zip`, unzip it in place (to a sibling folder named like the zip without `.zip`) and use that as the export directory.
- Sort `Positions.csv` rows by `Started On` descending so the most recent role is processed first; rows with empty `Finished On` are current and rank highest.
Note which optional CSVs are absent — this affects Phase 4 (e.g. no Certifications.csv means certifications cannot be audited; do not invent any).
---
## Phase 3: Analyse the CV
### 3a. Summary / Profile Section
- **Missing?** → Flag. Recruiters read the top third first; no summary = no pitch.
- **Generic phrases?** Flag any of: *results-oriented*, *dynamic*, *passionate about*,
*team player*, *hard worker*, *detail-oriented*, *fast learner*, *self-starter*,
*go-getter*, *ninja*, *rockstar*. These add zero signal.
- **First person?** "I am a developer..." → rewrite as a statement with no grammatical subject.
- **Length?** Ideal: 3–5 lines, 40–60 words. Flag if over 80 words.
- **Role-specific expectations:**
- **Engineer**: should mention primary stack or domain (e.g. "backend engineer specialising
in distributed systems and Go"), seniority signal (years or scope), and a standout outcome.
- **PM**: should mention the type of product (B2B SaaS, consumer, platform, growth) and
the scale or impact of past work (users, revenue, team size). "I love building products"
is not a pitch.
- **EM / Tech Lead**: should name team size or org scope, the type of engineering culture
or transformation driven, and career-level signal (managed N engineers, built N teams).
### 3b. Work Experience Bullets
For each bullet across all roles, check:
**Weak verb openers — always flag:**
*helped*, *worked on*, *assisted with*, *was responsible for*, *involved in*,
*participated in*, *supported*, *contributed to*, *played a role in*, *tried to*
**Strong verb banks by role:**
| Role | Strong Verbs |
|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Engineer | *engineered, architected, built, shipped, refactored, migrated, automated, reduced, optimised, scaled, deployed, integrated, designed, implemented, debugged* |
| PM / PO | *defined, launched, prioritised, drove, shipped, grew, negotiated, aligned, validated, synthesised, owned, partnered, increased, reduced, delivered* |
| EM / TL | *led, hired, grew, scaled, restructured, established, mentored, unblocked, defined, championed, partnered, transformed, delivered, set, cultivated* |
**Outcome check — flag bullets that are pure task, with no outcome of any kind.**
A bullet is *complete* if it carries at least one of:
- A **number** (latency, throughput, users, cost, dollar amount, percent, team size).
- A **scope or scale phrase** ("across 12 services", "for a 30-engineer org", "in a 2M-user product").
- A **named system or shipped artifact** ("the order-orchestration service", "v2 of the billing API", "the fraud-detection pipeline").
- A **before/after comparison**, even without numbers ("migrated from REST to gRPC", "replaced the bash deploy script with GitLab CI").
- A **complexity / problem signal** ("designed the leader-election protocol", "debugged a memory leak in the JVM scheduler").
A bullet that has **none** of those — e.g. "Wrote unit tests", "Worked on backend services",
"Participated in code reviews" — is pure task; flag it.
Numbers are **one** way to add outcome, not the only way. Invented or trivially small
numbers are worse than no number — recruiters and hiring managers spot them. For
engineers, scope and named-system signals are equally legitimate; for PMs and EMs, hard
numbers carry more weight because business KPIs and team metrics are inherent to the role.
| Role | Metric types when a number IS the right outcome |
|----------|---------------------------------------------------------------------------------------------------------------------------------|
| Engineer | Latency (ms), throughput (req/s), uptime (%), test coverage (%), build/deploy time, lines of code removed, cost savings ($) |
| PM / PO | MAU/DAU, conversion rate (%), ARR/MRR ($), NPS, sprint velocity, time-to-market, number of experiments run |
| EM / TL | Team size (#), hiring targets met (#), attrition rate (%), delivery on-time (%), promotion rate, number of teams/squads managed |
A pure-task bullet needs `[OUTCOME: e.g. <scope phrase> OR <named system> OR <number>]` appended — listing **at least two non-number options** so the user is not pushed to invent a metric.
**Result vs. task:**
"Wrote unit tests" (task) vs. "Achieved 94% test coverage on the payments service,
catching 3 critical regressions before they reached production" (number-as-outcome) vs.
"Built the regression-test harness for the payments service" (named-system-as-outcome) —
both rewrites are valid.
### 3c. Education and Certifications
- Degrees fully named? "CS degree" → "B.Sc. Computer Science, University of X, Year"
- Graduation year present?
- **Certifications (software-specific):** Flag if the person has cloud/infra experience
but no cloud cert listed, or does agile/scrum work but no cert — worth adding if held.
Certs that matter: AWS SA/Developer/SysOps, GCP ACE/PCA, Azure AZ-900/AZ-204,
CKA/CKAD, CSPO, CSM, PMP.
### 3d. Skills Section
- **Present?** Missing entirely is a serious ATS problem.
- **Structure by role:**
- **Engineer** — group by: `Languages`, `Frameworks & Libraries`, `Databases`,
`Cloud & Infrastructure`, `Testing`, `Tools`. Flat dumps are hard to skim.
- **PM** — group by: `Product Methodology`, `Analytics & Research`, `Tools`,
and optionally `Technical Background` if relevant.
- **EM / TL** — group by: `Leadership & Management`, `Engineering Practices`,
`Technical Background`, `Tools`.
- Technologies mentioned in experience bullets but absent from the skills section?
- Consistent casing: `JavaScript` (not `Javascript`), `TypeScript`, `PostgreSQL`,
`AWS`, `Kubernetes`, `GraphQL`, `CI/CD`.
### 3e. Software-Specific Signals
- **GitHub / portfolio link in contact section?**
- **Engineers**: flag if absent — recruiters and technical interviewers look for this.
Even an empty profile is better than none; note the gap.
- **PMs / EMs**: optional but valuable if they have public writing or side projects.
- **Open-source contributions** listed? For engineers, these are strong differentiators.
- **Projects section** present for engineers with fewer than 5 years experience? Essential
if the work history is thin.
- **Tenure signals**: flag any unexplained gap longer than 6 months.
- **ATS keyword coverage**: verify that key terms from the user's target role appear
in the CV. Common ATS terms by role:
- Engineer: the actual technology names (React, Kubernetes, Python, etc.) must be
spelled out in full — acronyms alone fail ATS parsers.
- PM: "product roadmap", "A/B testing", "user research", "cross-functional",
"go-to-market", "OKRs", "KPIs".
- EM: "engineering management", "agile", "performance management", "technical
strategy", "stakeholder management".
---
## Phase 4: Analyse the LinkedIn Profile
*(Skip entirely if the user chose to skip LinkedIn in Phase 0.)*
The data here is parsed from CSVs in Phase 2, so every check below operates on
concrete values — do not hedge with "if the headline is present". A field is
either present (non-empty string in the CSV) or absent (empty string / missing
column). Treat absent as a flagged finding, not a question to ask the user.
### 4a. Headline
If it is only the job title + company, it wastes the highest-visibility field on LinkedIn.
LinkedIn headline is the #1 field recruiters use in search filters.
**Headline templates by role:**
| Role | Template |
|----------|-----------------------------------------------------------------------------------------------------------------------------------------|
| Engineer | `{Seniority} {Specialisation} Engineer · {Primary Stack} · {Domain or Impact}` |
| PM | `{Seniority} Product Manager · {Product Type, e.g. B2B SaaS / Consumer / Platform} · {Impact angle, e.g. 0-to-1 / Growth / Enterprise}` |
| EM / TL | `Engineering Manager · {Team/Org context} · {Scale or domain, e.g. 40-person org / Fintech / Developer Tooling}` |
Examples:
- "Senior Backend Engineer · Go & Kafka · Building high-throughput fintech systems"
- "Product Manager · B2B SaaS · 0-to-1 Products & Enterprise Expansion"
- "Engineering Manager · 3 Teams, 24 Engineers · Platform & Infrastructure"
### 4b. About / Summary
- **Present?** (LinkedIn penalises completeness score if absent; profile ranks lower in search.)
- **Hook?** First 2 visible lines (before "...see more") must earn the click.
- **Flow:** what you do → what you are known for / strongest credential → what you are
looking for → contact CTA.
- **Role-specific must-haves:**
- **Engineer**: mention primary language/stack and one scale or performance achievement.
- **PM**: mention product type and one business or user impact metric.
- **EM**: mention team size and one org or delivery achievement.
### 4c. Experience Descriptions
- Roles with no descriptions are a missed opportunity — LinkedIn allows far more than a CV.
- Descriptions should expand on the CV, not copy-paste it.
- **Engineers**: describe the technical problem and the solution, not just the outcome.
- **PMs**: describe the business context (what problem, who the users were, what you shipped).
- **EMs**: describe the team's mission and your contribution to org health and delivery.
### 4d. Skills Section
- Top 3 featured skills should be the most recruiter-relevant for the target role.
- **Engineer**: feature the primary programming language, the main framework/platform,
and either the cloud provider or a relevant specialisation.
- **PM**: feature "Product Management", the domain (e.g. "SaaS", "B2B", "Mobile"),
and a methodology or tool (e.g. "Product Strategy", "A/B Testing").
- **EM**: feature "Engineering Management", a delivery methodology, and either a technical
domain or a scale signal (e.g. "Team Building", "Agile", "Distributed Systems").
### 4e. CV vs. LinkedIn Alignment
For each `Positions.csv` row, find the matching CV role by `Company Name`. Compare:
- `Title` vs. CV title — flag any difference (recruiters notice and ask).
- `Started On` / `Finished On` vs. CV dates — flag a mismatch greater than ~1 month. The CSV format is `Month YYYY`; CV dates may be `YYYY` only or a range — normalise to year before comparing.
- Roles present on the CV but absent from `Positions.csv` (LinkedIn looks abandoned for that period).
- Roles present in `Positions.csv` but absent from the CV (CV looks incomplete or there's a deliberate omission worth surfacing).
For Education, do the same comparison using `School Name` as the join key.
---
## Phase 5: Write Improved CV
Write the improved CV to `cv-improved.md` in the **same directory** as the original CV file.
If the CV content was pasted directly (no file path), write to `./cv-improved.md`.
**Rules:**
- Rewrite the summary using a role-specific template (use content already in the CV):
- **Engineer**: `{Seniority} {specialisation} engineer with {X} years building {domain}
systems. Known for {technical strength from bullets}. Track record of {performance or
scale achievement}.`
- **PM**: `Product manager with {X} years shipping {product type} for {user type}.
Known for {strength, e.g. "0-to-1 launches" / "growth experimentation"}. Track record
of {business outcome type}.`
- **EM**: `Engineering manager with {X} years leading {N}-person teams in {domain}.
Known for {strength, e.g. "building high-trust teams" / "technical transformation"}.
Track record of {delivery or org outcome}.`
- Replace every weak verb with a strong one from the role-specific verb bank in Phase 3b.
- For every **pure-task** bullet (no outcome of any kind, per the Phase 3b outcome check), append `[OUTCOME: e.g. <scope phrase>, <named system>, or <number>]`, listing **at least two non-number suggestions** drawn from the role and surrounding context. Do **not** append this to bullets that already carry scope, a named system, or a before/after comparison — even if no digit is present; those are already complete.
- **Do not invent facts.** Preserve company names, dates, titles, and technologies exactly.
- If the Skills section was absent, create one using the role-appropriate category structure
from Phase 3d, populated from technologies named in experience bullets.
- For engineers: if no GitHub link is in the contact section, add a placeholder
`GitHub: github.com/[your-username]` with a note that they should add the real link.
- Format: clean Markdown. `##` for section headers, `### Title @ Company (Start–End)`
for each role, `-` for bullets.
**Begin the file with a "Changes Made" block:**
```
## Changes Made
- Role detected: {Engineer / PM / EM}
- Summary: [added / rewrote — reason]
- Bullets rewritten: N across M roles (weak verbs → strong verbs)
- [OUTCOME] placeholders added: N bullets (only pure-task bullets — others left as-is)
- Skills section: [added with role structure / reformatted / unchanged]
- [any other changes, e.g. GitHub placeholder added]
```
**Never overwrite the original CV file.**
---
## Phase 6: Write LinkedIn Improvement Guide
*(Skip if the user chose to skip LinkedIn. Write to `linkedin-improvements.md` in the
same directory as the improved CV.)*
```markdown
# LinkedIn Profile Improvements — {Full Name from CV}
Role: {Engineer / PM / EM}
Generated: {today's date}
---
## Headline
**Current:** {their current headline, or "(not set)"}
**Suggested options (pick one or adapt):**
1. {Role-specific option A — uses template from Phase 4a}
2. {Role-specific option B — alternative angle}
3. {Role-specific option C — third variation}
**Why these work better:** {one sentence — what keyword or signal the current headline misses}
---
## About / Summary
**Current status:** {present and strong / present but weak / missing}
**Suggested text (~150–200 words):**
{Write a complete improved About section using the role-specific flow from Phase 4b.
Line 1–2 (hook, visible before "see more"): lead with role + domain + a hook credential.
Lines 3–6: core skills, domain expertise, one or two standout achievements from the CV.
Engineers: include primary stack and a scale-or-system fact (a number, a scope phrase, or a named system — whichever is most credible from the CV).
PMs: include product type and a business impact fact (numbers carry weight here — use them if the CV has them).
EMs: include team size and an org achievement.
Final 2 lines: what they are looking for + contact CTA.}
---
## Experience Description Improvements
{For each role where descriptions are missing or weak, provide improved content.
Skip roles that are already strong.}
### {Title} @ {Company}
**Add or replace with:**
- {Strong bullet — role-appropriate verb + quantified result drawn from CV content}
- {Additional bullet if the entry was sparse}
---
## Skills to Add or Feature
| Skill | Why | Seen in |
|---|---|---|
| {skill} | {missing from list / should be a top-3 featured skill} | {which role or section} |
---
## CV vs. LinkedIn Inconsistencies
| Field | CV | LinkedIn | Fix |
|---|---|---|---|
{rows — or omit entire table if no inconsistencies found}
---
## Quick Wins — Do These First
Ranked by recruiter visibility impact on LinkedIn for a {role type}:
1. **{Most impactful}** — {what to change and exactly where}
2. **{Second}** — {what to change}
3. **{Third}** — {what to change}
```
---
## Phase 7: Print Summary
```
## CV & LinkedIn Improvements Complete
Role: {Engineer / PM / EM / Other}
**Improved CV:** {full path to cv-improved.md}
- Summary: {added fresh / rewrote generic version}
- Bullets improved: {N} across {M} roles
- [OUTCOME] placeholders added: {N} (on pure-task bullets only)
{any other notable changes}
**LinkedIn Guide:** {full path to linkedin-improvements.md} [or "Skipped"]
- Headline: {N} alternatives suggested
- About section: {written fresh / rewrote weak version} (~{word count} words)
- Experience descriptions: {N} roles with new/improved bullets
- Inconsistencies flagged: {N}
**Top 3 Quick Wins:**
1. {Most impactful — specific and role-aware}
2. {Second}
3. {Third}
```