Repository navigation
fix: harden requirement extraction and rescore visibility - #15
Merged
Merged
Conversation
Extraction hygiene, all deterministic and scoring-neutral by construction: - Technology extraction order is now stable. Map.copyOf salts its iteration order per JVM run, so identical text produced differently ordered technology lists and ExtractedRequirements record equality was unstable across runs. Nothing depended on that while rescore membership compared scores only. - REST is extracted only from qualified evidence: the API/service/endpoint/ controller forms, RESTful, JAX-RS, Spring REST, the technical shorthands HTTP/REST, REST/JSON and APIs (REST), after an explicit technical introducer, and as a complete item in a delimited technology list. The list delimiter is never a bare space, which is what keeps "Rest Assured" and "the rest of the stack" negative. - Go is extracted only from unambiguous spellings or from a delimited language list with a recognised neighbour that terminates as a list item, so ordinary English "go" no longer counts as evidence. - SpringBoot and Spring-Boot canonicalise to Spring Boot; JVM becomes its own canonical term, in no skill list and not a programming language. - Postgres -> PostgreSQL stays deliberately deferred to the scoring redesign, pinned by a regression test, because PostgreSQL is an equally weighted backend skill today. Rescore preview visibility: - Plan membership follows either persisted projection, not the score alone. The write transaction already re-persisted requirements whenever they differed, so requirement-only drift was being written without ever appearing in a preview. - The preview reports scoreChanged, requirementsChanged, requirementsOnly, changedPlan and unchanged counts, and names every differing ExtractedRequirements field with sanitized, bounded old and new values. Raw values are compared before any display conversion, so two values that share a truncated prefix cannot be reported as equal. - ScoreRescorePlan asserts its entry count against the report, so a write can never touch a row the preview did not account for. Fingerprint, locking and the existing guards are unchanged. Focused regression tests cover every REST and Go case, the aliases, the deferral, the 15-field requirement diff and the plan/report invariants. No scoring weights, bands, blockers, screening, workflow, Mini App ranking, schema or configuration were changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ExtractedRequirementsfield visible before WRITE.Production evidence
core_recovery_rows = 0), so this PR is extraction fidelity only and changes no scoring weight.OO, MVC, REST,HTTP/REST,REST/JSON,APIs (REST). Those are now retained.Rest Assuredrows andthe rest of the stackremain negative, including theSelenium, Cucumber, BDD, Rest Assured and CI/CDtools list — the list delimiter never matches a bare space, soRestfollowed by a word is never a list item.Verification
DeterministicRequirementExtractorTest: 114 passedcom.jobpilot.matching.**: 55 passed in the final focused runJobProcessorTest,ManualJobUrlServiceTest,LeverJobSourceTest,ResumeTruthValidatorTest,ResumeGenerationServiceTest,EligibilityConfigurationTest,BrowserFallbackServiceTest)git diff --checkcleanImportant operational note
TECHNOLOGIESordering normalization: extraction order was previously salted per JVM run (Map.copyOf), and is now stable. Sets are unchanged on those rows; only the order is.EXPECTED_CHANGED_COUNTmust come only from the fresh post-merge production preview, never from a design estimate.docs/scoring-calibration-analysis.mdA1.4) now enters the plan as requirement-only changes and will render asSENIORITY="JUNIOR"->"UNKNOWN". It must be reviewed and accepted explicitly before WRITE — it is the majority of the write and is unrelated to extractor hygiene.Out of scope — unchanged
Scoring weights, bands, blockers, penalties, screening, workflow, MATCH-first Mini App ranking, Telegram, ingestion adapters, database schema, migrations, production configuration.
ScoreRescorePlanFingerprintis untouched; fingerprint, row locking and all existing write guards keep their semantics.🤖 Generated with Claude Code