← スキル一覧に戻る
generate-variant
fotescodev / portfolio
⭐ 1🍴 0📅 2026年1月15日
Generate job-targeted CV variants with built-in quality gates. Queries knowledge base, customizes content, runs eval/redteam pipeline.
SKILL.md
---
name: generate-variant
description: Generate job-targeted CV variants with built-in quality gates. Queries knowledge base, customizes content, runs eval/redteam pipeline.
---
# Generate Variant
<purpose>
Generate personalized portfolio variants for specific job opportunities, with full traceability and quality verification through a 9-phase pipeline.
</purpose>
<when_to_activate>
Activate when the user:
- Provides a job description or job URL
- Asks to create a variant for a specific company/role
- Says "generate variant", "create variant", "tailor CV for [company]"
- Wants to apply for a specific position
**Trigger phrases:** "variant", "tailor", "customize CV", "apply for [company]", "job application"
</when_to_activate>
<critical_principles>
## Critical Design Principles
**From Galaxy Variant Exercise:**
1. **Signature headline stays** — "Building at the edge of trust" is the brand
2. **companyAccent is REQUIRED** — Add inline company name (`— with {Company}`)
3. **Existing connections are gold** — Lead with what you've already proven
4. **Stats must be verifiable** — Every metric traced to knowledge base
5. **Pause between phases** — Get user approval before proceeding
</critical_principles>
---
## Phase 1: JD Analysis & Must-Have Extraction
**Goal:** Extract NON-GENERIC requirements using the deterministic `analyze:jd` script.
### Step 1.1: Save JD to File
If user provides JD text, save it first:
```bash
# Save JD to source-data/jd-{company}.txt
echo "[JD TEXT]" > source-data/jd-{company}.txt
```
### Step 1.2: Run Deterministic JD Analysis
**USE THE SCRIPT** — it automatically filters 47+ generic phrases and extracts specific requirements:
```bash
npm run analyze:jd -- --file source-data/jd-{company}.txt --save
```
This outputs to `capstone/develop/jd-analysis/{slug}.yaml` with:
- `extracted.company`, `extracted.role`, `extracted.yearsRequired`
- `mustHaves[]` with category and specificity (high/medium/low)
- `niceToHaves[]`
- `ignoredGeneric[]` — what was filtered out
- `domainKeywords[]` — crypto, fintech, developer_tools, etc.
- `searchTerms[]` — ready for knowledge base search
**What the script filters automatically:**
- "Team player", "excellent communicator", "fast-paced environment"
- "Passionate about [X]", "self-starter", "attention to detail"
- "Proven track record", "data-driven", "results-oriented"
- 40+ more generic phrases (see `scripts/analyze-jd.ts:GENERIC_PHRASES`)
### Step 1.3: Review Analysis Output
```bash
# Read the generated analysis
cat capstone/develop/jd-analysis/{slug}.yaml
```
Check for:
- Correct company/role extraction
- Meaningful must-haves (not generic)
- Appropriate domain keywords
### Step 1.4: Check for Existing Variants
```bash
ls content/variants/ | grep -i {company}
```
**Output:** JD analysis summary to user for confirmation before proceeding.
---
## Phase 1.5: Alignment Gate (GO/NO-GO)
**Goal:** Score alignment BEFORE investing time in content generation using the `search:evidence` script.
### Run Evidence Search
**USE THE SCRIPT** — it searches the knowledge base and generates an alignment report:
```bash
npm run search:evidence -- --jd-analysis capstone/develop/jd-analysis/{slug}.yaml --save
```
This outputs to `capstone/develop/alignment/{slug}.yaml` with:
- `summary.alignmentScore` — 0.0 to 1.0
- `summary.recommendation` — PROCEED | REVIEW | SKIP
- `summary.strongMatches` — count of high-relevance matches (≥70%)
- `summary.moderateMatches` — count of medium-relevance matches (40-70%)
- `matches[]` — sorted by relevance with evidence snippets
- `gaps[]` — search terms with no matches
### Alternative: Manual Search Terms
If you have specific terms not from JD analysis:
```bash
npm run search:evidence -- --terms "crypto,staking,infrastructure,api" --threshold 0.5 --save
```
### Review Alignment Report
```bash
cat capstone/develop/alignment/{slug}.yaml
```
### Decision Framework
| Score | Recommendation | Action |
|-------|----------------|--------|
| ≥ 0.50 + 2 strong | **PROCEED** | Generate variant |
| ≥ 0.30 or 1 strong | **REVIEW** | Show gaps, ask user if worth pursuing |
| < 0.30 and 0 strong | **SKIP** | Recommend not applying, show why |
### Honesty Check
For REVIEW/SKIP cases, the script surfaces:
- `gaps[]` — terms with no matching evidence
- Low relevance matches that may be stretches
Surface honestly:
- Which must-haves have no evidence
- Whether gaps are addressable (transferable skills) or hard blockers
- Honest assessment: "This role requires X, which isn't in your background"
**PAUSE:** Show alignment score and recommendation. Get explicit GO/NO-GO from user.
---
## Phase 2: Knowledge Base Query
**Goal:** Find matching achievements and stories.
1. Search achievements:
```bash
ls content/knowledge/achievements/
```
2. Read relevant achievement files matching JD requirements
3. Look for existing client relationships:
- Search for company name in achievements/stories
- Example: Galaxy was already an Anchorage client (ETH staking)
4. Rank matches by relevance (0.0-1.0):
- Direct skill match: 0.9-1.0
- Related experience: 0.7-0.9
- Transferable skills: 0.5-0.7
**Output:** List of relevant achievements with relevance scores.
---
## Phase 2.5: Bullet Coverage Check
**Goal:** Ensure experience highlights cover all 7 PM competency bundles using the `check:coverage` script.
### Run Coverage Check
**USE THE SCRIPT** — it automatically categorizes bullets into the 7 PM competency bundles:
```bash
npm run check:coverage
```
For JSON output (easier to process):
```bash
npm run check:coverage -- --json
```
To save report:
```bash
npm run check:coverage -- --save
```
### The 7 Competency Bundles (Automated)
The script categorizes based on keywords (see `scripts/check-coverage.ts:BUNDLES`):
| Bundle | Keywords Detected |
|--------|-------------------|
| **1. Product Design** | shipped, launched, built, designed, UX, prototyped, improved |
| **2. Leadership** | led, managed, coordinated, E2E, cross-functional, stakeholders |
| **3. Strategy** | strategy, vision, roadmap, prioritized, market analysis |
| **4. Business** | revenue, ARR, GTM, partnerships, growth, B2B, pricing |
| **5. Project Mgmt** | delivered, timeline, Agile, risk, milestones, on-time |
| **6. Technical** | architecture, API, SDK, data, metrics, trade-offs, system |
| **7. Communication** | presented, documented, collaborated, aligned, storytelling |
### Review Coverage Output
The script outputs:
- Count per bundle
- Examples of bullets in each bundle
- `gaps[]` — bundles with <2 bullets
- `overweight[]` — bundles with 5+ bullets
- Overall balance assessment
### Interpretation
| Gap Level | Action |
|-----------|--------|
| 0 gaps | Proceed — well-rounded |
| 1-2 gaps | Surface gaps to user — may want to emphasize in bio/tagline |
| 3+ gaps | Warning — resume may appear unbalanced |
### Using Coverage for This Variant
Cross-reference gaps with JD must-haves:
1. Does this role care about the gap? (Check Phase 1 analysis)
2. Can the bio/tagline emphasize this competency?
3. Are there achievements in knowledge base that weren't surfaced?
**Note:** Not all variants need all 7 bundles. A technical PM role may not care about "Business & Marketing." Use the JD must-haves to determine which gaps matter.
---
## Phase 3: Content Generation
**IMPORTANT:** Invoke `dmitrii-writing-style` skill before writing bio content.
### Hero Section
```yaml
hero:
status: "Open to Product Roles" # Keep simple
headline:
- text: "Building"
style: "italic"
- text: "at the edge of"
style: "muted"
- text: "trust"
style: "accent"
companyAccent: # REQUIRED
- text: "with"
style: "muted"
- text: "{Company}"
style: "accent"
subheadline: >
[Tailored elevator pitch mentioning company connection]
```
### About Section
```yaml
about:
tagline: >
[One-line positioning statement]
bio:
- >
[Paragraph 1: Recent experience, relevant achievements, company connection]
- >
[Paragraph 2: Career arc leading to this opportunity + vision]
stats:
- value: "[X]+"
label: "[Relevant metric]"
- value: "[Y]"
label: "[Relevant metric]"
- value: "[Z]"
label: "[Relevant metric]"
```
### Relevance Scoring
```yaml
relevance:
caseStudies:
- slug: "[most-relevant]"
relevanceScore: 1.0
reasoning: "[Why this matches JD]"
# ... ranked list
skills:
- category: "[Top category]"
relevanceScore: 1.0
# ... ranked list
```
**PAUSE:** Show generated content to user for review before proceeding.
---
## Phase 4: Variant File Creation
1. Create variant YAML:
```bash
# Write to content/variants/{slug}.yaml
```
2. Sync to JSON:
```bash
npm run variants:sync -- --slug {slug}
```
3. Verify JSON created:
```bash
ls content/variants/{slug}.json
```
---
## Phase 5: Evaluation Pipeline
1. Run evaluation:
```bash
npm run eval:variant -- --slug {slug}
```
2. Review extracted claims (metrics with anchors)
3. For each unverified claim, verify against knowledge base:
```bash
npm run eval:variant -- --slug {slug} --verify {claim-id}={source-path}
```
4. Target: **100% claims verified**
**PAUSE:** Show claims status to user before proceeding.
---
## Phase 6: Red Team Pipeline
1. Run red team scan:
```bash
npm run redteam:variant -- --slug {slug}
```
2. Review findings:
- **FAIL** — Must fix before publishing
- **WARN** — Review and decide
3. Common issues and fixes:
| Check | Issue | Fix |
|-------|-------|-----|
| RT-ACC-CLAIMS | Unverified claims | Run Phase 5 verification |
| RT-SEC-SECRETS | Tokens in content | Remove sensitive data |
| RT-TONE-SYCOPHANCY | Flattery detected | Rewrite objectively |
| RT-PRIV-JD | Long JD exposed | Truncate in YAML |
**PAUSE:** Show redteam results to user for approval.
---
## Phase 7: Final Review
1. Start dev server if not running:
```bash
npm run dev
```
2. Open variant in browser:
```
http://localhost:5173/{company}/{role}
```
3. Visual checklist:
- [ ] companyAccent renders inline after "trust"
- [ ] Stats are visible and accurate
- [ ] Bio reads naturally
- [ ] Case studies are relevant
4. Offer to commit if approved.
---
## Phase 8: Resume Generation
**Goal:** Generate a variant-specific resume PDF and link it to the variant.
1. Generate variant resume:
```bash
npm run generate:resume -- --variant {slug}
```
This will:
- Render the resume at `/{company}/{role}/resume`
- Output PDF to `public/resumes/{slug}.pdf`
- Auto-update variant YAML with `resumePath: /resumes/{slug}.pdf`
2. Sync the updated variant:
```bash
npm run variants:sync -- --slug {slug}
```
3. Verify resume was generated:
```bash
ls -la public/resumes/{slug}.pdf
```
**Note:** The variant resume uses the merged profile/experience data, so it reflects the tailored content (bio, stats, tagline) specific to this role.
---
## Phase 9: Dashboard Update
**Goal:** Regenerate the CV dashboard to include the new variant.
1. Regenerate dashboard HTML:
```bash
DASHBOARD_PASSWORD=<password> npm run generate:dashboard
```
Or use the combined command (syncs variants AND regenerates dashboard):
```bash
DASHBOARD_PASSWORD=<password> npm run variants:sync:dashboard
```
2. Verify the new variant appears in the dashboard output:
- Check the console shows the new variant in the list
- Dashboard HTML is updated at `public/cv-dashboard/index.html`
3. Commit the updated dashboard:
```bash
git add public/cv-dashboard/index.html
```
**Note:** The dashboard is password-protected. The `DASHBOARD_PASSWORD` env var is required. Check `.env.local` or ask the user for the password.
---
## Quality Checklist
Before marking variant complete:
- [ ] All claims verified against knowledge base
- [ ] No hallucinated achievements
- [ ] Company connection established (existing client? industry overlap?)
- [ ] Signature headline preserved with companyAccent (REQUIRED)
- [ ] Stats are verifiable and impactful
- [ ] Red team passes (0 FAIL, minimal WARN)
- [ ] Would defend every claim in an interview
- [ ] Writing style matches dmitrii-writing-style
- [ ] Resume PDF generated and linked (`resumePath` in variant metadata)
- [ ] Dashboard regenerated with new variant visible
---
## File Locations Reference
| File | Purpose |
|------|---------|
| `content/variants/{slug}.yaml` | Variant source (canonical) |
| `content/variants/{slug}.json` | Runtime artifact |
| `content/variants/_template.yaml` | Template reference |
| `capstone/develop/evals/{slug}.claims.yaml` | Claims ledger |
| `capstone/develop/evals/{slug}.eval.md` | Eval report |
| `capstone/develop/redteam/{slug}.redteam.md` | Redteam report |
| `content/knowledge/achievements/*.yaml` | Achievement sources |
| `content/knowledge/stories/*.yaml` | Story sources |
| `public/resumes/{slug}.pdf` | Variant-specific resume PDF |
| `public/cv-dashboard/index.html` | Dashboard HTML (password-protected) |
| `public/cv-dashboard/variants-manifest.json` | Dashboard data source |
---
## Commands Reference
```bash
# ═══════════════════════════════════════════════════════════════
# PHASE 1: JD Analysis (deterministic)
# ═══════════════════════════════════════════════════════════════
npm run analyze:jd -- --file source-data/jd-{company}.txt --save
npm run analyze:jd -- --file jd.txt --json # JSON output
# ═══════════════════════════════════════════════════════════════
# PHASE 1.5: Evidence Search (deterministic)
# ═══════════════════════════════════════════════════════════════
npm run search:evidence -- --jd-analysis capstone/develop/jd-analysis/{slug}.yaml --save
npm run search:evidence -- --terms "crypto,staking,api" --threshold 0.5
# ═══════════════════════════════════════════════════════════════
# PHASE 2.5: Coverage Check (deterministic)
# ═══════════════════════════════════════════════════════════════
npm run check:coverage
npm run check:coverage -- --json
npm run check:coverage -- --save
# ═══════════════════════════════════════════════════════════════
# PHASE 4-6: Variant Pipeline
# ═══════════════════════════════════════════════════════════════
npm run variants:sync -- --slug {slug}
npm run eval:variant -- --slug {slug}
npm run eval:variant -- --slug {slug} --verify {id}={path}
npm run redteam:variant -- --slug {slug}
# ═══════════════════════════════════════════════════════════════
# PHASE 8: Resume Generation
# ═══════════════════════════════════════════════════════════════
npm run generate:resume -- --variant {slug}
npm run variants:sync -- --slug {slug} # Sync after resume path update
# ═══════════════════════════════════════════════════════════════
# PHASE 9: Dashboard Update
# ═══════════════════════════════════════════════════════════════
DASHBOARD_PASSWORD=<password> npm run generate:dashboard
# Or combined sync + dashboard:
DASHBOARD_PASSWORD=<password> npm run variants:sync:dashboard
# ═══════════════════════════════════════════════════════════════
# PREVIEW
# ═══════════════════════════════════════════════════════════════
npm run dev
open "http://localhost:5173/{company}/{role}"
open "http://localhost:5173/{company}/{role}/resume" # Preview resume page
```
---
## Example: Galaxy PM Variant
**Job:** Director, Technical Program Manager at Galaxy
**Key Learnings Applied:**
1. Found existing connection: Galaxy was already an Anchorage client (ETH staking)
2. Matched L2 integration framework to "cross-functional" TPM requirement
3. Used punchy stats: "8+", "7+", "Zero" (all verified)
4. companyAccent: `trust — with Galaxy` (inline, subtle)
5. Status: "Open to Product Roles" (simple, not desperate)
**Result:** All 6 claims verified, redteam passed, variant shipped.
<quality_gate>
## Quality Gate
See [Quality Gate Template](../_shared/quality-gate.md) for universal checks.
**Variant-specific:**
- [ ] All claims verified against knowledge base
- [ ] companyAccent is set (REQUIRED)
- [ ] Red team passes (0 FAIL findings)
- [ ] Would defend every claim in an interview
</quality_gate>
<skill_compositions>
## Works Well With
- **dmitrii-writing-style** — MUST invoke before writing bio content
- **cv-knowledge-query** — Search evidence before generating
- **ultrathink** — For complex alignment decisions
- **generate-resume** — Generate variant-specific resume after variant
</skill_compositions>