Skip to content

feat: implement causal chain bullet rewriting with seniority-aware framing#81

Open
Ztrimus wants to merge 1 commit into
mainfrom
feat/#55/causal-chain-bullet-rewriting
Open

feat: implement causal chain bullet rewriting with seniority-aware framing#81
Ztrimus wants to merge 1 commit into
mainfrom
feat/#55/causal-chain-bullet-rewriting

Conversation

@Ztrimus

@Ztrimus Ztrimus commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

Enforces an explicit causal chain formula on every resume bullet, anchors Tier 1 keywords from #54, and adjusts framing based on the detected seniority level of the target role.

Closes #55
Depends on #54


Problem

Issue Impact
No enforced bullet structure Bullets ranged from excellent to generic with no consistency
No Tier 1 keyword obligation Keywords extracted in #54 weren't guaranteed to appear in bullets
No seniority awareness Same framing for a junior analyst and a staff engineer
No fabrication guard LLM could invent metrics not supported by the candidate's history

Causal Chain Formula

Bad: "Worked on database migration projects"
Good: "Led 6-engineer team migrating 14M records to PostgreSQL, cutting query latency by 68%"


Rules (applied to every bullet in EXPERIENCE + PROJECTS)

# Rule
1 Every bullet must contain ≥1 Tier 1 keyword from
2 Use numbers/percentages whenever the original resume data supports them
3 Scope fallback: team size, data volume, user count if no metric exists
4 Never fabricate metrics not in the original resume
5 Seniority framing — see table below
6 Preserve all factual details (company, title, dates) exactly
7 Reverse-chronological order

Seniority framing

Bullet emphasis
Learning velocity, initiative, direct contribution, collaboration
Technical wins, measurable outcomes, independent ownership
System-level scope, cross-team impact, strategic decisions
People leadership, org-level outcomes, directional influence

Schema change

Added to .

Detection signals baked into :

  • Years required: 0-2 → junior, 2-5 → mid, 5+ → senior
  • Title modifiers: Senior/Staff/Principal → senior, Lead/Manager/Director → lead
  • Scope language: "owns", "drives", "leads team" → senior/lead

Zero integration cost

flows into section prompts via the existing — no changes to .

Verified

All 9 templates smoke-tested. Literal constraint validated (rejects invalid values).

…aming

Closes #55
Depends on #54 (keyword tiers, already merged)

## Problem
Bullet generation was generic — no enforced structure, no per-tier keyword
obligation, no fabrication guard, and no awareness of whether the role was
junior vs. lead. Modern ATS LLMs score quantified, keyword-anchored bullets
3-5x higher than vague ones.

## Changes

### zlm/schemas/job_details_schema.py
- Added `seniority_level: Literal["junior", "mid", "senior", "lead"]` to
  `JobDetails`. Validated by Pydantic — rejects invalid values at parse time.
- Added `Literal` to imports.

### zlm/prompts/resume_prompt.py (JOB_DETAILS_EXTRACTOR)
- Expanded step 1 of `<reasoning>` to include seniority detection signals:
  years required (0-2 → junior, 2-5 → mid, 5+ → senior), title modifiers
  (Senior/Staff/Principal → senior, Lead/Manager/Director → lead), and
  scope language ("owns", "drives", "leads team" → senior/lead).
- Added `seniority_level` to `<instructions>` with mapping rules and signals.

### zlm/prompts/sections_prompt.py (EXPERIENCE + PROJECTS)
Replaced generic bullet guidance with an explicit 7-rule causal chain contract:

  Formula: [Action Verb] + [Tier 1 Keyword] + [Quantified Impact or Scope]

  Rule 1 — Tier 1 must-have: every bullet must contain ≥1 Tier 1 keyword.
  Rule 2 — Metrics first: use numbers whenever original data supports them.
  Rule 3 — Scope fallback: if no metric, add team size / data volume / scale.
  Rule 4 — No fabrication: metrics not in the original resume are forbidden.
  Rule 5 — Seniority framing (references `seniority_level` from job JSON):
    junior → learning velocity, initiative, direct contribution
    mid    → technical wins, measurable outcomes, independent ownership
    senior → system scope, cross-team impact, strategic decisions
    lead   → people leadership, org-level outcomes, directional influence
  Rule 6 — Factual preservation: titles, companies, dates unchanged.
  Rule 7 — Reverse-chronological ordering.

  Output schema updated to show "Action + Tier1Keyword + Metric/Scope"
  in bullet type comments (reinforces the formula).

## Integration
`seniority_level` flows into section prompts automatically via the existing
`json.dumps(job_details)` passed as `job_description` — no changes to
`__init__.py` required.

## Verified
All 9 templates smoke-tested. Literal constraint validated (rejects
"invalid" seniority value). JobDetails instantiates with seniority_level=senior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P1-ATS] Implement causal chain bullet rewriting (Action + Skill + Metric)

1 participant