JAA-ATS-Tool / scripts /verify_skills_distribution.py
saitejatirunagari's picture
feat: LaTeX resume input + recruiter-grade keyword placement + resilient Run (Phase 7)
7759bfb
Raw
History Blame
5.25 kB
"""
Deterministic regression for the recruiter-grade SKILLS section (Phase 7, R14).
Locks in the renderer fix: the DOCX SKILLS block must read like a real skills
list β€” AT MOST one labelled line per category, NO repeated "Core Competencies:"
headers, and a recruiter-credible 18-28 total de-duplicated items β€” instead of
the ~12 identical "Core Competencies:" dump lines the old PER_LINE=12 chunking
produced. No LLM, no network: builds a Resume directly and renders it.
"""
import os
import sys
import io
import shutil
import tempfile
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
sys.path.insert(0, os.path.abspath("."))
from docx import Document
from src.resume_model import Resume, Contact, Role, Education
from src.resume_renderer import render_resume_docx
ok = True
def check(name, cond, detail=""):
global ok
ok = ok and cond
print(f" [{'PASS' if cond else 'FAIL'}] {name} {detail}")
# Known terms that land in dedicated buckets (exercise multiple category lines).
TOOLS = ["Jira", "Confluence", "Figma", "Mixpanel", "Amplitude", "SQL"]
METHODS = ["Agile", "Scrum", "Kanban", "Experimentation", "Prioritization"]
DOMAINS = ["FinTech", "SaaS", "B2B", "Payments"]
# ~40 generic terms β€” none belong to Tools/Methods/Domains, so they all fall
# into "Core Competencies" and would (pre-fix) overflow into repeated headers.
CORE = [
"Stakeholder Communication", "Cross-functional Leadership", "Team Mentorship",
"Strategic Planning", "Problem Solving", "Executive Reporting", "Vision Setting",
"Customer Empathy", "Negotiation", "Presentation Skills", "Decision Making",
"Conflict Resolution", "Time Management", "Budgeting", "Vendor Management",
"Change Management", "Risk Management", "Quality Assurance", "Process Improvement",
"Documentation", "Requirements Gathering", "Wireframing", "Storytelling",
"Public Speaking", "Coaching", "Hiring", "Onboarding", "Cross-team Collaboration",
"Prioritisation Frameworks", "Financial Modeling", "Forecasting", "Pricing Strategy",
"Partnerships", "Customer Success", "Account Management", "Technical Writing",
"Localization", "Accessibility", "Internationalization", "Compliance Reporting",
]
SKILLS = TOOLS + METHODS + DOMAINS + CORE # ~55 mixed terms
resume = Resume(
name="Jordan Avery",
contact=Contact(phone="+1 555 0100", email="jordan.avery@example.com",
location="Austin, TX, USA"),
summary=("Strong-fit candidate for Senior Product Manager: 6+ years shipping "
"B2B SaaS products. Drives roadmap, discovery, and cross-functional "
"delivery with measurable revenue impact."),
skills=SKILLS,
roles=[
Role(title="Senior Product Manager", company="Acme Corp", location="Austin, TX",
dates="Jan 2022 – Present",
bullets=["Led discovery and roadmap for a payments platform serving 2M users.",
"Drove a 30% lift in activation via experimentation and analytics.",
"Partnered with engineering and design across three squads."]),
Role(title="Product Manager", company="Globex", location="Remote",
dates="Jun 2019 – Dec 2021",
bullets=["Owned the B2B onboarding funnel; cut time-to-value by 40%.",
"Shipped 12 features against a quarterly OKR cadence.",
"Built stakeholder alignment across sales and support."]),
],
education=[Education(degree="B.S. β€” Computer Science", institution="UT Austin",
dates="2015 – 2019")],
)
CATEGORIES = ["Tools & Analytics:", "Methodologies:", "Domains:", "Core Competencies:"]
tmpdir = tempfile.mkdtemp(prefix="skills_dist_")
docx_path = os.path.join(tmpdir, "skills_test.docx")
try:
render_resume_docx(resume, docx_path)
doc = Document(docx_path)
paras = [p.text.strip() for p in doc.paragraphs if p.text and p.text.strip()]
# Count category-label occurrences and tally rendered skill items.
label_counts = {c: 0 for c in CATEGORIES}
total_items = 0
for text in paras:
for label in CATEGORIES:
if text.startswith(label):
label_counts[label] += 1
body = text[len(label):].strip()
items = [x for x in (s.strip() for s in body.split(",")) if x]
total_items += len(items)
break
check("'Core Competencies:' appears at most once (no repeated headers)",
label_counts["Core Competencies:"] <= 1,
f"count={label_counts['Core Competencies:']}")
repeated = {c: n for c, n in label_counts.items() if n > 1}
check("no category label appears more than once",
not repeated, f"repeated={repeated}")
check("at least one category line rendered",
sum(label_counts.values()) >= 1, f"labels={label_counts}")
check("total rendered skill items within 18-28 inclusive",
18 <= total_items <= 28, f"total_items={total_items}")
print("\n" + ("\u2713 SKILLS-DISTRIBUTION REGRESSION PASSES" if ok
else "\u2717 SOME CHECKS FAILED"))
finally:
shutil.rmtree(tmpdir, ignore_errors=True)
sys.exit(0 if ok else 1)