Skip to content

fix: doctor, search, and CV fixes found auditing real job offers - #56

Merged
DeibyGS merged 6 commits into
mainfrom
fix/cc-workflow-audit-fixes
Aug 13, 2026
Merged

fix: doctor, search, and CV fixes found auditing real job offers#56
DeibyGS merged 6 commits into
mainfrom
fix/cc-workflow-audit-fixes

Conversation

@DeibyGS

@DeibyGS DeibyGS commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Chain Context

  • Position: PR 1/2
  • Depends on: none (bases off main)
  • Followed by: PR 2 (branch fix/cc-doctor-search-cv-fixes) — JSON empty-results contract fix across 7 commands, and accent-insensitive company matching
  • Scope: doctor health check, search/add company matching, CV filename + PDF page validation, cv review-blind rubric

Summary

This is PR 1 of 2 stacked PRs (chained via /chained-pr, split because the combined diff exceeded the 500-line budget). PR 2 (branch fix/cc-doctor-search-cv-fixes) is stacked on top of this one and depends on it.

Six commits, all bugs found by actually using applyr end-to-end against real job offers (registering offers, generating CVs, running review-blind) rather than by reading the code:

  1. fix(doctor): distinguish forward-compat schema warning from a real issue — doctor never checked schema version at all; the only signal was a bare stderr line from init_db() on every OTHER command, disconnected from doctor's structured report. Added a proper "note" (not "issue") check to _check_database().
  2. fix(search): add --company exact match to align with add's duplicate check — search (LIKE substring) and add's duplicate detection (exact match) disagreed on what counts as "the same company." Added search --company <name> as an exact-match mode reusing the same find_company_offers() add already uses, and updated AGENT_INSTRUCTIONS.md Step 2 to use it.
  3. docs: clarify cv review-blind scope is document quality, not fit — review-blind's ATS SCORE could read like a second fit opinion when it's actually a document-quality check; fit is Step 3 (Matcher/add). Docs-only.
  4. fix(cv): company-only filenames and PDF 1-page ATS validation — generated CV filenames included the full job title (truncated to 40 chars, e.g. cv-acm-innovacion-y-personas-desarrollador.md); now company-only (cv-acm.md), with automatic id-suffix disambiguation if a second offer at the same company would collide. Also added a page-count check after cv pdf generation (regex over raw PDF bytes, no new dependency) that warns when the ATS 1-2 page rule is exceeded.
  5. fix(cv): stop scoring cv review-blind against finished-CV criteria — review-blind reads cv-master.md BEFORE any CV is tailored for the offer (Step 5 runs ahead of Step 6), but reused the same rubric as the finished-CV review, including "ATS Format Compliance" and "Length & Relevance" (1-2 pages) — criteria a multi-role master profile will always fail before it's even been trimmed. Split into a dedicated blind-review rubric without those two criteria.
  6. test: fix contradictory/collision-prone assertions in new tests — two of the new tests above had bugs of their own (a self-contradictory assertion in the doctor test, and a fixture value that coincidentally collided with new rubric text in the review-blind test).

Verified locally: 561 tests pass on this branch (python3 -m pytest -q).

Verification

  • Tests: 561/561 ✅
  • Docs updated: AGENT_INSTRUCTIONS.md
  • Budget: 327 lines (under 500)

Checklist

  • Branch follows naming convention (fix/cc-workflow-audit-fixes)
  • Commits are work-unit based (tests+code together)
  • No secrets or .env committed
  • Docs updated (AGENT_INSTRUCTIONS.md clarification)

DeibyGS and others added 6 commits August 13, 2026 16:17
A newer DB schema than the installed applyr is forward-compatible, not
breakage, but doctor never reported it at all — the only signal was a
bare stderr line from init_db(), disconnected from the structured
health-check report and easy to misread as an actual problem.

Add a dedicated schema-version check to _check_database() that surfaces
as a labeled "note" (not an "issue"), so it doesn't fail the exit code
and reads clearly as informational.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…check

search and add disagreed on what counts as "the same company": add's
duplicate detection uses an exact, case-insensitive match
(find_company_offers), while search used a broad LIKE substring across
five fields. Following AGENT_INSTRUCTIONS.md Step 2's "check duplicates
via search" as written could miss or over-match relative to what add
actually blocks on.

Add `search --company <name>` as an exact-match mode reusing
find_company_offers, so the pre-add duplicate check now uses the same
definition add enforces. Plain `search <keyword>` keeps its LIKE-based
substring behavior — a fuzzy company match there risks false positives
on short names, which is why this wasn't fixed by loosening search
itself.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
review-blind's rubric scores the CV artifact (keywords, ATS format,
evidence, clarity, length) — the same axes cv review uses — not whether
the candidate fits the offer. That judgment already happens in Step 3
(add's Matcher topic scoring). Nothing in the workflow said this
explicitly, so the ATS SCORE read like a second fit opinion when it
isn't one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two independent fixes to the generated-CV pipeline:

- _make_slug() dropped the job title from generated filenames — a CV
  used to be named cv-<company>-<title>.md (e.g.
  cv-acm-innovacion-y-personas-desarrollador.md), truncated to 40 chars
  in a way that made the file hard to identify at a glance. Filenames
  are now cv-<company>.md. A second offer at the same company (a normal
  case per duplicates.py — applying to multiple roles at one company is
  not a duplicate) gets an automatic id suffix instead of colliding
  with or silently overwriting the first CV; regenerating the SAME
  offer's CV still hits the existing already_exists/--force guard.

- cv pdf never validated the "1 page (2 for 5+ years)" ATS rule that
  cv review already states in its rubric — generation always reported
  success regardless of length. Added a page count after generation
  (regex over raw PDF bytes, no new dependency — the project's stated
  philosophy is colorama as the only dependency) and a non-blocking
  warning when it exceeds the limit, derived from the offer's
  seniority_level (senior/lead/director allow 2 pages, else 1).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Found while auditing a real offer end-to-end: cv review-blind reads
cv-master.md fresh, BEFORE any CV is generated or trimmed for the
offer (Step 5 runs ahead of Step 6). It reused the same rubric as
cv review (which evaluates an already-tailored CV file), including
"ATS Format Compliance" and "Length & Relevance" (1-2 pages) — both
criteria that only make sense against a finished document. A master
profile spanning a full career history will always fail a page-count
check it was never meant to pass yet, dragging the score down
regardless of how strong the actual candidate material is.

Split into a dedicated _BLIND_REVIEW_RUBRIC / _BLIND_REVIEW_OUTPUT_FORMAT
that drops both finished-document criteria and reweights Keyword Match,
Evidence & Metrics and Clarity & Impact to 100%. cmd_cv_review (which
evaluates the tailored, generated CV) keeps the original rubric
unchanged — that's the right place for the page-count and ATS-format
checks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- test_doctor.py: the new schema-forward-compat test asserted both
  "note(s) to review" in out AND "note(s)" not in out — a contradiction
  that only passed by accident. Removed the wrong second assertion.
- test_cv_review_blind.py: the fixture's compatibility_pct (45)
  coincidentally matched the new blind rubric's "Keyword Match
  (weight: 45%)" line, making the blindness check fail on an
  unrelated string collision. Changed the fixture to 47, a value that
  can't coincide with a round rubric weight.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@DeibyGS
DeibyGS enabled auto-merge (squash) August 13, 2026 16:04
@DeibyGS
DeibyGS merged commit 3c88afc into main Aug 13, 2026
12 checks passed
@DeibyGS
DeibyGS deleted the fix/cc-workflow-audit-fixes branch August 13, 2026 16:05
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.

1 participant