rohitsar567 Claude Opus 4.7 (1M context) commited on
Commit
28f795b
·
1 Parent(s): 7d021cf

fix(fact-find): KI-067 — recognize "first policy" / "new to insurance" as zero existing cover

Browse files

User screenshot: bot asked "Already have any health insurance ...?", user
replied "This is my first policy.", bot rejected with "Sorry, I didn't
catch that. Let me ask again —". User had to repeat as "No, this is my
first policy." to make it through.

Root cause: `_parse_existing_cover()` only matched the negative-word path
(`no|none|haven't|don't|...`) but not the semantically-equivalent
first-time-buyer phrasings that are common in natural speech.

Fix: added a second pattern bank to the function. Recognises any of:
- first policy / first insurance / first one / first time / first buy
- buying my first
- new to insurance / new to health insurance
- never bought/had/got/taken
- haven't bought/had/got/taken
- don't have any / a policy / insurance / cover

Also added bare "never" to the original negative-word pattern.

Verified 17/17 inline cases (8 new first-time variants + 9 existing
positive + negative cases). No regression on numeric amount parsing
("5 lakhs" / "₹5L" / "30k" / "30000" all still resolve correctly).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. backend/fact_find_normalizer.py +19 -2
backend/fact_find_normalizer.py CHANGED
@@ -264,10 +264,27 @@ def _parse_int(text: str, schema: dict) -> int | None:
264
 
265
 
266
  def _parse_existing_cover(text: str) -> int | None:
267
- """Handle "no" / "none" / "5 lakh" / "₹500000" / "5L" / "haven't got any" / "30k"."""
 
 
 
 
 
 
268
  s = text.lower().strip()
269
  # Negative answers map to 0 (no existing cover).
270
- if re.search(r"\b(no|none|nothing|zero|nope|nah|haven'?t|don'?t)\b", s):
 
 
 
 
 
 
 
 
 
 
 
271
  return 0
272
 
273
  # Look for a number followed by a unit suffix (digit-attached OR separated).
 
264
 
265
 
266
  def _parse_existing_cover(text: str) -> int | None:
267
+ """Handle "no" / "none" / "5 lakh" / "₹500000" / "5L" / "haven't got any" / "30k".
268
+
269
+ KI-067 (2026-05-15) — also recognises first-time-buyer phrasings
270
+ ("first policy", "first time buying", "new to insurance"). The previous
271
+ pattern caught "No, this is my first policy" via the "no" word but
272
+ rejected "This is my first policy" alone — user had to retry.
273
+ """
274
  s = text.lower().strip()
275
  # Negative answers map to 0 (no existing cover).
276
+ if re.search(r"\b(no|none|nothing|zero|nope|nah|haven'?t|don'?t|never)\b", s):
277
+ return 0
278
+ # KI-067 — first-time-buyer signals also imply zero existing cover.
279
+ _first_time_patterns = (
280
+ r"first\s+(?:policy|insurance|one|time|buy|cover)",
281
+ r"buying\s+(?:my\s+)?first",
282
+ r"new\s+(?:to\s+)?(?:health\s+)?insurance",
283
+ r"never\s+(?:bought|had|got|taken)",
284
+ r"haven'?t\s+(?:bought|had|got|taken)",
285
+ r"don'?t\s+have\s+(?:any|insurance|cover|a\s+policy)",
286
+ )
287
+ if any(re.search(p, s) for p in _first_time_patterns):
288
  return 0
289
 
290
  # Look for a number followed by a unit suffix (digit-attached OR separated).