Spaces:
Sleeping
Sleeping
File size: 11,375 Bytes
8155d78 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | #!/usr/bin/env python3
"""Deterministic regression for Phase 08-02: Non-destructive tailoring (R17).
It MUST be impossible for this script to pass while the candidate's real history
can be altered. It proves:
1. STATIC: every bullet-mutation call site in resume_customizer.py
(_weave_keywords_into_bullets / _force_weave_into_bullets) is gated by
`non_destructive`, and _maximize_external_coverage takes a non_destructive
parameter. (Adding a new unguarded mutation site fails this.)
2. END-TO-END: _generate_resume_v4 run with a destructive no-LLM stub provider
and _maximum_ats_mode=True yields a DOCX whose role titles, companies,
dates, and EXISTING bullets are byte-identical to the base resume, the
destructive LLM output is discarded, and no fabrication term appears.
3. UNIT: _apply_non_destructive preserves roles verbatim, appends <=3 bullets
per role, and never appends a fabrication-risk term (cissp/pmp/cuda).
4. LATEX: inject_keywords appends new \\item lines (no in-place edits), keeps
one competencies line + a summary sentence, and is idempotent.
No real LLM, no LaTeX engine, no network. ASCII-only output. Exit 0 on success.
"""
import os
import re
import sys
import tempfile
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if REPO_ROOT not in sys.path:
sys.path.insert(0, REPO_ROOT)
CUST_PATH = os.path.join(REPO_ROOT, "src", "resume_customizer.py")
_failures = []
def check(condition, message):
if condition:
print(f" [PASS] {message}")
else:
print(f" [FAIL] {message}")
_failures.append(message)
# ββ 1. STATIC call-site guard check βββββββββββββββββββββββββββββββββββββββββ
def test_static_guards():
print("[1] Static: all bullet-mutation call sites gated by non_destructive")
src = open(CUST_PATH, encoding="utf-8").read()
check("NON_DESTRUCTIVE_DEFAULT" in src and "_apply_non_destructive" in src
and "_append_keyword_bullets" in src,
"non-destructive mode + append helpers present")
check(bool(re.search(r"def _maximize_external_coverage\([^)]*non_destructive",
src, re.S)),
"_maximize_external_coverage takes a non_destructive parameter")
calls = [m.start()
for c in ("_weave_keywords_into_bullets(", "_force_weave_into_bullets(")
for m in re.finditer(re.escape(c), src)]
unguarded = [i for i in calls if "non_destructive" not in src[max(0, i - 400):i]]
check(not unguarded,
f"every weave/force-weave occurrence ({len(calls)}) is non_destructive-guarded")
# ββ 2. END-TO-END diff through the live max-ATS path ββββββββββββββββββββββββ
def _build_base_resume():
from src.resume_model import Resume, Role, Contact, Education
return Resume(
name="Jordan Tester",
contact=Contact(email="jordan@example.com", phone="555-0100",
location="Hyderabad, Telangana, India"),
summary="Product manager with delivery experience across teams.",
skills=[],
roles=[
Role(title="Senior Product Manager", company="Acme Qwerty Labs",
location="Remote", dates="Jan 2021 - Present",
bullets=[
"Spearheaded zylotron onboarding revamp lifting activation by forty percent.",
"Owned blorptastic pricing experiments across enterprise cohorts.",
"Led quibblefax vendor integration from scoping to launch.",
]),
Role(title="Associate Product Owner", company="Bumblewick Systems",
location="Pune", dates="Jun 2018 - Dec 2020",
bullets=[
"Drove frobnicator dashboard adoption to scale across regions.",
"Managed wuggle backlog and release cadence for two squads.",
"Shipped znorf analytics module improving retention.",
]),
],
education=[Education(degree="MBA", institution="Northwind Institute",
dates="2017")],
)
class _StubProvider:
"""No-LLM provider that RETURNS DESTRUCTIVE output (renamed titles + rewritten
bullets) to prove the pipeline discards it in non-destructive mode."""
name = "stub"
def __init__(self, destructive_dict):
self._d = destructive_dict
def tailor_resume(self, base_dict, jd, title, company, raw):
return self._d, "ok"
def test_end_to_end():
print("[2] End-to-end: _generate_resume_v4 (_maximum_ats_mode=True) preserves history")
from src.resume_customizer import ResumeCustomizer, _read_docx_text
base = _build_base_resume()
dd = base.to_dict()
dd["summary"] = "REWRITTENSUMMARY tailored pitch."
for i, r in enumerate(dd["roles"]):
r["title"] = f"RENAMEDTITLE{i} Chief Officer"
r["bullets"] = [f"REWRITTENBULLET{i}A delivered value",
f"REWRITTENBULLET{i}B drove growth"]
stub = _StubProvider(dd)
jd = ("We need product roadmap ownership, stakeholder management, and a/b "
"testing experience for a SaaS B2B product. Strong user research and "
"go-to-market skills required.")
tmp = tempfile.mkdtemp(prefix="nd_e2e_")
try:
cust = ResumeCustomizer(None, base.to_flat_text(), tmp)
fp = os.path.join(cust.output_dir, "out.docx")
job = {
"title": "Product Manager", "company": "Northwind",
"description": jd, "ats_keywords": "", "_raw_assessment": {},
"_maximum_ats_mode": True, "_confirmed_terms": [],
}
path = cust._generate_resume_v4(job, cfg=None, filepath=fp,
provider=stub, base_resume_override=base)
check(bool(path) and os.path.exists(path),
"generation returned a DOCX path")
if not path or not os.path.exists(path):
return
text = _read_docx_text(path)
low = text.lower()
# Titles / companies / dates verbatim.
for token in ("Senior Product Manager", "Associate Product Owner",
"Acme Qwerty Labs", "Bumblewick Systems"):
check(token in text, f"verbatim preserved: '{token}'")
check("2021" in text and "2018" in text, "employment dates preserved")
# Existing bullets verbatim (distinctive tokens).
for token in ("zylotron", "blorptastic", "quibblefax",
"frobnicator", "wuggle", "znorf"):
check(token in low, f"existing bullet token preserved: '{token}'")
# Destructive ROLE output discarded (renamed titles + rewritten bullets).
# NOTE: R17 PERMITS summary augmentation, so the tailored summary may
# legitimately differ β only role content must be preserved verbatim.
for bad in ("renamedtitle", "rewrittenbullet"):
check(bad not in low, f"destructive role output discarded: '{bad}'")
# No fabrication anywhere.
for fab in ("cissp", "pmp", "cuda", "12+ years"):
check(fab not in low, f"no fabrication term in export: '{fab}'")
finally:
import shutil
shutil.rmtree(tmp, ignore_errors=True)
# ββ 3. UNIT: _apply_non_destructive βββββββββββββββββββββββββββββββββββββββββ
def test_apply_non_destructive_unit():
print("[3] Unit: _apply_non_destructive preserves roles + caps appended bullets")
from src.resume_customizer import ResumeCustomizer
from src.resume_model import Resume
base = _build_base_resume()
# A 'destructive' tailored copy with renamed titles + rewritten bullets.
dd = base.to_dict()
for i, r in enumerate(dd["roles"]):
r["title"] = f"FAKE{i}"
r["bullets"] = [f"FAKEBULLET{i}"]
tailored = Resume.from_dict(dd)
tmp = tempfile.mkdtemp(prefix="nd_unit_")
try:
cust = ResumeCustomizer(None, base.to_flat_text(), tmp)
cust._apply_non_destructive(
tailored, base,
include_terms=["product roadmap", "stakeholder management",
"a/b testing", "cissp", "pmp", "cuda"],
jd_text="product roadmap stakeholder management a/b testing",
)
for ti, role in enumerate(tailored.roles):
bro = base.roles[ti]
check(role.title == bro.title and role.company == bro.company
and role.dates == bro.dates,
f"role {ti}: title/company/dates verbatim")
check(role.bullets[:len(bro.bullets)] == list(bro.bullets),
f"role {ti}: existing bullets verbatim")
extra = len(role.bullets) - len(bro.bullets)
check(0 <= extra <= 3, f"role {ti}: <=3 bullets appended ({extra})")
appended = " ".join(role.bullets[len(bro.bullets):]).lower()
for fab in ("cissp", "pmp", "cuda"):
check(fab not in appended,
f"role {ti}: no fabrication term appended ('{fab}')")
finally:
import shutil
shutil.rmtree(tmp, ignore_errors=True)
# ββ 4. LATEX preservation βββββββββββββββββββββββββββββββββββββββββββββββββββ
SAMPLE_LATEX = (
"\\documentclass{article}\n\\begin{document}\n"
"\\section*{Summary}\nExperienced PM.\n"
"\\section*{Experience}\n\\begin{itemize}\n"
"\\item Led onboarding discovery research.\n"
"\\item Shipped the v1 analytics module.\n"
"\\end{itemize}\n\\end{document}\n"
)
def test_latex_preservation():
print("[4] LaTeX: inject_keywords appends items, no in-place edits, idempotent")
from src.latex_resume import inject_keywords
terms = ["product strategy", "stakeholder management", "a/b testing",
"user research"]
out, inj = inject_keywords(SAMPLE_LATEX, terms)
check("Led onboarding discovery research." in out
and "Shipped the v1 analytics module." in out,
"existing \\item lines unchanged")
check("(applying" not in out, "no in-place '(applying X)' edits")
n = out.count("% ats-item")
check(1 <= n <= 3, f"1..3 appended \\item lines ({n})")
check(out.count("\\textbf{Core Competencies:}") <= 1,
"at most one competencies line")
check("core focus areas include" in out.lower(), "summary sentence present")
out2, _ = inject_keywords(out, terms)
check(out2.count("% ats-item") == n, "idempotent (re-run does not stack items)")
def main():
print("=" * 70)
print("Phase 08-02 verification: Non-destructive tailoring (R17)")
print("=" * 70)
test_static_guards()
test_end_to_end()
test_apply_non_destructive_unit()
test_latex_preservation()
print("-" * 70)
if _failures:
print(f"FAIL - {len(_failures)} check(s) failed:")
for f in _failures:
print(f" - {f}")
return 1
print("PASS - tailoring is non-destructive end-to-end (history preserved, "
"keywords appended, honesty intact)")
return 0
if __name__ == "__main__":
sys.exit(main())
|