Engine: signal-weighted India stack + cursorless pool + honest-card hardening
Boards (signal-weighted, ~150/sweep): - Add TimesJobs (shahidirfan) — richest board: skills+salary+experience+offsite. Build/normalize + register; legacy city alias (New Delhi→Delhi, Bengaluru→Bangalore, Gurugram→Gurgaon) — verified live it returns 0 for "New Delhi", 35 for "Delhi". - Swap LinkedIn harvestapi → curious_coder (structured industry/jobFunction/applicants); harvestapi kept registered as linkedin_v1 fallback. - Drop Indeed from enabled (0% skills, redundant). Budgets: Foundit 40, TimesJobs 35, Naukri 30, LinkedIn 30, WorkIndia 15. Pool — cursorless freshness + safety: - REMOVE pagination/cursors: curious_coder only honors start=0 (start>0 → empty), proven; the rest are date feeds. Freshness now = boards' date-sort + the per-user seen-net + pool_save id-dedup. - Exhaustion guard: a refill adding < POOL_MIN_NEW_PER_REFILL new jobs flags the (user,query) exhausted → the gate relaxes the floor instead of block-fetching dupes (makes the 100/90 floor safe on niche queries). - Storage cap: pool_save trims beyond POOL_MAX_PER_QUERY freshest (kills DB swell). 72h TTL verified. - Thresholds 100/90 (deep pool, pay-for-volume). Scoring / cards: - Evidence-based fallback prose: when Haiku's cards stage gives nothing, the card uses Opus's REAL dimension notes (not a generic "Strong on X") + coverage logging + generic salvage parser. - "Skills & requirements" → "Skills fit" (consistent dimension labels). Bug fixes: - mark_seen dedups ids (was CardinalityViolationError on a duplicate id in one batch). Tests: deep stack contracts + committed board-sample fixture (no cache-pollution flakiness) + offline e2e + opt-in live e2e. 64 pass.
This commit is contained in:
@@ -1,26 +1,37 @@
|
||||
"""Warm-pool gate — the reorder/floor decision that keeps the shelf stocked without over-fetching."""
|
||||
from app.engine.search import pool_decision
|
||||
|
||||
FLOOR, REORDER = 70, 80 # the configured thresholds (POOL_SAFETY_FLOOR / POOL_REORDER_AT)
|
||||
FLOOR, REORDER = 90, 100 # the configured thresholds (POOL_SAFETY_FLOOR / POOL_REORDER_AT)
|
||||
|
||||
|
||||
def test_pool_healthy_serves_no_fetch():
|
||||
assert pool_decision(150, False, FLOOR, REORDER) == "pool"
|
||||
assert pool_decision(80, False, FLOOR, REORDER) == "pool" # exactly at reorder → still no fetch
|
||||
assert pool_decision(100, False, FLOOR, REORDER) == "pool" # exactly at reorder → still no fetch
|
||||
|
||||
|
||||
def test_pool_dipping_serves_plus_background_refill():
|
||||
assert pool_decision(79, False, FLOOR, REORDER) == "pool+refill" # below reorder → top up in bg
|
||||
assert pool_decision(70, False, FLOOR, REORDER) == "pool+refill" # at the floor → still serve, refill
|
||||
assert pool_decision(99, False, FLOOR, REORDER) == "pool+refill" # below reorder → top up in bg
|
||||
assert pool_decision(90, False, FLOOR, REORDER) == "pool+refill" # at the floor → still serve, refill
|
||||
|
||||
|
||||
def test_pool_below_floor_blocks_and_fetches():
|
||||
assert pool_decision(69, False, FLOOR, REORDER) == "sweep" # under the hard floor → blocking fetch
|
||||
assert pool_decision(89, False, FLOOR, REORDER) == "sweep" # under the hard floor → blocking fetch
|
||||
assert pool_decision(0, False, FLOOR, REORDER) == "sweep" # empty pool (first search) → fetch
|
||||
|
||||
|
||||
def test_forced_fresh_always_fetches():
|
||||
assert pool_decision(999, True, FLOOR, REORDER) == "sweep" # dev _fresh toggle bypasses the pool
|
||||
assert pool_decision(5, True, FLOOR, REORDER, exhausted=True) == "sweep" # force overrides exhaustion
|
||||
|
||||
|
||||
def test_exhausted_query_serves_instead_of_block_fetching():
|
||||
# tapped-out niche query below the floor: serve what's pooled, DON'T re-buy duplicates
|
||||
assert pool_decision(30, False, FLOOR, REORDER, exhausted=True) == "pool" # below floor but exhausted
|
||||
assert pool_decision(1, False, FLOOR, REORDER, exhausted=True) == "pool" # even 1 job → serve it
|
||||
# but an EMPTY exhausted pool must still try a fetch (nothing to serve)
|
||||
assert pool_decision(0, False, FLOOR, REORDER, exhausted=True) == "sweep"
|
||||
# exhaustion does NOT suppress the healthy/refill paths
|
||||
assert pool_decision(200, False, FLOOR, REORDER, exhausted=True) == "pool"
|
||||
|
||||
|
||||
def test_floor_never_above_reorder_invariant():
|
||||
|
||||
Reference in New Issue
Block a user