Claude Code Claude Opus 4.7 (1M context) commited on
Commit
f266901
·
1 Parent(s): 61980e6

fix(pricing+scoring): rebuild premium engine to 0 logical violations + classification, faithfulness, links, writing

Browse files

Pricing: rebuilt sample→premium as median-of-normalized-bases (monotone by construction) + real-fact product-type classifier + age-bucket-key fix + type-aware abs/low caps + P7 capped vs cheapest real comprehensive + Sanjeevani rel-cap. Exhaustive harness 3,316→0 (P1-P8=0, 104,760 checks); 5 monotonicity + 4 strict all-148 seeds clean. Deep-research harvest (6 agents, integrity-gated): 93/148 now real-quote-anchored, rest type×profile-modelled w/ honest provenance labels.

Classification: fixed Health Guard/Star Assure (voluntary-deductible comprehensive mislabelled topup → ded≥₹2L threshold), Criti Care/Medicare→disease, Energy→comprehensive, Health Protector Plus→topup.

Scoring: parity-by-construction (_scorecard_signal mirrors marketplace doctype-rank + merge); harness S3=0, test_scorecard_parity green. Reviews source-map + 148 confirm. Weighted-avg math audited PASS.

Faithfulness: _verify_prose_grounding — UINs in reply prose must be retrieved-grounded (faithfulness_passed now computed, was hard-True).

Links: 17 /70-docs/ path-mangled URLs restored + citation local-PDF fallback.

Writing: 8 P1s (verified-overclaim, raw-error leak, additive prompt bullet rule).

Docs: 70-docs/80-audit/{premium-source-map,premium-dependency-map,reviews-source-map}.md.

Known scoped follow-up: 11/148 alias/merged-card grade-parity edges (agreed oracle + parity test pass; single-source refactor documented).

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

40-data/corpus_urls.md CHANGED
@@ -48,15 +48,15 @@
48
  | care-health | Care Health Insurance | Care Advantage | brochure | https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)---brochure.pdf | base brochure |
49
  | care-health | Care Health Insurance | Care Advantage + add-ons (Protect Plus + Care Shield) | brochure | https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-with-add-on-protect-plus-&-care-shield-brochure.pdf | combo brochure |
50
  | care-health | Care Health Insurance | Care Heart | brochure | https://cms.careinsurance.com/cms/public/uploads/download_center/care-heart---piano-fold-brochure---web.pdf | cardiac-specific |
51
- | icici-lombard | ICICI Lombard | Complete Health Insurance (Health Shield) | wordings | https://www.icicilombard.com/70-docs/default-source/policy-wordings-product-brochure/complete-health-insurance-(health-shield).pdf | retail comprehensive |
52
- | icici-lombard | ICICI Lombard | Complete Health Insurance (umbrella) | wordings | https://www.icicilombard.com/70-docs/default-source/default-document-library/icihlip23144v072223-icici-lombard-complete-health-insurance.pdf | umbrella PW |
53
- | icici-lombard | ICICI Lombard | Health Shield 360 Retail | wordings | https://www.icicilombard.com/70-docs/default-source/default-document-library/health-shield-360-retail_pw.pdf | 360 retail |
54
- | icici-lombard | ICICI Lombard | Health Shield 360 Retail | cis | https://www.icicilombard.com/70-docs/default-source/policy-wordings-product-brochure/health-shield-360-retail---cis.pdf | CIS |
55
- | icici-lombard | ICICI Lombard | Health Booster (top-up) | wordings | https://www.icicilombard.com/70-docs/default-source/default-document-library/health-booster_policy-wordings.pdf | top-up |
56
- | icici-lombard | ICICI Lombard | Health AdvantEdge | wordings | https://www.icicilombard.com/70-docs/default-source/apps/healthclientapp/assets/pdf/health-advantedge-policy-wordings.pdf | wellness-led product |
57
- | icici-lombard | ICICI Lombard | Elevate | wordings | https://www.icicilombard.com/70-docs/default-source/apps/elevateapp/assets/pdf/elevate-policy-wordings.pdf | premium tier |
58
- | icici-lombard | ICICI Lombard | Health Elite Plus | wordings | https://www.icicilombard.com/70-docs/default-source/policy-wordings-product-brochure/complete-health-insurance-(health-elite-plus).pdf | elite plus tier |
59
- | icici-lombard | ICICI Lombard | Arogya Sanjeevani | wordings | https://www.icicilombard.com/70-docs/default-source/policy-wordings-product-brochure/arogya-sanjeevani-policy-policy-wordings.pdf | IRDAI standard product |
60
  | bajaj-allianz | Bajaj Allianz | Health Guard | wordings | https://www.bajajallianz.com/download-documents/health-insurance/health-guard/Health-Guard-Policy-Wordings-print.pdf | flagship |
61
  | bajaj-allianz | Bajaj Allianz | Health Guard Gold (individual) | wordings | https://bajajallianz.com/download-documents/health-insurance/health-guard-individual-policy/HG_Gold_Policy_Wording_&_CIS.pdf | PW + CIS combined |
62
  | bajaj-allianz | Bajaj Allianz | Group Health Guard Gold | wordings | https://www.bajajallianz.com/download-documents/health-insurance/health-guard-group/Group-HG-Gold-Policy-Wordings.pdf | group |
@@ -68,14 +68,14 @@
68
  | bajaj-allianz | Bajaj Allianz | Silver Health | cis | https://www.bajajallianz.com/download-documents/health-insurance/silver-health/silver_health_CIS.pdf | senior citizens (CIS only found) |
69
  | bajaj-allianz | Bajaj Allianz | Tax Gain | cis | https://www.bajajallianz.com/download-documents/health-insurance/tax-gain/tax_gain_CIS.pdf | tax-saver plan |
70
  | bajaj-allianz | Bajaj Allianz | Group Personal Accident | wordings | https://www.bajajallianz.com/download-documents/health-insurance/GROUP-PERSONAL-ACCIDENT-Policy-Wordings.pdf | PA |
71
- | new-india | New India Assurance | New India Mediclaim Policy | wordings | https://www.newindia.co.in/assets/70-docs/know-more/health/new-india-mediclaim-policy/PolicyClauseNewIndiaMediclaimPolicy(NIAHLIP23187V052223).pdf | flagship retail mediclaim |
72
- | new-india | New India Assurance | New India Mediclaim Policy | brochure | https://www.newindia.co.in/assets/70-docs/know-more/health/new-india-mediclaim-policy/Prospectus%20New%20India%20Mediclaim%20Policy.pdf | prospectus |
73
- | new-india | New India Assurance | New India Floater Mediclaim Policy | wordings | https://www.newindia.co.in/assets/70-docs/know-more/health/floater-mediclaim-policy/Policy%20Clause%20New%20India%20Floater%20Mediclaim%20Policy%20wef%2001%2010%202024.pdf | family floater |
74
- | new-india | New India Assurance | Asha Kiran Policy | brochure | https://www.newindia.co.in/assets/70-docs/know-more/health/asha-kiran-policy/Prospectus%20New%20India%20Asha%20Kiran%20Policy%20wef%2001%2004%202021.pdf | women+family hybrid; prospectus |
75
- | new-india | New India Assurance | Asha Kiran Policy | cis | http://www.newindia.co.in/assets/70-docs/know-more/health/asha-kiran-policy/Customer%20Information%20Sheet%20NEW%20INDIA%20ASHA%20KIRAN%20POLICY.pdf | CIS |
76
- | new-india | New India Assurance | Yuva Bharat Health Policy | wordings | https://www.newindia.co.in/assets/70-docs/know-more/health/yuva-bharat-health-policy/Policy%20Clause%20Yuva%20Bharat%20Health%20Policy%20%20wef%2001%2010%202024_1.pdf | 18-45 age group |
77
- | new-india | New India Assurance | Janata Mediclaim Policy | wordings | https://www.newindia.co.in/assets/70-docs/know-more/health/janata-mediclaim-policy/Policy%20Clause%20Janata%20Mediclaim%20Policy.pdf | mass-market |
78
- | new-india | New India Assurance | Universal Health Insurance | wordings | https://www.newindia.co.in/assets/70-docs/know-more/health/universal-health-insurance/Policy%20Clause%20Universal%20Health%20Insurance%20Policy.pdf | govt-sponsored |
79
  | aditya-birla | Aditya Birla Health Insurance | Activ Health (individual) | wordings | https://www.adityabirlacapital.com/healthinsurance/assets/pdf/policy-wording-form.pdf | flagship; brand may have rebranded as Activ One |
80
  | aditya-birla | Aditya Birla Health Insurance | Group Activ Health | wordings | https://www.adityabirlacapital.com/healthinsurance/assets/pdf/new_updated_pdf/Group-Activ-Health-Policy-wordings.pdf | group, structurally similar |
81
  | aditya-birla | Aditya Birla Health Insurance | Activ Assure Diamond | wordings | https://www.adityabirlacapital.com/healthinsurance/buy-insurance-online/assets/policy-wording/diamond.pdf | mid-tier |
 
48
  | care-health | Care Health Insurance | Care Advantage | brochure | https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)---brochure.pdf | base brochure |
49
  | care-health | Care Health Insurance | Care Advantage + add-ons (Protect Plus + Care Shield) | brochure | https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-with-add-on-protect-plus-&-care-shield-brochure.pdf | combo brochure |
50
  | care-health | Care Health Insurance | Care Heart | brochure | https://cms.careinsurance.com/cms/public/uploads/download_center/care-heart---piano-fold-brochure---web.pdf | cardiac-specific |
51
+ | icici-lombard | ICICI Lombard | Complete Health Insurance (Health Shield) | wordings | https://www.icicilombard.com/docs/default-source/policy-wordings-product-brochure/complete-health-insurance-(health-shield).pdf | retail comprehensive; path restored 2026-05-18 — was: /70-docs/ (path-mangle, project rename artifact) |
52
+ | icici-lombard | ICICI Lombard | Complete Health Insurance (umbrella) | wordings | https://www.icicilombard.com/docs/default-source/default-document-library/icihlip23144v072223-icici-lombard-complete-health-insurance.pdf | umbrella PW; path restored 2026-05-18 — was: /70-docs/ |
53
+ | icici-lombard | ICICI Lombard | Health Shield 360 Retail | wordings | https://www.icicilombard.com/docs/default-source/default-document-library/health-shield-360-retail_pw.pdf | 360 retail; path restored 2026-05-18 — was: /70-docs/ |
54
+ | icici-lombard | ICICI Lombard | Health Shield 360 Retail | cis | https://www.icicilombard.com/docs/default-source/policy-wordings-product-brochure/health-shield-360-retail---cis.pdf | CIS; path restored 2026-05-18 — was: /70-docs/ |
55
+ | icici-lombard | ICICI Lombard | Health Booster (top-up) | wordings | https://www.icicilombard.com/docs/default-source/default-document-library/health-booster_policy-wordings.pdf | top-up; path restored 2026-05-18 — was: /70-docs/ |
56
+ | icici-lombard | ICICI Lombard | Health AdvantEdge | wordings | https://www.icicilombard.com/docs/default-source/apps/healthclientapp/assets/pdf/health-advantedge-policy-wordings.pdf | wellness-led product; path restored 2026-05-18 — was: /70-docs/ |
57
+ | icici-lombard | ICICI Lombard | Elevate | wordings | https://www.icicilombard.com/docs/default-source/apps/elevateapp/assets/pdf/elevate-policy-wordings.pdf | premium tier; path restored 2026-05-18 — was: /70-docs/ |
58
+ | icici-lombard | ICICI Lombard | Health Elite Plus | wordings | https://www.icicilombard.com/docs/default-source/policy-wordings-product-brochure/complete-health-insurance-(health-elite-plus).pdf | elite plus tier; path restored 2026-05-18 — was: /70-docs/ |
59
+ | icici-lombard | ICICI Lombard | Arogya Sanjeevani | wordings | https://www.icicilombard.com/docs/default-source/policy-wordings-product-brochure/arogya-sanjeevani-policy-policy-wordings.pdf | IRDAI standard product; path restored 2026-05-18 — was: /70-docs/ |
60
  | bajaj-allianz | Bajaj Allianz | Health Guard | wordings | https://www.bajajallianz.com/download-documents/health-insurance/health-guard/Health-Guard-Policy-Wordings-print.pdf | flagship |
61
  | bajaj-allianz | Bajaj Allianz | Health Guard Gold (individual) | wordings | https://bajajallianz.com/download-documents/health-insurance/health-guard-individual-policy/HG_Gold_Policy_Wording_&_CIS.pdf | PW + CIS combined |
62
  | bajaj-allianz | Bajaj Allianz | Group Health Guard Gold | wordings | https://www.bajajallianz.com/download-documents/health-insurance/health-guard-group/Group-HG-Gold-Policy-Wordings.pdf | group |
 
68
  | bajaj-allianz | Bajaj Allianz | Silver Health | cis | https://www.bajajallianz.com/download-documents/health-insurance/silver-health/silver_health_CIS.pdf | senior citizens (CIS only found) |
69
  | bajaj-allianz | Bajaj Allianz | Tax Gain | cis | https://www.bajajallianz.com/download-documents/health-insurance/tax-gain/tax_gain_CIS.pdf | tax-saver plan |
70
  | bajaj-allianz | Bajaj Allianz | Group Personal Accident | wordings | https://www.bajajallianz.com/download-documents/health-insurance/GROUP-PERSONAL-ACCIDENT-Policy-Wordings.pdf | PA |
71
+ | new-india | New India Assurance | New India Mediclaim Policy | wordings | https://www.newindia.co.in/assets/docs/know-more/health/new-india-mediclaim-policy/PolicyClauseNewIndiaMediclaimPolicy(NIAHLIP23187V052223).pdf | flagship retail mediclaim; path restored 2026-05-18 — was: /assets/70-docs/ (served HTML error page) |
72
+ | new-india | New India Assurance | New India Mediclaim Policy | brochure | https://www.newindia.co.in/assets/docs/know-more/health/new-india-mediclaim-policy/Prospectus%20New%20India%20Mediclaim%20Policy.pdf | prospectus; path restored 2026-05-18 — was: /assets/70-docs/ |
73
+ | new-india | New India Assurance | New India Floater Mediclaim Policy | wordings | https://www.newindia.co.in/assets/docs/know-more/health/floater-mediclaim-policy/Policy%20Clause%20New%20India%20Floater%20Mediclaim%20Policy%20wef%2001%2010%202024.pdf | family floater; path restored 2026-05-18 — was: /assets/70-docs/ |
74
+ | new-india | New India Assurance | Asha Kiran Policy | brochure | https://www.newindia.co.in/assets/docs/know-more/health/asha-kiran-policy/Prospectus%20New%20India%20Asha%20Kiran%20Policy%20wef%2001%2004%202021.pdf | women+family hybrid; prospectus; path restored 2026-05-18 — was: /assets/70-docs/ |
75
+ | new-india | New India Assurance | Asha Kiran Policy | cis | https://www.newindia.co.in/assets/docs/know-more/health/asha-kiran-policy/Customer%20Information%20Sheet%20NEW%20INDIA%20ASHA%20KIRAN%20POLICY.pdf | CIS; path restored 2026-05-18 — was: http://.../assets/70-docs/ |
76
+ | new-india | New India Assurance | Yuva Bharat Health Policy | wordings | https://www.newindia.co.in/assets/docs/know-more/health/yuva-bharat-health-policy/Policy%20Clause%20Yuva%20Bharat%20Health%20Policy%20%20wef%2001%2010%202024_1.pdf | 18-45 age group; path restored 2026-05-18 — was: /assets/70-docs/ (served HTML error page) |
77
+ | new-india | New India Assurance | Janata Mediclaim Policy | wordings | https://www.newindia.co.in/assets/docs/know-more/health/janata-mediclaim-policy/Policy%20Clause%20Janata%20Mediclaim%20Policy.pdf | mass-market; path restored 2026-05-18 — was: /assets/70-docs/ |
78
+ | new-india | New India Assurance | Universal Health Insurance | wordings | https://www.newindia.co.in/assets/docs/know-more/health/universal-health-insurance/Policy%20Clause%20Universal%20Health%20Insurance%20Policy.pdf | govt-sponsored; path restored 2026-05-18 — was: /assets/70-docs/ |
79
  | aditya-birla | Aditya Birla Health Insurance | Activ Health (individual) | wordings | https://www.adityabirlacapital.com/healthinsurance/assets/pdf/policy-wording-form.pdf | flagship; brand may have rebranded as Activ One |
80
  | aditya-birla | Aditya Birla Health Insurance | Group Activ Health | wordings | https://www.adityabirlacapital.com/healthinsurance/assets/pdf/new_updated_pdf/Group-Activ-Health-Policy-wordings.pdf | group, structurally similar |
81
  | aditya-birla | Aditya Birla Health Insurance | Activ Assure Diamond | wordings | https://www.adityabirlacapital.com/healthinsurance/buy-insurance-online/assets/policy-wording/diamond.pdf | mid-tier |
40-data/premiums/illustrative_premiums.json CHANGED
The diff for this file is too large to render. See raw diff
 
70-docs/80-audit/premium-dependency-map.md ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Premium Dependency Map
2
+
3
+ | Field | Value |
4
+ | --- | --- |
5
+ | Document type | Dependency / change-cascade map (data + code) |
6
+ | Subject data file | `40-data/premiums/illustrative_premiums.json` |
7
+ | Generated (this doc) | 2026-05-18 |
8
+ | Companion | [`premium-source-map.md`](premium-source-map.md) (per-sample provenance) |
9
+ | Source of truth for chain | `backend/premium_calculator.py`, `backend/brain_tools.py`, `backend/main.py`, `backend/scorecard.py` |
10
+
11
+ ## 0. Purpose
12
+
13
+ This document is the **change-cascade contract for the premium pipeline**. It exists so a future edit to the curated JSON, a calculator helper, an API contract, or the reviews/scorecard parity surface does not silently break a downstream consumer.
14
+
15
+ Every node below names: **what it consumes**, **what depends on it**, and an explicit **"if you change X you must re-verify Y"** rule. Function and constant names are taken verbatim from the source files (read 2026-05-18); they are not paraphrased.
16
+
17
+ ## 1. The pricing chain (end to end)
18
+
19
+ ```
20
+ 40-data/premiums/illustrative_premiums.json
21
+ │ (base_premiums{}, scaling_factors{})
22
+
23
+ premium_calculator._load_data() [reads + json.loads the file; {} on any error]
24
+
25
+ premium_calculator._canonical_sample_key() [resolve recommended/marketplace id → base_premiums key]
26
+ │ ├─ _SAMPLE_DOCTYPE_SUFFIXES (__brochure/__cis/__wordings/__prospectus/__policy)
27
+ │ └─ _KNOWN_BAD_SAMPLE_KEYS (currently EMPTY frozenset — quarantine mechanism, retained)
28
+
29
+ premium_calculator._plausible_samples() [type-aware ₹/lakh sanity guard, via _per_lakh_band()]
30
+
31
+ premium_calculator._interpolate_from_samples() [nearest sample in (age, log SI) space]
32
+
33
+ premium_calculator.estimate() [#38 FULL ratio-normalization + OUTPUT plausibility ceiling]
34
+ │ └─ NO-sample path → _attribute_base_factor() (product-TYPE model; no JSON I/O)
35
+
36
+ premium_calculator.bulk_estimate() [calls estimate() per policy on the curated path;
37
+ │ flat ₹500/lakh × type-factor on the no-sample path]
38
+
39
+ premium_calculator.estimate_premium_band() [prices the 26-policy _DEFAULT_BAND_POLICY_IDS basket;
40
+ │ p25–p75 interquartile via resolve_profile_sum_insured()]
41
+
42
+ backend/main.py POST /api/premium/estimate (PremiumEstimateRequest → PremiumEstimateResponse)
43
+ POST /api/premium/bulk (PremiumBulkRequest → PremiumBulkResponse)
44
+ GET /api/profile/predicted-premium-band (→ PredictedPremiumBandResponse)
45
+
46
+ frontend/src/lib/api.ts postPremiumEstimate() / PremiumEstimateResponse
47
+
48
+ frontend/src/components/PolicyPremiumWidget.tsx (point + ±15% band + methodology line + SI disclosure)
49
+ └─ embedded in PolicyCompareModal.tsx; header chip in app/page.tsx (premiumBand state)
50
+ ```
51
+
52
+ Parallel, independent chain (claim-experience parity, **not** premium-priced):
53
+
54
+ ```
55
+ 40-data/reviews/<slug>.json
56
+
57
+ brain_tools._insurer_reviews(slug) [cached read; None if missing]
58
+
59
+ scorecard.score_claim_experience(p, insurer_reviews=…) [IRDAI CSR + complaints/10k → sub-score]
60
+
61
+ scorecard.build_scorecard(data, insurer_reviews=…, profile=…)
62
+ ├─ recommendation path: brain_tools._scorecard_signal() → cited-card grade
63
+ └─ marketplace path: main.py /api/policies/all → marketplace grade
64
+ ▼ PARITY INVARIANT (tests/test_scorecard_parity.py): cited-card GRADE LETTER == marketplace GRADE LETTER
65
+ ```
66
+
67
+ ## 2. Node-by-node dependency contract
68
+
69
+ ### 2.1 `40-data/premiums/illustrative_premiums.json`
70
+
71
+ - **Consumes:** nothing — it is the single source of truth. Top-level keys: `last_updated`, `methodology`, `sources_consulted`, `notes`, `base_premiums` (100 entries), `scaling_factors`, `link_rot_repairs`.
72
+ - **Depended on by:** `_load_data()` (the ONLY reader), and transitively everything below it. Also documented by [`premium-source-map.md`](premium-source-map.md).
73
+ - **Sample shape (post-harvest):** evidenced samples carry `age`, `sum_insured_inr`, `city_tier`, `smoker`, `family_size`, `annual_premium_inr`, `source_url`, `source_quote`, `source_quality`, `fetched_on` (+ optional `source_note`/`derivation_note`/`variant`). 194 evidenced samples across 73 entries; 27 entries are model-only.
74
+ - **If you change X you must re-verify Y:**
75
+ - Change/add a `samples[]` entry → re-run `_plausible_samples()` mentally against `_per_lakh_band()` for that policy type (comprehensive 250–6500/L; top-up 10–800/L; benefit plans unbounded). A sample outside the band is silently dropped, so the policy may regress to the model path.
76
+ - Change a `base_premiums` **key** → re-verify `_canonical_sample_key()` still resolves the marketplace/recommended id (suffix + single-hyphen forms) AND that the key appears in `_DEFAULT_BAND_POLICY_IDS` if it should be in the header basket.
77
+ - Change `scaling_factors` (age/SI/city/floater/smoker/PED multipliers) → re-verify the **#38 ratio-normalization** in `estimate()`: it divides the sample's own multipliers out and re-applies the user's, so a changed factor moves every curated-path estimate. Re-run `tests/test_premium_attribute_and_normalization.py` + `tests/test_premium_reconciliation.py`.
78
+ - Edit/add/remove any evidenced sample → **regenerate [`premium-source-map.md`](premium-source-map.md) §1 counts and §2/§3 tables in the same commit** (the JSON is the single source of truth for both docs).
79
+
80
+ ### 2.2 `premium_calculator._load_data()`
81
+
82
+ - **Consumes:** `PREMIUM_DATA` path (`settings.DATA_DIR / "premiums" / "illustrative_premiums.json"`).
83
+ - **Depended on by:** `estimate()`, `bulk_estimate()` (each call re-reads — no module cache).
84
+ - **If you change X:** moving/renaming the JSON, or breaking its JSON validity, makes `_load_data()` return `{}` **silently** → every policy falls to `FALLBACK_*` constants (no exception, no log). Re-verify by calling `estimate(policy_id=...)` for a known-curated policy and asserting `base_sample_used is not None`.
85
+
86
+ ### 2.3 `premium_calculator._canonical_sample_key()`
87
+
88
+ - **Consumes:** the incoming `policy_id`, `base_premiums` keys, `_SAMPLE_DOCTYPE_SUFFIXES`, `_KNOWN_BAD_SAMPLE_KEYS`.
89
+ - **Depended on by:** `estimate()` (sample lookup) **and** `bulk_estimate()` (the `if _canonical_sample_key(pid, …) is not None` branch decides curated-anchor vs flat-base). Both must agree or the widget and the per-policy panel diverge.
90
+ - **If you change X:** add a doctype suffix or change the hyphen-normalization → re-verify BOTH call sites resolve the same key (a mismatch reintroduces the ₹33,700 collision / the SBI Arogya Supreme double-floater bug). `_KNOWN_BAD_SAMPLE_KEYS` is currently the empty frozenset (SBI Arogya Supreme was unquarantined 2026-05-18 after its bad brochure-extract was physically replaced with real SBI rate-chart figures); to re-quarantine a proven-bad entry, add its key here AND note it in the source map.
91
+
92
+ ### 2.4 `premium_calculator._per_lakh_band()` / `_plausible_samples()`
93
+
94
+ - **Consumes:** `policy_id` substring (type detection), each sample's `sum_insured_inr` + `annual_premium_inr`.
95
+ - **Depended on by:** `estimate()` (input guard before interpolation) **and** the **OUTPUT plausibility ceiling** at the end of `estimate()` (ceiling = `_hi_b * 1.5`).
96
+ - **If you change X:** widening/narrowing a band → re-verify (a) no real evidenced sample is now dropped (would silently demote a policy to the model path) and (b) the output ceiling still trips only on genuinely broken data. The product-type substrings (`top-up`, `hospital-cash`, `cancer`, `critical-illness`, …) are matched against the lowercased `policy_id`; renaming a key can flip a plan between bands.
97
+
98
+ ### 2.5 `premium_calculator._attribute_base_factor()` — the no-sample path
99
+
100
+ - **Consumes:** `policy_id` substring only. No JSON I/O — deterministic on the id.
101
+ - **Depended on by:** `estimate()` (no-sample branch), `bulk_estimate()` (flat-base `flat_base = BULK_BASE_INR_PER_LAKH * si_lakhs * _attribute_base_factor(pid)`), and therefore every one of the **27 model-only entries** in the source map §3.
102
+ - **Returns:** super-top-up/top-up 0.35×, hospital-cash/fixed-benefit 0.30×, cancer/critical-illness 0.55×, `sanjeevani` 0.70×, comprehensive 1.0× (no regression for the dominant type).
103
+ - **If you change X:** changing a factor moves every model-only policy of that type AND the flat-base widget number. Re-verify against the type-band so a model-only estimate stays inside `_per_lakh_band()`; re-run `tests/test_premium_attribute_and_normalization.py`. **Provenance label:** model-path estimates carry the methodology string *"Indicative estimate modelled from this plan's product type … NOT a quote"* — if you ever anchor a model-only policy to a real sample, move it out of source-map §3 into §2 and the label flips to the *"Anchored to a verified public-quote sample"* variant automatically (driven by `sample_used is not None`).
104
+
105
+ ### 2.6 `premium_calculator.estimate()`
106
+
107
+ - **Consumes:** `_load_data()`, `_canonical_sample_key()`, `_plausible_samples()`, `_interpolate_from_samples()`, `scaling_factors`, the B6/D2/KI-275 loadings (`_health_loading`, `_existing_cover_loading`, `_parents_loading`, `_copay_discount`, `_family_history_loading`, `_copay_multiplier`).
108
+ - **Depended on by:** `bulk_estimate()` (curated path calls `estimate()` directly), `POST /api/premium/estimate`, and indirectly the header band (`estimate_premium_band → bulk_estimate → estimate`).
109
+ - **Two critical internal invariants:**
110
+ 1. **#38 full ratio-normalization** — the sample's own age/SI/city/family multipliers are divided out, then the user's profile is applied exactly once by the unconditional city/floater/smoker/PED block. Sample `family_size` is HEADCOUNT (1=individual); `estimate()`'s floater key is dependents-beyond-self (`max(0, headcount-1)`). Breaking this re-introduces double-counted floater (the SBI ₹149,800 bug).
111
+ 2. **OUTPUT plausibility ceiling** — if a sample-anchored point still exceeds `_per_lakh_band(...)[1] * 1.5` per lakh after normalization+loadings, it drops `sample_used`/`sources` and falls back to the policy-blind model base.
112
+ - **If you change X:** changing the loading order, the normalization, or the ceiling → re-run BOTH `tests/test_premium_reconciliation.py` and `tests/test_premium_attribute_and_normalization.py`; the header-band p25–p75 contract depends on `estimate()` being stable.
113
+
114
+ ### 2.7 `premium_calculator.bulk_estimate()` / `estimate_premium_band()`
115
+
116
+ - **Consumes:** `bulk_estimate()` calls `estimate()` on the curated path; `estimate_premium_band()` calls `bulk_estimate()` over `_DEFAULT_BAND_POLICY_IDS` (26 policies) and `resolve_profile_sum_insured()` for the shared SI.
117
+ - **Depended on by:** `POST /api/premium/bulk`, `GET /api/profile/predicted-premium-band`, the PolicyCompareModal widget, and the header "Premium range" chip.
118
+ - **SI contract (KI-278):** `resolve_profile_sum_insured()` precedence (`desired_sum_insured_inr ?? existing_cover_inr ?? ₹10L`, snapped to ₹50k) MUST stay byte-identical to `PremiumCalculatorPanel`'s slider seed (`frontend/src/app/page.tsx` ~L2417) and `PolicyPremiumWidget`'s `initialSumInsured`. The chip band is the **p25–p75 interquartile** of the basket, NOT raw min–max.
119
+ - **If you change X:**
120
+ - Add/remove a policy in `_DEFAULT_BAND_POLICY_IDS` → re-verify each id resolves via `_canonical_sample_key()` (else it silently uses the flat path) and re-check the chip band is still a sane range.
121
+ - Change the SI precedence on either side → change BOTH `resolve_profile_sum_insured()` and the page.tsx slider seed in the same commit, else header ≠ panel returns. Re-run `tests/test_premium_reconciliation.py`.
122
+
123
+ ### 2.8 API layer (`backend/main.py`)
124
+
125
+ - **Consumes:** `estimate`, `bulk_estimate`, `estimate_premium_band`, `unpublished_si_disclosure`, `_policy_corroborated_si`.
126
+ - **Depended on by:** `frontend/src/lib/api.ts` (`postPremiumEstimate`, `PremiumEstimateResponse` type), `PolicyPremiumWidget.tsx`, `PolicyCompareModal.tsx`, `app/page.tsx` (`premiumBand`).
127
+ - **Contract surfaces that must not drift:** `PremiumEstimateResponse.base_sample_used` (widget shows/hides its "Estimate" badge off this — it is `e.base_sample_used is not None`), `methodology` (rendered verbatim under the estimate), `sources` (the source URLs), `sum_insured_disclosure` (rendered verbatim only when `_policy_corroborated_si(...).kind == "none"`). `predicted-premium-band` feeds the profile dict via `brain_tools.SLOT_UNION` with the answered-only gate (`profile.asked`).
128
+ - **If you change X:** renaming/removing a response field → update `frontend/src/lib/api.ts` types + every `.tsx` consumer in the same commit. Changing `tenure_years`/`deductible_inr` snapping uses `BULK_TENURE_MULT`/`BULK_DEDUCTIBLE_DISCOUNT` from the calculator — keep them in sync.
129
+
130
+ ### 2.9 Reviews → scorecard claim-experience PARITY chain
131
+
132
+ - **Consumes:** `40-data/reviews/<slug>.json` → `brain_tools._insurer_reviews(slug)` (cached; `None` if missing) → `scorecard.score_claim_experience(p, insurer_reviews=…)` → `scorecard.build_scorecard(data, insurer_reviews=…, profile=…)`.
133
+ - **Two paths that MUST stay in parity:**
134
+ - **Recommendation / cited-card grade:** `brain_tools._scorecard_signal()` builds `data` via `_merge_curated(extracted, curated)` (KI-PARITY 2026-05-18 — curated-only made the cited grade systematically lower), resolves `slug`, passes `_insurer_reviews(slug)` into `build_scorecard`.
135
+ - **Marketplace grade:** `/api/policies/all` builds `build_scorecard` on the full curated+reviews layer.
136
+ - **PARITY INVARIANT:** the cited-card **grade letter** must equal the marketplace **grade letter** for the same policy. Locked by `tests/test_scorecard_parity.py` (overall scores may differ by a few points because the marketplace overlays `EXTRACTED_DIR`; the LETTER, which `_recommendation_fit` gates on, must match).
137
+ - **If you change X:**
138
+ - Edit a `40-data/reviews/<slug>.json` `claim_metrics` value → re-verify `score_claim_experience()` band thresholds (CSR ≥95 +20, ≥90 +12, ≥85 +5, ≥75 −6, else −20; complaints/10k ≤10 +8 … >45 −16) and re-run `tests/test_scorecard_parity.py` — a CSR/complaints change can flip the sub-score enough to move the grade letter, which must move identically on BOTH paths.
139
+ - Change `_scorecard_signal()`'s data assembly (`_merge_curated`, `_candidate_stems`, slug derivation) → re-run `tests/test_scorecard_parity.py`; divergence makes the recommendation path drop policies (empty `citations` → CitedPolicyCards never render).
140
+ - This chain is **independent of premium pricing** — it does NOT read `illustrative_premiums.json`. Document it here only because it shares the source-methodology + dependency-map treatment and the same `_insurer_reviews`/scorecard machinery.
141
+
142
+ ## 3. Quick "change X → re-verify Y" lookup
143
+
144
+ | If you change… | You must re-verify… | Tests / docs to re-run |
145
+ | --- | --- | --- |
146
+ | A `samples[]` entry / a premium figure | `_plausible_samples` band, `_interpolate_from_samples` nearest pick, `estimate()` #38 normalization | `test_premium_reconciliation.py`, `test_premium_attribute_and_normalization.py`, regenerate `premium-source-map.md` |
147
+ | A `base_premiums` key name | `_canonical_sample_key` both call sites, `_DEFAULT_BAND_POLICY_IDS` membership, `_per_lakh_band`/`_attribute_base_factor` substring match | `test_premium_reconciliation.py`, source map §2/§3 |
148
+ | `scaling_factors` multipliers | `estimate()` ratio-normalization output, header band | both premium tests |
149
+ | `_attribute_base_factor` | every model-only entry + flat-base widget, type-band sanity | `test_premium_attribute_and_normalization.py`, source map §3 |
150
+ | `resolve_profile_sum_insured` precedence | page.tsx slider seed byte-identity, header == panel | `test_premium_reconciliation.py` |
151
+ | A `PremiumEstimateResponse` field | `frontend/src/lib/api.ts` types, `PolicyPremiumWidget.tsx`, `PolicyCompareModal.tsx`, `page.tsx` | frontend typecheck/build |
152
+ | `_DEFAULT_BAND_POLICY_IDS` | each id resolves via `_canonical_sample_key`, chip band sanity | `test_premium_reconciliation.py` |
153
+ | `40-data/reviews/<slug>.json` claim_metrics | `score_claim_experience` thresholds, cited-grade == marketplace-grade | `test_scorecard_parity.py` |
154
+ | `_scorecard_signal` data assembly | parity invariant (grade letter both paths) | `test_scorecard_parity.py` |
155
+ | Move/rename/corrupt the JSON | `_load_data()` returns `{}` SILENTLY → all-fallback | manual `estimate()` smoke on a known-curated id |
156
+
157
+ ## 4. Regeneration
158
+
159
+ Both this map and [`premium-source-map.md`](premium-source-map.md) are derived from the same single source of truth (`40-data/premiums/illustrative_premiums.json`) plus the code chain above. After any premium-harvest or calculator-contract change, update the affected §2 node contract and the §3 lookup row in the **same commit** as the code/data change — the "if you change X you must re-verify Y" rules are only useful if they stay in lockstep with the chain.
70-docs/80-audit/premium-source-map.md ADDED
@@ -0,0 +1,690 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Premium Source Map
2
+
3
+ | Field | Value |
4
+ | --- | --- |
5
+ | Document type | Source-methodology catalog (data-provenance audit) |
6
+ | Subject data file | `40-data/premiums/illustrative_premiums.json` |
7
+ | `last_updated` (data file) | `2026-05-13` |
8
+ | Generated (this doc) | 2026-05-18 |
9
+ | Raw agent outputs | `/tmp/research_out_1.json` … `/tmp/research_out_6.json` |
10
+ | Companion | [`premium-dependency-map.md`](premium-dependency-map.md) |
11
+
12
+ ## 0. Purpose
13
+
14
+ This document is the **authoritative provenance catalog for every evidenced premium sample** the bot prices against. It is the premium-pricing analogue of [`70-docs/20-data-pipeline/information-source-map.md`](../../20-data-pipeline/information-source-map.md): for each `base_premiums` entry that carries at least one *evidenced* sample (a sample with a verbatim `source_quote` **and** a `fetched_on` timestamp from the 2026-05-18 premium harvest), every sample is listed with its profile, the figure it contributes, the specific source page, the trimmed verbatim quote, the source-quality tag, and the fetch date.
15
+
16
+ A reviewer can use this file to answer two questions:
17
+
18
+ 1. **"Is this premium number real?"** → look up the policy + profile row; the `source_quote` is the verbatim text the figure was read from.
19
+ 2. **"Which policies are still model-only?"** → §3 lists every entry with **zero** evidenced samples (priced by `_attribute_base_factor` type-model, never a fabricated quote).
20
+
21
+ This document does **not** modify the JSON — it is read-only documentation. The integrity gate in the harvest already rejected bare-homepage URLs and quotes lacking a number+profile; §4 independently re-verifies that none slipped through.
22
+
23
+ ## 1. Summary
24
+
25
+ | Metric | Value |
26
+ | --- | --- |
27
+ | Total `base_premiums` entries | 100 |
28
+ | Entries WITH ≥1 evidenced sample | 73 |
29
+ | Entries WITHOUT any evidenced sample (model-only) | 27 |
30
+ | Total evidenced samples | 194 |
31
+ | Distinct source domains | 22 |
32
+ | Samples sourced from an insurer-official PDF / rate-chart | 133 |
33
+ | Samples sourced from an aggregator / comparison site | 47 |
34
+ | Samples from other insurer-site HTML pages | 14 |
35
+ | Evidenced samples carrying a `source_quality` tag | 194 |
36
+
37
+ `source_quality` distribution: `insurer_site` × 152, `aggregator_quote` × 42.
38
+
39
+ Top source domains: `acko-cms.ackoassets.com` (27), `joinditto.in` (23), `cms.careinsurance.com` (18), `iffcotokio.co.in` (18), `newindia.co.in` (15), `probusinsurance.com` (14), `assets.ctfassets.net` (11), `nationalinsurance.nic.co.in` (11), `content.sbigeneral.in` (7), `godigit.com` (6), `tataaig.com` (6), `bajajgeneralinsurance.com` (5).
40
+
41
+ > **Provenance note.** `source_quality` is the harvester's own page-class tag (`insurer_site` = read off an insurer-owned page/PDF; `aggregator_quote` = read off a comparison portal). The *insurer-official-PDF* count above is computed independently here by URL heuristic (`.pdf` and not an aggregator host); the two need not match exactly because some insurer-site samples are HTML rate pages, not PDFs.
42
+
43
+ ## 2. Evidenced samples — grouped by insurer
44
+
45
+ Each row is one sample inside that policy's `samples[]`. `annual_premium_inr` is the figure the calculator anchors to (before profile normalization — see the dependency map). Quotes are trimmed to ≤160 chars; the untrimmed text is in the JSON.
46
+
47
+ ### Acko
48
+
49
+ **`acko__acko-health-ii`** · Acko Health Ii · UIN `ACKHLIP26036V012526`
50
+
51
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
52
+ | --- | --- | --- | --- | --- | --- |
53
+ | age 20 / 3L / tier2 / fs1 | ₹4,234 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,234 3,00,000 ... 21 - 25 6,306 3,00,000 ... 31 - 35 6,306 3,00,000 ... 36 - 40 7,742 3,00,000 ..… | `insurer_site` | 2026-05-18 |
54
+ | age 23 / 3L / tier2 / fs1 | ₹6,306 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,234 3,00,000 ... 21 - 25 6,306 3,00,000 ... 31 - 35 6,306 3,00,000 ... 36 - 40 7,742 3,00,000 ..… | `insurer_site` | 2026-05-18 |
55
+ | age 33 / 3L / tier2 / fs1 | ₹6,306 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,234 3,00,000 ... 21 - 25 6,306 3,00,000 ... 31 - 35 6,306 3,00,000 ... 36 - 40 7,742 3,00,000 ..… | `insurer_site` | 2026-05-18 |
56
+ | age 38 / 3L / tier2 / fs1 | ₹7,742 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,234 3,00,000 ... 21 - 25 6,306 3,00,000 ... 31 - 35 6,306 3,00,000 ... 36 - 40 7,742 3,00,000 ..… | `insurer_site` | 2026-05-18 |
57
+ | age 53 / 3L / tier2 / fs1 | ₹17,152 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,234 3,00,000 ... 21 - 25 6,306 3,00,000 ... 31 - 35 6,306 3,00,000 ... 36 - 40 7,742 3,00,000 ..… | `insurer_site` | 2026-05-18 |
58
+ | age 58 / 3L / tier2 / fs1 | ₹22,559 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,234 3,00,000 ... 21 - 25 6,306 3,00,000 ... 31 - 35 6,306 3,00,000 ... 36 - 40 7,742 3,00,000 ..… | `insurer_site` | 2026-05-18 |
59
+ | age 18 / 3L / metro / fs1 | ₹7,567 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Illustration 2 ... 16 - 20 7,567 3,00,000 ... 21 - 25 7,567 3,00,000 ... 41 - 45 11,357 3,00,000 ... 46 - 50 15,216 3,00,000 ... 71- 75 65,624 3,00,000 ... 7… | `insurer_site` | 2026-05-18 |
60
+ | age 43 / 3L / metro / fs1 | ₹11,357 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Illustration 2 ... 16 - 20 7,567 3,00,000 ... 21 - 25 7,567 3,00,000 ... 41 - 45 11,357 3,00,000 ... 46 - 50 15,216 3,00,000 ... 71- 75 65,624 3,00,000 ... 7… | `insurer_site` | 2026-05-18 |
61
+ | age 48 / 3L / metro / fs1 | ₹15,216 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_II_93c2be4860.pdf) | Illustration 2 ... 16 - 20 7,567 3,00,000 ... 21 - 25 7,567 3,00,000 ... 41 - 45 11,357 3,00,000 ... 46 - 50 15,216 3,00,000 ... 71- 75 65,624 3,00,000 ... 7… | `insurer_site` | 2026-05-18 |
62
+
63
+ **`acko__acko-health-iii`** · Acko Health Iii · UIN `ACKHLIP27040V012627`
64
+
65
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
66
+ | --- | --- | --- | --- | --- | --- |
67
+ | age 20 / 3L / tier2 / fs1 | ₹4,485 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,485 3,00,000 ... 21 - 25 6,680 3,00,000 ... 31 - 35 6,680 3,00,000 ... 36 - 40 8,200 3,00,000 ..… | `insurer_site` | 2026-05-18 |
68
+ | age 23 / 3L / tier2 / fs1 | ₹6,680 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,485 3,00,000 ... 21 - 25 6,680 3,00,000 ... 31 - 35 6,680 3,00,000 ... 36 - 40 8,200 3,00,000 ..… | `insurer_site` | 2026-05-18 |
69
+ | age 33 / 3L / tier2 / fs1 | ₹6,680 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,485 3,00,000 ... 21 - 25 6,680 3,00,000 ... 31 - 35 6,680 3,00,000 ... 36 - 40 8,200 3,00,000 ..… | `insurer_site` | 2026-05-18 |
70
+ | age 38 / 3L / tier2 / fs1 | ₹8,200 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,485 3,00,000 ... 21 - 25 6,680 3,00,000 ... 31 - 35 6,680 3,00,000 ... 36 - 40 8,200 3,00,000 ..… | `insurer_site` | 2026-05-18 |
71
+ | age 53 / 3L / tier2 / fs1 | ₹18,168 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,485 3,00,000 ... 21 - 25 6,680 3,00,000 ... 31 - 35 6,680 3,00,000 ... 36 - 40 8,200 3,00,000 ..… | `insurer_site` | 2026-05-18 |
72
+ | age 58 / 3L / tier2 / fs1 | ₹23,895 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 4,485 3,00,000 ... 21 - 25 6,680 3,00,000 ... 31 - 35 6,680 3,00,000 ... 36 - 40 8,200 3,00,000 ..… | `insurer_site` | 2026-05-18 |
73
+ | age 18 / 3L / metro / fs1 | ₹8,015 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Illustration 2 ... 16 - 20 8,015 3,00,000 ... 21 - 25 8,015 3,00,000 ... 41 - 45 12,030 3,00,000 ... 46 - 50 16,117 3,00,000 ... 71 - 75 69,509 3,00,000 ...… | `insurer_site` | 2026-05-18 |
74
+ | age 43 / 3L / metro / fs1 | ₹12,030 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Illustration 2 ... 16 - 20 8,015 3,00,000 ... 21 - 25 8,015 3,00,000 ... 41 - 45 12,030 3,00,000 ... 46 - 50 16,117 3,00,000 ... 71 - 75 69,509 3,00,000 ...… | `insurer_site` | 2026-05-18 |
75
+ | age 48 / 3L / metro / fs1 | ₹16,117 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Acko_Health_III_8d36488120.pdf) | Illustration 2 ... 16 - 20 8,015 3,00,000 ... 21 - 25 8,015 3,00,000 ... 41 - 45 12,030 3,00,000 ... 46 - 50 16,117 3,00,000 ... 71 - 75 69,509 3,00,000 ...… | `insurer_site` | 2026-05-18 |
76
+
77
+ **`acko__acko-personal-health`** · Acko Personal Health · UIN `ACKHLIP23114V012223`
78
+
79
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
80
+ | --- | --- | --- | --- | --- | --- |
81
+ | age 20 / 3L / tier2 / fs1 | ₹2,789 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
82
+ | age 23 / 3L / tier2 / fs1 | ₹4,614 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
83
+ | age 33 / 3L / tier2 / fs1 | ₹4,614 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
84
+ | age 38 / 3L / tier2 / fs1 | ₹5,318 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
85
+ | age 53 / 3L / tier2 / fs1 | ₹9,760 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
86
+ | age 58 / 3L / tier2 / fs1 | ₹12,286 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
87
+ | age 63 / 3L / tier2 / fs1 | ₹14,817 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
88
+ | age 68 / 3L / tier2 / fs1 | ₹18,223 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Annexure 2: Benefit Illustration Illustration 1 ... 0 - 15 2,789 3,00,000 ... 21 - 25 4,614 3,00,000 ... 31 - 35 4,614 3,00,000 ... 36 - 40 5,318 3,00,000 ..… | `insurer_site` | 2026-05-18 |
89
+ | age 18 / 3L / metro / fs1 | ₹5,075 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Illustration 2 ... 16 - 20 5,075 3,00,000 ... 21 - 25 5,075 3,00,000 ... 41 - 45 6,559 3,00,000 ... 46 - 50 9,390 3,00,000 ... 71- 75 20,046 3,00,000 ... 76… | `insurer_site` | 2026-05-18 |
90
+ | age 43 / 3L / metro / fs1 | ₹6,559 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Illustration 2 ... 16 - 20 5,075 3,00,000 ... 21 - 25 5,075 3,00,000 ... 41 - 45 6,559 3,00,000 ... 46 - 50 9,390 3,00,000 ... 71- 75 20,046 3,00,000 ... 76… | `insurer_site` | 2026-05-18 |
91
+ | age 48 / 3L / metro / fs1 | ₹9,390 | [assets.ctfassets.net…](https://assets.ctfassets.net/uwf0n1j71a7j/25TEE8WpUiVF72r63DRHdP/e41cdc19d2da5a1ad08a2920ac2d085a/acko-personal-health-policy-prospectus.pdf) | Illustration 2 ... 16 - 20 5,075 3,00,000 ... 21 - 25 5,075 3,00,000 ... 41 - 45 6,559 3,00,000 ... 46 - 50 9,390 3,00,000 ... 71- 75 20,046 3,00,000 ... 76… | `insurer_site` | 2026-05-18 |
92
+
93
+ **`acko__arogya-sanjeevani`** · Arogya Sanjeevani · UIN `ACKHLIP20183V011920`
94
+
95
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
96
+ | --- | --- | --- | --- | --- | --- |
97
+ | age 18 / 3L / tier2 / fs1 | ₹3,431 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | ANNEXURE: BENEFIT ILLUSTRATION Illustration 1 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 31 - 35 3,897 3,00,000 ... 36 - 40 3,897 3,00,000 ...… | `insurer_site` | 2026-05-18 |
98
+ | age 23 / 3L / tier2 / fs1 | ₹3,431 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | ANNEXURE: BENEFIT ILLUSTRATION Illustration 1 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 31 - 35 3,897 3,00,000 ... 36 - 40 3,897 3,00,000 ...… | `insurer_site` | 2026-05-18 |
99
+ | age 33 / 3L / tier2 / fs1 | ₹3,897 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | ANNEXURE: BENEFIT ILLUSTRATION Illustration 1 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 31 - 35 3,897 3,00,000 ... 36 - 40 3,897 3,00,000 ...… | `insurer_site` | 2026-05-18 |
100
+ | age 38 / 3L / tier2 / fs1 | ₹3,897 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | ANNEXURE: BENEFIT ILLUSTRATION Illustration 1 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 31 - 35 3,897 3,00,000 ... 36 - 40 3,897 3,00,000 ...… | `insurer_site` | 2026-05-18 |
101
+ | age 53 / 3L / tier2 / fs1 | ₹6,694 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | ANNEXURE: BENEFIT ILLUSTRATION Illustration 1 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 31 - 35 3,897 3,00,000 ... 36 - 40 3,897 3,00,000 ...… | `insurer_site` | 2026-05-18 |
102
+ | age 58 / 3L / tier2 / fs1 | ₹8,219 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | ANNEXURE: BENEFIT ILLUSTRATION Illustration 1 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 31 - 35 3,897 3,00,000 ... 36 - 40 3,897 3,00,000 ...… | `insurer_site` | 2026-05-18 |
103
+ | age 63 / 3L / tier2 / fs1 | ₹9,957 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | ANNEXURE: BENEFIT ILLUSTRATION Illustration 1 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 31 - 35 3,897 3,00,000 ... 36 - 40 3,897 3,00,000 ...… | `insurer_site` | 2026-05-18 |
104
+ | age 43 / 3L / tier2 / fs1 | ₹4,491 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | Illustration 2 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 41 - 45 4,491 3,00,000 ... 46 - 50 6,101 3,00,000 | `insurer_site` | 2026-05-18 |
105
+ | age 48 / 3L / tier2 / fs1 | ₹6,101 | [acko-cms.ackoassets.com…](https://acko-cms.ackoassets.com/Prospectus_Arogya_Sanjeevani_Policy_d985e9910d.pdf) | Illustration 2 ... 16 - 20 3,431 3,00,000 ... 21 - 25 3,431 3,00,000 ... 41 - 45 4,491 3,00,000 ... 46 - 50 6,101 3,00,000 | `insurer_site` | 2026-05-18 |
106
+
107
+ ### Aditya Birla Health
108
+
109
+ **`aditya-birla__activ-secure-personal-accident-cancer-secure`** · Activ Secure Personal Accident Cancer Secure · UIN `ADIHLIP18076V011718`
110
+
111
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
112
+ | --- | --- | --- | --- | --- | --- |
113
+ | age 39 / 10L / metro / fs1 | ₹5,863 | [adityabirlacapital.com…](https://www.adityabirlacapital.com/healthinsurance/assets/pdf/Activ-Secure-Prospectus.pdf) | Mr. Shankar ... they choose to buy P.A plan 3(10 L each all members) and C.I plan 2 (10L for self and 5L each for spouse and children) ... Self( age 39)- 10L… | `insurer_site` | 2026-05-18 |
114
+ | age 38 / 5L / metro / fs1 | ₹3,242 | [adityabirlacapital.com…](https://www.adityabirlacapital.com/healthinsurance/assets/pdf/Activ-Secure-Prospectus.pdf) | Mr. Shankar ... they choose to buy P.A plan 3(10 L each all members) and C.I plan 2 (10L for self and 5L each for spouse and children) ... Self( age 39)- 10L… | `insurer_site` | 2026-05-18 |
115
+ | age 10 / 5L / metro / fs1 | ₹1,430 | [adityabirlacapital.com…](https://www.adityabirlacapital.com/healthinsurance/assets/pdf/Activ-Secure-Prospectus.pdf) | Mr. Shankar ... they choose to buy P.A plan 3(10 L each all members) and C.I plan 2 (10L for self and 5L each for spouse and children) ... Self( age 39)- 10L… | `insurer_site` | 2026-05-18 |
116
+ | age 8 / 5L / metro / fs1 | ₹1,430 | [adityabirlacapital.com…](https://www.adityabirlacapital.com/healthinsurance/assets/pdf/Activ-Secure-Prospectus.pdf) | Mr. Shankar ... they choose to buy P.A plan 3(10 L each all members) and C.I plan 2 (10L for self and 5L each for spouse and children) ... Self( age 39)- 10L… | `insurer_site` | 2026-05-18 |
117
+
118
+ ### Bajaj Allianz
119
+
120
+ **`bajaj-allianz__extra-care-plus`** · Extra Care Plus · UIN `BAJHLIP23069V032223`
121
+
122
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
123
+ | --- | --- | --- | --- | --- | --- |
124
+ | age 55 / 10L / metro / fs4 | ₹7,525 | [bajajgeneralinsurance.com…](https://www.bajajgeneralinsurance.com/download-documents/health-insurance/extra-care-plus/Extra_Care_Plus_brochure.pdf) | Benefit Illustration in respect of Policies offered on Floater basis ... Age of the members to be insured 55 50 20 18 ... Premium ... 7,525 ... Sum Insured/De… | `insurer_site` | 2026-05-18 |
125
+
126
+ **`bajaj-allianz__health-guard-gold-individual`** · Health Guard Gold Individual · UIN `BAJHLIP26073V082526`
127
+
128
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
129
+ | --- | --- | --- | --- | --- | --- |
130
+ | age 18 / 3L / metro / fs1 | ₹6,894 | [bajajgeneralinsurance.com…](https://www.bajajgeneralinsurance.com/download-documents/health-insurance/health-guard/Health-Guard-Brochure-print.pdf) | Benefit Illustration in respect of Policies offered on Individual & Family Floater basis Age of the members to be insured ... Premium (for Zone A) Sum Insure… | `insurer_site` | 2026-05-18 |
131
+ | age 21 / 3L / metro / fs1 | ₹11,244 | [bajajgeneralinsurance.com…](https://www.bajajgeneralinsurance.com/download-documents/health-insurance/health-guard/Health-Guard-Brochure-print.pdf) | Benefit Illustration in respect of Policies offered on Individual & Family Floater basis Age of the members to be insured ... Premium (for Zone A) Sum Insure… | `insurer_site` | 2026-05-18 |
132
+ | age 40 / 3L / metro / fs1 | ₹14,805 | [bajajgeneralinsurance.com…](https://www.bajajgeneralinsurance.com/download-documents/health-insurance/health-guard/Health-Guard-Brochure-print.pdf) | Benefit Illustration in respect of Policies offered on Individual & Family Floater basis Age of the members to be insured ... Premium (for Zone A) Sum Insure… | `insurer_site` | 2026-05-18 |
133
+ | age 45 / 3L / metro / fs1 | ₹17,653 | [bajajgeneralinsurance.com…](https://www.bajajgeneralinsurance.com/download-documents/health-insurance/health-guard/Health-Guard-Brochure-print.pdf) | Benefit Illustration in respect of Policies offered on Individual & Family Floater basis Age of the members to be insured ... Premium (for Zone A) Sum Insure… | `insurer_site` | 2026-05-18 |
134
+
135
+ ### Care Health
136
+
137
+ **`care-health__care-advantage-add-ons-protect-plus-care-shield`** · Care Advantage Add Ons Protect Plus Care Shield · UIN `CHIHLIP26049V042526`
138
+
139
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
140
+ | --- | --- | --- | --- | --- | --- |
141
+ | age 14 / 25L / metro / fs1 | ₹5,111 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
142
+ | age 22 / 25L / metro / fs1 | ₹8,588 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
143
+ | age 24 / 25L / metro / fs1 | ₹8,588 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
144
+ | age 40 / 25L / metro / fs1 | ₹11,864 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
145
+ | age 44 / 25L / metro / fs1 | ₹13,654 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
146
+ | age 61 / 25L / metro / fs1 | ₹53,659 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
147
+ | age 71 / 25L / metro / fs1 | ₹96,095 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
148
+ | age 75 / 25L / metro / fs1 | ₹121,318 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/care-advantage-(health-insurance-product)--prospectus-cum-sales-literature.pdf?rv=0.62429600+1621514455) | Annexure - VI Benefit/ Premium illustration Illustration 1 ... 44 13,654 25,00,000 13,654 NA 13,654 25,00,000 32,647 NA 32,647 25,00,000 40 11,864 25,00,000… | `insurer_site` | 2026-05-18 |
149
+
150
+ **`care-health__care-supreme-enhance`** · Care Supreme Enhance · UIN `CHIHLIP25036V012425`
151
+
152
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
153
+ | --- | --- | --- | --- | --- | --- |
154
+ | age 28 / 10L / metro / fs1 | ₹1,972 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/supreme-enhance---prospectus-cum-sales-literature.pdf) | Annexure IV - Benefit / Premium illustration Illustration 1 ... 28 1972 10,00,000 ... 30 1972 10,00,000 ... Total Premium when policy is opted on floater bas… | `insurer_site` | 2026-05-18 |
155
+ | age 30 / 10L / metro / fs1 | ₹1,972 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/supreme-enhance---prospectus-cum-sales-literature.pdf) | Annexure IV - Benefit / Premium illustration Illustration 1 ... 28 1972 10,00,000 ... 30 1972 10,00,000 ... Total Premium when policy is opted on floater bas… | `insurer_site` | 2026-05-18 |
156
+ | age 17 / 10L / metro / fs1 | ₹1,750 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/supreme-enhance---prospectus-cum-sales-literature.pdf) | Annexure IV - Benefit / Premium illustration Illustration 1 ... 28 1972 10,00,000 ... 30 1972 10,00,000 ... Total Premium when policy is opted on floater bas… | `insurer_site` | 2026-05-18 |
157
+ | age 56 / 10L / metro / fs1 | ₹8,258 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/supreme-enhance---prospectus-cum-sales-literature.pdf) | Annexure IV - Benefit / Premium illustration Illustration 1 ... 28 1972 10,00,000 ... 30 1972 10,00,000 ... Total Premium when policy is opted on floater bas… | `insurer_site` | 2026-05-18 |
158
+ | age 60 / 10L / metro / fs1 | ₹8,258 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/supreme-enhance---prospectus-cum-sales-literature.pdf) | Annexure IV - Benefit / Premium illustration Illustration 1 ... 28 1972 10,00,000 ... 30 1972 10,00,000 ... Total Premium when policy is opted on floater bas… | `insurer_site` | 2026-05-18 |
159
+
160
+ **`care-health__ultimate-care`** · Ultimate Care · UIN `CHIHLIP26058V022526`
161
+
162
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
163
+ | --- | --- | --- | --- | --- | --- |
164
+ | age 17 / 5L / metro / fs1 | ₹6,491 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/ultimate-care---prospectus-cum-sales-literature.pdf) | Annexure V - Benefit / Premium illustration Illustration 1 ... 46 13,885 5,00,000 ... 51 17,402 5,00,000 ... Illustration 2 ... 46 13,885 5,00,000 ... 51 17,… | `insurer_site` | 2026-05-18 |
165
+ | age 46 / 5L / metro / fs1 | ₹13,885 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/ultimate-care---prospectus-cum-sales-literature.pdf) | Annexure V - Benefit / Premium illustration Illustration 1 ... 46 13,885 5,00,000 ... 51 17,402 5,00,000 ... Illustration 2 ... 46 13,885 5,00,000 ... 51 17,… | `insurer_site` | 2026-05-18 |
166
+ | age 51 / 5L / metro / fs1 | ₹17,402 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/ultimate-care---prospectus-cum-sales-literature.pdf) | Annexure V - Benefit / Premium illustration Illustration 1 ... 46 13,885 5,00,000 ... 51 17,402 5,00,000 ... Illustration 2 ... 46 13,885 5,00,000 ... 51 17,… | `insurer_site` | 2026-05-18 |
167
+ | age 61 / 5L / metro / fs1 | ₹32,898 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/ultimate-care---prospectus-cum-sales-literature.pdf) | Annexure V - Benefit / Premium illustration Illustration 1 ... 46 13,885 5,00,000 ... 51 17,402 5,00,000 ... Illustration 2 ... 46 13,885 5,00,000 ... 51 17,… | `insurer_site` | 2026-05-18 |
168
+ | age 64 / 5L / metro / fs1 | ₹39,948 | [cms.careinsurance.com…](https://cms.careinsurance.com/cms/public/uploads/download_center/ultimate-care---prospectus-cum-sales-literature.pdf) | Annexure V - Benefit / Premium illustration Illustration 1 ... 46 13,885 5,00,000 ... 51 17,402 5,00,000 ... Illustration 2 ... 46 13,885 5,00,000 ... 51 17,… | `insurer_site` | 2026-05-18 |
169
+
170
+ ### Cholamandalam MS
171
+
172
+ **`cholamandalam__super-topup`** · Super Topup · UIN `CHOHLIP21561V012021`
173
+
174
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
175
+ | --- | --- | --- | --- | --- | --- |
176
+ | age 18 / 10L / metro / fs1 | ₹912 | [irdai.gov.in…](https://irdai.gov.in/documents/37343/931203/CHOHLIP21561V012021_2020-2021.pdf/cace22d1-c5c7-fc4c-3f58-6d80a024512d?version=1.1&t=1668584072276&download=true) | CHOLA FLEXI SUPER TOPUP INSURANCE -GOLD PLAN, Policy Period - ONE Year ... 18 912 Rs 10 Lakhs Sum insured with Rs 5 Lakhs Deductible 912 | `insurer_site` | 2026-05-18 |
177
+ | age 48 / 10L / metro / fs1 | ₹1,949 | [irdai.gov.in…](https://irdai.gov.in/documents/37343/931203/CHOHLIP21561V012021_2020-2021.pdf/cace22d1-c5c7-fc4c-3f58-6d80a024512d?version=1.1&t=1668584072276&download=true) | 48 1,949 Rs 10 Lakhs Sum insured with Rs 5 Lakhs Deductible 1,949 ... Total premium for all members of the family is Rs. 6691/-, when each member is covered… | `insurer_site` | 2026-05-18 |
178
+ | age 54 / 10L / metro / fs1 | ₹2,795 | [irdai.gov.in…](https://irdai.gov.in/documents/37343/931203/CHOHLIP21561V012021_2020-2021.pdf/cace22d1-c5c7-fc4c-3f58-6d80a024512d?version=1.1&t=1668584072276&download=true) | 54 2,795 Rs 10 Lakhs Sum insured with Rs 5 Lakhs Deductible 2,795 | `insurer_site` | 2026-05-18 |
179
+
180
+ ### Go Digit
181
+
182
+ **`go-digit__arogya-sanjeevani`** · Arogya Sanjeevani · UIN `GODHLIP20168V011920`
183
+
184
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
185
+ | --- | --- | --- | --- | --- | --- |
186
+ | age 22 / 5L / metro / fs1 | ₹3,122 | [godigit.com…](https://www.godigit.com/content/dam/godigit/directportal/en/downloads/health/Arogya%20Sanjeevani%20-%20Prospectus%20(with%20premium%20Illustration).pdf) | Family Composition - 1A / Highest member Age Band ... 1 Lakh 2 Lakh 3 Lakh 4 Lakh 5 Lakh 10 Lakh 25 lakh 50 Lakh 1 Crore / 18-25 1,802 2,269 2,682 2,929 3,12… | `insurer_site` | 2026-05-18 |
187
+ | age 33 / 5L / metro / fs1 | ₹3,625 | [godigit.com…](https://www.godigit.com/content/dam/godigit/directportal/en/downloads/health/Arogya%20Sanjeevani%20-%20Prospectus%20(with%20premium%20Illustration).pdf) | Family Composition - 1A ... 5 Lakh ... 31-35 2,093 2,635 3,114 3,401 3,625 5,446 7,239 8,458 9,546 | `insurer_site` | 2026-05-18 |
188
+ | age 43 / 5L / metro / fs1 | ₹5,468 | [godigit.com…](https://www.godigit.com/content/dam/godigit/directportal/en/downloads/health/Arogya%20Sanjeevani%20-%20Prospectus%20(with%20premium%20Illustration).pdf) | Family Composition - 1A ... 5 Lakh ... 41-45 3,157 3,975 4,698 5,130 5,468 8,213 10,918 12,757 14,399 | `insurer_site` | 2026-05-18 |
189
+ | age 58 / 5L / metro / fs1 | ₹13,466 | [godigit.com…](https://www.godigit.com/content/dam/godigit/directportal/en/downloads/health/Arogya%20Sanjeevani%20-%20Prospectus%20(with%20premium%20Illustration).pdf) | Family Composition - 1A ... 5 Lakh ... 56-60 7,775 9,788 11,569 12,634 13,466 20,227 26,887 31,418 35,460 | `insurer_site` | 2026-05-18 |
190
+
191
+ **`go-digit__digit-health-care-plus`** · Digit Health Care Plus · UIN `GODHLIP21486V022021`
192
+
193
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
194
+ | --- | --- | --- | --- | --- | --- |
195
+ | age 51 / 5L / metro / fs4 | ₹8,162 | [d2h44aw7l5xdvz.cloudfront.net…](https://d2h44aw7l5xdvz.cloudfront.net/policyDocuments/Health/Digit%20Health%20Care%20Plus%20Policy_Benefit_Illustration.pdf) | 2Adults +2Children / 51 8,162 5,00,000 8,162 10% 7,346 5,00,000 14,568 NA 14,568 5,00,000 | `insurer_site` | 2026-05-18 |
196
+ | age 48 / 5L / metro / fs4 | ₹7,014 | [d2h44aw7l5xdvz.cloudfront.net…](https://d2h44aw7l5xdvz.cloudfront.net/policyDocuments/Health/Digit%20Health%20Care%20Plus%20Policy_Benefit_Illustration.pdf) | 48 7,014 5,00,000 7,014 10% 6,313 5,00,000 | `insurer_site` | 2026-05-18 |
197
+ | age 18 / 5L / metro / fs4 | ₹3,268 | [d2h44aw7l5xdvz.cloudfront.net…](https://d2h44aw7l5xdvz.cloudfront.net/policyDocuments/Health/Digit%20Health%20Care%20Plus%20Policy_Benefit_Illustration.pdf) | 18 3,268 5,00,000 3,268 10% 2,941 5,00,000 | `insurer_site` | 2026-05-18 |
198
+ | age 62 / 3L / metro / fs2 | ₹11,048 | [d2h44aw7l5xdvz.cloudfront.net…](https://d2h44aw7l5xdvz.cloudfront.net/policyDocuments/Health/Digit%20Health%20Care%20Plus%20Policy_Benefit_Illustration.pdf) | 2 Adults / 62 11,048 300,000 11,048 5% 10,496 300,000 20,104 NA 20,104 300,000 | `insurer_site` | 2026-05-18 |
199
+
200
+ **`go-digit__digit-top-up`** · Digit Top Up · UIN `GODHLIP24056V012324`
201
+
202
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
203
+ | --- | --- | --- | --- | --- | --- |
204
+ | age 18 / 1Cr / metro / fs3 | ₹1,011 | [godigit.com…](https://www.godigit.com/content/dam/godigit/directportal/en/downloads/health/Prospectus_Digit%20Top%20Up%20Policy.pdf) | Plan Name Platinum Super Top Up / Family Composition 2A+1C / Sum Insured 1,00,00,000 / Deductible 10,00,000 / Policy Type Floater Individual ... 18 3,120 1,0… | `insurer_site` | 2026-05-18 |
205
+ | age 62 / 1Cr / metro / fs2 | ₹7,302 | [godigit.com…](https://www.godigit.com/content/dam/godigit/directportal/en/downloads/health/Prospectus_Digit%20Top%20Up%20Policy.pdf) | Plan Name Platinum Super Top Up / Family Composition 2A / Sum Insured 1,00,00,000 / Deductible 10,00,000 / Policy Type Floater Individual ... 62 10,953 7,302… | `insurer_site` | 2026-05-18 |
206
+
207
+ ### HDFC ERGO
208
+
209
+ **`hdfc-ergo__energy-diabetes-hypertension`** · Energy Diabetes Hypertension · UIN `—`
210
+
211
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
212
+ | --- | --- | --- | --- | --- | --- |
213
+ | age 45 / 15L / metro / fs1 | ₹23,702 | [joinditto.in…](https://joinditto.in/articles/health-insurance/hdfc-ergo-energy-plan-diabetes-health-insurance-review/) | A 45-year-old living in Delhi pays ₹23,702 per year for a ₹15 lakh cover under the Silver variant. | `aggregator_quote` | 2026-05-18 |
214
+ | age 25 / 15L / metro / fs1 | ₹18,463 | [joinditto.in…](https://joinditto.in/articles/health-insurance/hdfc-ergo-energy-plan-diabetes-health-insurance-review/) | Premium Comparison Table (₹15 lakh Sum Insured, Delhi) / 25 / ₹18,463 / ₹23,463 | `aggregator_quote` | 2026-05-18 |
215
+
216
+ **`hdfc-ergo__total-health-plan`** · Total Health Plan · UIN `HDHHLIP21317V032021`
217
+
218
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
219
+ | --- | --- | --- | --- | --- | --- |
220
+ | age 35 / 5L / metro / fs1 | ₹5,599 | [hdfcergo.com…](https://www.hdfcergo.com/docs/default-source/downloads/policy-wordings/health/total-health-plan.pdf) | Product Name – Total Health Plan / Sum Insured - 5 Lakhs / Tenure – 1 Year ... 35 5,599 5 5,599 560 5,039 5 | `insurer_site` | 2026-05-18 |
221
+ | age 40 / 5L / metro / fs1 | ₹6,336 | [hdfcergo.com…](https://www.hdfcergo.com/docs/default-source/downloads/policy-wordings/health/total-health-plan.pdf) | 40 6,336 5 6,336 634 5,702 5 | `insurer_site` | 2026-05-18 |
222
+
223
+ **`hdfc-ergo__my-health-medisure-prime`** · My Health Medisure Prime · UIN `—`
224
+
225
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
226
+ | --- | --- | --- | --- | --- | --- |
227
+ | age 30 / 5L / metro / fs1 | ₹9,224 | [hdfcergo.com…](https://www.hdfcergo.com/docs/default-source/downloads/prospectus/myhealth-medisure-prime-insurance.pdf) | PREMIUM CHART ... Zone 1: Mumbai, Thane, Navi Mumbai, Delhi, and NCR Regions / SI (`) 500000 / Age - years 26-35 ... 9,224 | `insurer_site` | 2026-05-18 |
228
+
229
+ **`hdfc-ergo__my-optima-secure`** · My Optima Secure · UIN `HDFHLIP23123V022223`
230
+
231
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
232
+ | --- | --- | --- | --- | --- | --- |
233
+ | age 25 / 10L / metro / fs1 | ₹22,000 | [healthstatic.policybazaar.com…](https://healthstatic.policybazaar.com/health-insurance/Insurer_Document/HDFC/my-optima-secure-prospectus.pdf) | my: Optima Secure - Optima Secure Plan Gross Premium (Excl. GST) - Tier 1 ... Age 25 ... Sum Insured 10,00,000 ... 22,000 | `insurer_site` | 2026-05-18 |
234
+ | age 45 / 10L / metro / fs1 | ₹16,500 | [healthstatic.policybazaar.com…](https://healthstatic.policybazaar.com/health-insurance/Insurer_Document/HDFC/my-optima-secure-prospectus.pdf) | Premium Computation Illustration Illustration 2 Plan Name - Optima Secure Tenure - 1 Year Location - Delhi - Tier 1 ... 45 16,500 10 ... | `insurer_site` | 2026-05-18 |
235
+ | age 55 / 10L / metro / fs1 | ₹32,500 | [healthstatic.policybazaar.com…](https://healthstatic.policybazaar.com/health-insurance/Insurer_Document/HDFC/my-optima-secure-prospectus.pdf) | Illustration 2 Plan Name - Optima Secure ... Location - Delhi - Tier 1 ... 55 32,500 10 32,500 3,250 29,250 10 ... | `insurer_site` | 2026-05-18 |
236
+ | age 30 / 5L / metro / fs1 | ₹11,000 | [healthstatic.policybazaar.com…](https://healthstatic.policybazaar.com/health-insurance/Insurer_Document/HDFC/my-optima-secure-prospectus.pdf) | Optima Secure Plan Gross Premium (Excl. GST) - Tier 1 ... 30 11,000 13,500 14,400 15,200 15,950 19,000 23,000 29,000 | `insurer_site` | 2026-05-18 |
237
+
238
+ **`hdfc-ergo__my-optima-secure-older-variant`** · My Optima Secure Older Variant · UIN `—`
239
+
240
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
241
+ | --- | --- | --- | --- | --- | --- |
242
+ | age 25 / 15L / metro / fs1 | ₹14,130 | [joinditto.in…](https://joinditto.in/articles/health-insurance/hdfc-ergo-health-insurance-premium-chart/) | Popular HDFC ERGO Health Insurance Plans With Premium Charts / (Individual Plan): Age 25 / Optima Secure / Rs.14,130 ... 'Unless mentioned otherwise, the pre… | `aggregator_quote` | 2026-05-18 |
243
+ | age 25 / 10L / metro / fs1 | ₹22,172 | [healthstatic.policybazaar.com…](https://healthstatic.policybazaar.com/health-insurance/Insurer_Document/HDFC/my-optima-secure-prospectus.pdf) | my: Optima Secure - Optima Super Secure Plan Gross Premium (Excl. GST) - Tier 1 ... 25 10,571 12,762 13,646 14,420 15,144 18,184 22,172 27,706 | `insurer_site` | 2026-05-18 |
244
+
245
+ ### ICICI Lombard
246
+
247
+ **`icici-lombard__complete-health-insurance-health-shield`** · Complete Health Insurance Health Shield · UIN `—`
248
+
249
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
250
+ | --- | --- | --- | --- | --- | --- |
251
+ | age 30 / 5L / metro / fs1 | ₹6,477 | [policyx.com…](https://www.policyx.com/health-insurance/icici-lombard-health-insurance/complete-health-insurance.php) | Let's see how the premium varies across different types and sum insured for an individual at the age of 30 and for a policy term of 1 year. Health Shield / S… | `aggregator_quote` | 2026-05-18 |
252
+ | age 30 / 10L / metro / fs1 | ₹7,665 | [policyx.com…](https://www.policyx.com/health-insurance/icici-lombard-health-insurance/complete-health-insurance.php) | Health Shield / SI Options (Rs.) 5L 10L 20L 25L 50L / Premium Payable (Rs.) 6,477 7,665 12,246 13,188 16,580 | `aggregator_quote` | 2026-05-18 |
253
+ | age 30 / 20L / metro / fs1 | ₹12,246 | [policyx.com…](https://www.policyx.com/health-insurance/icici-lombard-health-insurance/complete-health-insurance.php) | Health Shield / SI Options (Rs.) 5L 10L 20L 25L 50L / Premium Payable (Rs.) 6,477 7,665 12,246 13,188 16,580 | `aggregator_quote` | 2026-05-18 |
254
+
255
+ **`icici-lombard__arogya-sanjeevani`** · Arogya Sanjeevani · UIN `—`
256
+
257
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
258
+ | --- | --- | --- | --- | --- | --- |
259
+ | age 25 / 15L / metro / fs1 | ₹6,719 | [joinditto.in…](https://joinditto.in/articles/health-insurance/hdfc-ergo-health-insurance-premium-chart/) | Popular HDFC ERGO Health Insurance Plans With Premium Charts / (Individual Plan): Age 25 / Arogya Sanjeevani / Rs.6,719 ... 'Unless mentioned otherwise, the… | `aggregator_quote` | 2026-05-18 |
260
+
261
+ **`icici-lombard__health-elite-plus`** · Health Elite Plus · UIN `—`
262
+
263
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
264
+ | --- | --- | --- | --- | --- | --- |
265
+ | age 30 / 5L / metro / fs1 | ₹9,644 | [policyx.com…](https://www.policyx.com/health-insurance/icici-lombard-health-insurance/complete-health-insurance.php) | Let's see how the premium varies across different types and sum insured for an individual at the age of 30 and for a policy term of 1 year. Health Elite / SI… | `aggregator_quote` | 2026-05-18 |
266
+ | age 30 / 10L / metro / fs1 | ₹13,866 | [policyx.com…](https://www.policyx.com/health-insurance/icici-lombard-health-insurance/complete-health-insurance.php) | Health Elite / SI Options (Rs.) 5L 10L 20L 25L 50L / Premium Payable (Rs.) 9,644 13,866 26,380 27,411 30,697 | `aggregator_quote` | 2026-05-18 |
267
+
268
+ ### IFFCO Tokio
269
+
270
+ **`iffco-tokio__critical-illness-benefit`** · Critical Illness Benefit · UIN `IFFHLIP19036V011920`
271
+
272
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
273
+ | --- | --- | --- | --- | --- | --- |
274
+ | age 30 / 10L / tier2 / fs1 | ₹3,256 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/critical-illness-benefit-policy.pdf) | Critical Illness Benefit Policy UIN: IFFHLIP19036V011920 Rate chart ... Age/SI ... 1,000,000 ... 25-35 ... 3,256 ... Year 1 Premium | `insurer_site` | 2026-05-18 |
275
+ | age 45 / 10L / tier2 / fs1 | ₹7,755 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/critical-illness-benefit-policy.pdf) | Age/SI ... 1,000,000 ... 41-45 ... 7,755 ... Year 1 Premium | `insurer_site` | 2026-05-18 |
276
+ | age 22 / 10L / tier2 / fs1 | ₹2,566 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/critical-illness-benefit-policy.pdf) | Age/SI 100,000 ... 1,000,000 ... <25 257 ... 2,566 ... Year 1 Premium | `insurer_site` | 2026-05-18 |
277
+
278
+ **`iffco-tokio__essential-health-plan`** · Essential Health Plan · UIN `IFFHLIP25035V012425`
279
+
280
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
281
+ | --- | --- | --- | --- | --- | --- |
282
+ | age 30 / 5L / tier2 / fs1 | ₹5,620 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/premium-chart.pdf) | ESSENTIAL HEALTH PROTECTOR UIN: IFFHLIP25035V012425 PREMIUM CHART Policy Period 1 year Individual basis ... Age/SI ... 26-35 ... 500,000 4,890 5,620 | `insurer_site` | 2026-05-18 |
283
+ | age 30 / 10L / tier2 / fs1 | ₹7,510 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/premium-chart.pdf) | Age/SI 0-25 26-35 ... 1,000,000 6,545 7,510 10,050 | `insurer_site` | 2026-05-18 |
284
+ | age 50 / 5L / tier2 / fs1 | ₹10,335 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/premium-chart.pdf) | Age/SI 0-25 26-35 36-45 46-55 ... 500,000 4,890 5,620 7,530 10,335 | `insurer_site` | 2026-05-18 |
285
+
286
+ **`iffco-tokio__family-health-protector`** · Family Health Protector · UIN `IFFHLIP24013V052324`
287
+
288
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
289
+ | --- | --- | --- | --- | --- | --- |
290
+ | age 30 / 5L / tier2 / fs1 | ₹6,208 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/family-health-protector.pdf) | FAMILY HEALTH PROTECTOR WITHOUT CRITICAL ILLNESS Premium Rates for Highest Aged Member ... Age/SI 0-25 26-35 ... 5,00,000 5,382 6,208 8,780 11,566 | `insurer_site` | 2026-05-18 |
291
+ | age 30 / 10L / tier2 / fs1 | ₹8,250 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/family-health-protector.pdf) | Age/SI 0-25 26-35 36-45 ... 10,00,000 7,153 8,250 11,669 15,370 | `insurer_site` | 2026-05-18 |
292
+ | age 50 / 5L / tier2 / fs1 | ₹11,566 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/family-health-protector.pdf) | Age/SI 0-25 26-35 36-45 46-55 ... 5,00,000 5,382 6,208 8,780 11,566 | `insurer_site` | 2026-05-18 |
293
+
294
+ **`iffco-tokio__individual-health-protector`** · Individual Health Protector · UIN `IFFHLIP24012V052324`
295
+
296
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
297
+ | --- | --- | --- | --- | --- | --- |
298
+ | age 30 / 5L / tier2 / fs1 | ₹7,916 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/individual-health-protector.pdf) | Health Protector UIN: IFFHLIP24012V052324 RATE CHART ... Rate Sheet of Health Protector portfolio without Critical Illness ... 5,00,000 5,934 7,916 9,853 14,948 | `insurer_site` | 2026-05-18 |
299
+ | age 30 / 10L / tier2 / fs1 | ₹10,642 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/individual-health-protector.pdf) | Health Protector UIN: IFFHLIP24012V052324 RATE CHART Rate Sheet of Health Protector portfolio without Critical Illness ... 10,00,000 7,977 10,642 13,245 20,094 | `insurer_site` | 2026-05-18 |
300
+ | age 50 / 5L / tier2 / fs1 | ₹14,948 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/rate-chart/individual-health-protector.pdf) | Age (yrs.)/SI 3months to 25 26 to 35 36 to 45 46 to 55 ... 5,00,000 5,934 7,916 9,853 14,948 | `insurer_site` | 2026-05-18 |
301
+
302
+ **`iffco-tokio__health-protector-assure`** · Health Protector Assure · UIN `IFFHLIP24131V012324`
303
+
304
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
305
+ | --- | --- | --- | --- | --- | --- |
306
+ | age 30 / 10L / tier2 / fs1 | ₹1,505 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/iffco-pdf/Premium_Table_Health_Protector_Assure.pdf) | HEALTH PROTECTOR ASSURE UIN: IFFHLIP24131V012324 RATING CHART A) SUPER TOP-UP VARIANT PREMIUM RATES (EXCLUDING GST) Super Top-Up Individual Basis (1 Year Pol… | `insurer_site` | 2026-05-18 |
307
+ | age 30 / 5L / tier2 / fs1 | ₹1,135 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/iffco-pdf/Premium_Table_Health_Protector_Assure.pdf) | Super Top-Up Individual Basis (1 Year Policy) Sum Insured Deductible 0-25 26-35 ... 500,000 500,000 985 1,135 1,605 2,110 | `insurer_site` | 2026-05-18 |
308
+ | age 50 / 10L / tier2 / fs1 | ₹2,805 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/iffco-pdf/Premium_Table_Health_Protector_Assure.pdf) | Sum Insured Deductible 0-25 26-35 36-45 46-55 ... 1,000,000 500,000 1,305 1,505 2,130 2,805 | `insurer_site` | 2026-05-18 |
309
+
310
+ **`iffco-tokio__health-protector-plus`** · Health Protector Plus · UIN `—`
311
+
312
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
313
+ | --- | --- | --- | --- | --- | --- |
314
+ | age 30 / 10L / tier2 / fs1 | ₹2,899 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/iffco-pdf/RATE%20CHART-%20Health%20Protector%20Plus.pdf) | RATE CHART Health Protector Plus 1) Top-up a. Individual basis for 1 Member: Sum Insured ... 1000000 Deductible ... 500000 Above 3 months to 35 years ... 2,899 | `insurer_site` | 2026-05-18 |
315
+ | age 30 / 10L / tier2 / fs1 | ₹3,199 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/iffco-pdf/RATE%20CHART-%20Health%20Protector%20Plus.pdf) | 2) Super Top-up a. Individual basis for 1 Member: Sum Insured ... 1000000 Deductible ... 500000 Above 3 months to 35 years ... 3,199 | `insurer_site` | 2026-05-18 |
316
+ | age 50 / 10L / tier2 / fs1 | ₹3,799 | [iffcotokio.co.in…](https://www.iffcotokio.co.in/content/dam/iffcotokio/iffco-pdf/RATE%20CHART-%20Health%20Protector%20Plus.pdf) | 1) Top-up a. Individual basis for 1 Member: ... 1000000 ... 500000 ... 46 to 55 ... 3,799 | `insurer_site` | 2026-05-18 |
317
+
318
+ ### ManipalCigna
319
+
320
+ **`manipalcigna__prohealth-prime`** · Prohealth Prime · UIN `—`
321
+
322
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
323
+ | --- | --- | --- | --- | --- | --- |
324
+ | age 30 / 5L / metro / fs2 | ₹13,999 | [manipalcigna.com…](https://www.manipalcigna.com/hospitalization-cover/prohealth-insurance/prohealthprime-protect) | Premium PER ANNUM: 13,999* inclusive of taxes(as applicable) *The Premium value is indicative for the below mentioned profile Age - 30, Zone - 1, Cover type… | `insurer_site` | 2026-05-18 |
325
+ | age 35 / 5L / metro / fs1 | ₹12,640 | [manipalcigna.com…](https://www.manipalcigna.com/hospitalization-cover/prohealth-insurance/prohealthprime-advantage) | Premium Per Annum: Rs.12,640* (inclusive of taxes) ... indicative for the below mentioned profile Age 35, Zone 1, Cover type Individual, Tenure 1 year, Premi… | `insurer_site` | 2026-05-18 |
326
+ | age 35 / 5L / metro / fs1 | ₹13,118 | [manipalcigna.com…](https://www.manipalcigna.com/hospitalization-cover/prohealth-insurance/prohealthprime-active) | Premium PER ANNUM: 13,118* inclusive of taxes(as applicable) ... indicative for the below mentioned profile Age 35, Zone 1, Cover type Individual, Tenure 1 y… | `insurer_site` | 2026-05-18 |
327
+
328
+ ### National Insurance
329
+
330
+ **`national-insurance__arogya-sanjeevani`** · Arogya Sanjeevani · UIN `NICHLIP20174V011920`
331
+
332
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
333
+ | --- | --- | --- | --- | --- | --- |
334
+ | age 30 / 5L / metro / fs1 | ₹7,185 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/ASP%20Rate%20Chart%20up%20to%2010%20Lakhs%20SI_0.pdf) | Arogya Sanjeevani Policy – National Rate Chart (in INR) For Policy on Individual basis – Premium Table for each family Member ... 26-30 2,293 3,031 3,748 4,3… | `insurer_site` | 2026-05-18 |
335
+
336
+ **`national-insurance__national-critical-illness`** · National Critical Illness · UIN `NICHLIP18086V011718`
337
+
338
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
339
+ | --- | --- | --- | --- | --- | --- |
340
+ | age 28 / 5L / metro / fs1 | ₹1,680 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/2024-08/NCIP%20Rate%20Chart%20with%20GST.pdf) | National Critical Illness Policy Rate Chart Rates (in INR) per individual Plan A (covering 11 CIs) Age/ SI ... 26-30 ... 5,00,000 1,056 1,173 1,680 2,441 ... | `insurer_site` | 2026-05-18 |
341
+
342
+ **`national-insurance__national-hospi-cash`** · National Hospi Cash · UIN `NICHLIP25046V012425`
343
+
344
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
345
+ | --- | --- | --- | --- | --- | --- |
346
+ | age 30 / 3.65L / metro / fs1 | ₹614 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/2026-04/NHCP%20Rate%20Chart.pdf) | National Hospi Cash Policy Rate Chart (in INR) In-built cover - 1 year Premium Indemnity Period 30 days Time Excess 1 day Upto 45 ... 1000 614 941 1,256 1,08… | `insurer_site` | 2026-05-18 |
347
+
348
+ **`national-insurance__national-mediclaim-plus`** · National Mediclaim Plus · UIN `NICHLIP21150V022021`
349
+
350
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
351
+ | --- | --- | --- | --- | --- | --- |
352
+ | age 30 / 5L / metro / fs1 | ₹10,417 | [bankofbaroda.bank.in…](https://bankofbaroda.bank.in/-/media/Project/BOB/CountryWebsites/India/pdfs/nmpp-rate-chart-09-13.pdf) | National Mediclaim Plus Policy Rate Chart Rate without TPA charges (in ₹) SI 3m-5 6 - 17 18 - 25 26-35 36-45 ... 5,00,000 9,191 9,192 10,212 10,417 10,417 15… | `insurer_site` | 2026-05-18 |
353
+
354
+ **`national-insurance__national-mediclaim`** · National Mediclaim · UIN `NICHLIP25036V082425`
355
+
356
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
357
+ | --- | --- | --- | --- | --- | --- |
358
+ | age 28 / 5L / metro / fs1 | ₹7,125 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/2024-12/NMP%20Rate%20Chart%20Revised.pdf) | National Mediclaim Policy Rate Chart (in ₹ per Individual, without TPA Charges) Age band / SI 1,00,000 2,00,000 3,00,000 4,00,000 5,00,000 ... 26-30 2,934 3,… | `insurer_site` | 2026-05-18 |
359
+
360
+ **`national-insurance__national-parivar-plus`** · National Parivar Plus · UIN `NICHLIP25039V032425`
361
+
362
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
363
+ | --- | --- | --- | --- | --- | --- |
364
+ | age 30 / 6L / metro / fs1 | ₹11,649 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/2024-12/NPMPP%20Rate%20Chart.pdf) | National Parivar Mediclaim Plus Policy Rate chart (in ₹) Rate for senior most member (without TPA) for each policy year for Zone I (Greater Mumbai Metropolit… | `insurer_site` | 2026-05-18 |
365
+
366
+ **`national-insurance__national-senior-citizen`** · National Senior Citizen · UIN `NICHLIP21083V022021`
367
+
368
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
369
+ | --- | --- | --- | --- | --- | --- |
370
+ | age 62 / 5L / metro / fs1 | ₹19,746 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/NSCMP%20-%20Rate%20Chart.pdf) | National Senior Citizen Mediclaim Policy RATE CHART Plan A – Premium Table for Individuals / Premium Table for Senior most member (for floater policy) SI 1,0… | `insurer_site` | 2026-05-18 |
371
+
372
+ **`national-insurance__national-super-top-up`** · National Super Top Up · UIN `NICHLIP24154V042324`
373
+
374
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
375
+ | --- | --- | --- | --- | --- | --- |
376
+ | age 30 / 10L / metro / fs1 | ₹1,564 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/2025-01/NSTUMP%20Rate%20Chart.pdf) | National Super Top Up Mediclaim Policy Rate Chart (in ₹) Premium (₹) per Individual (for individual policy)/ Senior most member (for floater policy) Threshol… | `insurer_site` | 2026-05-18 |
377
+
378
+ **`national-insurance__national-young-india-plus`** · National Young India Plus · UIN `NICHLIP24127V012324`
379
+
380
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
381
+ | --- | --- | --- | --- | --- | --- |
382
+ | age 28 / 5L / metro / fs1 | ₹7,145 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/2024-10/NYIMPP%20Rate%20Chart.pdf) | National Young India Mediclaim Plus Policy Rate Chart (in ₹ for Individual) Zone 1 Eldest Age Band 500000 1000000 1500000 2500000 ... 18-25 7021 8570 10319 1… | `insurer_site` | 2026-05-18 |
383
+
384
+ **`national-insurance__national-young-india`** · National Young India · UIN `NICHLIP23032V012223`
385
+
386
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
387
+ | --- | --- | --- | --- | --- | --- |
388
+ | age 28 / 5L / metro / fs1 | ₹11,599 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/NYIMP%20Rate%20Chart%20with%20GST.pdf) | National Young India Mediclaim Policy Rate Chart (in ₹ for Individual) Premium without TPA Charges Zone Age-band/SI 3,00,000 5,00,000 10,00,000 1 ... 26-30 9… | `insurer_site` | 2026-05-18 |
389
+
390
+ **`national-insurance__new-national-parivar`** · New National Parivar · UIN `NICHLIP23033V012223`
391
+
392
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
393
+ | --- | --- | --- | --- | --- | --- |
394
+ | age 28 / 5L / metro / fs1 | ₹10,099 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/NNPMP%20Rate%20Chart.pdf) | New National Parivar Mediclaim Policy Rate Chart (in ₹) Zone 1 : Premium of senior-most member Age band 100000 200000 300000 400000 500000 ... 18-25 4,566 6,… | `insurer_site` | 2026-05-18 |
395
+
396
+ **`national-insurance__universal-health`** · Universal Health · UIN `NICHLIP21593V042021`
397
+
398
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
399
+ | --- | --- | --- | --- | --- | --- |
400
+ | age 30 / 0.5L / metro / fs1 | ₹597 | [nationalinsurance.nic.co.in…](https://nationalinsurance.nic.co.in/sites/default/files/2024-10/UHIP%20Prospectus.pdf) | Rate Chart (in ₹ per family) Members SI – ₹ 30,000 SI – ₹ 50,000 Individual ₹ 385 ₹ 597 Family up to 5 members (consisting of Insured, spouse and first 3 dep… | `insurer_site` | 2026-05-18 |
401
+
402
+ ### New India Assurance
403
+
404
+ **`new-india__asha-kiran-policy`** · Asha Kiran Policy · UIN `NIAHLIP25038V012425`
405
+
406
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
407
+ | --- | --- | --- | --- | --- | --- |
408
+ | age 25 / 5L / metro / fs1 | ₹7,917 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/asha-kiran-policy/Premium%20chart%20New%20India%20Asha%20Kiran%20Policy-01%20Oct%202024%20(1).pdf) | NEW INDIA ASHA KIRAN POLICY New India Asha Kiran Policy - Premium Chart (Excluding GST) ... PRIMARY MEMBER Premiums applicable at different ages (Rs. per ann… | `insurer_site` | 2026-05-18 |
409
+
410
+ **`new-india__janata-mediclaim-policy`** · Janata Mediclaim Policy · UIN `—`
411
+
412
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
413
+ | --- | --- | --- | --- | --- | --- |
414
+ | age 30 / 0.5L / metro / fs1 | ₹809 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/janata-mediclaim-policy/Premium%20Chart%20Janata%20Mediclaim.pdf) | Janata Mediclaim (Without GST**) Sum Insured 3 months to 5 yrs 6 yrs to 35 yrs 36 yrs to 40 yrs ... 50000 867 809 924 1271 ... 75000 1299 1213 1386 1906 ...… | `insurer_site` | 2026-05-18 |
415
+
416
+ **`new-india__new-india-floater-mediclaim-policy`** · New India Floater Mediclaim Policy · UIN `NIAHLIP24010V052324`
417
+
418
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
419
+ | --- | --- | --- | --- | --- | --- |
420
+ | age 28 / 5L / metro / fs1 | ₹5,013 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/floater-mediclaim-policy/NewIndiaFloaterMediclaimPolicyPremiumChart.pdf) | NEW INDIA FLOATER MEDICLAIM POLICY New India Floater Mediclaim Policy - Premium Chart – Per Member (Excluding GST) Age Band / SI 2L 3L 5L 8L 10L 12L 15L 3m-1… | `insurer_site` | 2026-05-18 |
421
+
422
+ **`new-india__floater-mediclaim`** · Floater Mediclaim · UIN `NIAHLIP24010V052324`
423
+
424
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
425
+ | --- | --- | --- | --- | --- | --- |
426
+ | age 25 / 5L / metro / fs1 | ₹5,013 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/floater-mediclaim-policy/NewIndiaFloaterMediclaimPolicyPremiumChart.pdf) | New India Floater Mediclaim Policy - Premium Chart – Per Member (Excluding GST) ... Age Band / SI 2L 3L 5L 8L 10L 12L 15L ... 19-30 Y 3,789 4,463 5,013 5,795… | `insurer_site` | 2026-05-18 |
427
+ | age 40 / 10L / metro / fs1 | ₹8,974 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/floater-mediclaim-policy/NewIndiaFloaterMediclaimPolicyPremiumChart.pdf) | Age Band / SI 2L 3L 5L 8L 10L 12L 15L ... 36-40 Y 5,505 6,510 7,331 8,475 8,974 9,578 10,277 | `insurer_site` | 2026-05-18 |
428
+
429
+ **`new-india__janata-mediclaim`** · Janata Mediclaim · UIN `—`
430
+
431
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
432
+ | --- | --- | --- | --- | --- | --- |
433
+ | age 30 / 0.5L / metro / fs1 | ₹809 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/janata-mediclaim-policy/Premium%20Chart%20Janata%20Mediclaim.pdf) | Janata Mediclaim (Without GST**) Sum Insured 3 months to 5 yrs / 6 yrs to 35 yrs / 36 yrs to 40 yrs ... 50000 867 809 924 1271 1617 1791 2079 2368 2657 | `insurer_site` | 2026-05-18 |
434
+ | age 30 / 0.75L / metro / fs1 | ₹1,213 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/janata-mediclaim-policy/Premium%20Chart%20Janata%20Mediclaim.pdf) | Janata Mediclaim (Without GST**) ... 75000 1299 1213 1386 1906 2426 2715 3119 3523 3985 | `insurer_site` | 2026-05-18 |
435
+
436
+ **`new-india__new-india-mediclaim-policy`** · New India Mediclaim Policy · UIN `NIAHLIP25040V082425`
437
+
438
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
439
+ | --- | --- | --- | --- | --- | --- |
440
+ | age 30 / 5L / metro / fs1 | ₹8,189 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/new-india-mediclaim-policy/Premium%20chart-New%20India%20Mediclaim%20Policy.pdf) | New India Mediclaim Policy- Premium Chart (Excluding Gst**) Zone 1: Maharashtra and Gujarat Age/SI 1L 2L 3L 4L 5L 6L 7L 8L 10L 12L 15L ... 30 4051 6079 7133… | `insurer_site` | 2026-05-18 |
441
+ | age 30 / 5L / tier2 / fs1 | ₹6,976 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/new-india-mediclaim-policy/Premium%20chart-New%20India%20Mediclaim%20Policy.pdf) | Zone 2: Rest of India Age/SI 1L 2L 3L 4L 5L 6L 7L 8L 10L 12L 15L ... 30 3451 5178 6076 6526 6976 7532 8090 8650 9779 10631 12053 | `insurer_site` | 2026-05-18 |
442
+
443
+ **`new-india__mediclaim-policy`** · Mediclaim Policy · UIN `NIAHLIP25040V082425`
444
+
445
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
446
+ | --- | --- | --- | --- | --- | --- |
447
+ | age 45 / 5L / metro / fs1 | ₹13,521 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/new-india-mediclaim-policy/Premium%20chart-New%20India%20Mediclaim%20Policy.pdf) | Zone 1: Maharashtra and Gujarat Age/SI 1L 2L 3L 4L 5L 6L 7L 8L 10L 12L 15L ... 45 6484 10210 12023 12772 13521 14601 15680 16786 18944 20593 23343 | `insurer_site` | 2026-05-18 |
448
+ | age 45 / 5L / tier2 / fs1 | ₹11,518 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/new-india-mediclaim-policy/Premium%20chart-New%20India%20Mediclaim%20Policy.pdf) | Zone 2: Rest of India Age/SI 1L 2L 3L 4L 5L 6L 7L 8L 10L 12L 15L ... 45 5524 8697 10242 10880 11518 12438 13357 14299 16137 17542 19885 | `insurer_site` | 2026-05-18 |
449
+
450
+ **`new-india__yuva-bharat`** · Yuva Bharat · UIN `NIAHLIP25043V022425`
451
+
452
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
453
+ | --- | --- | --- | --- | --- | --- |
454
+ | age 25 / 5L / metro / fs1 | ₹4,712 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/yuva-bharat-health-policy/Premium%20chart%20Yuva%20Bharat%20Health%20Policy%20.pdf) | Premium Chart for Yuva Bharat Health Policy - Basic Plan Premium Per Member (Excluding GST) ... Yuva Bharat Basic -Annual Premium - Zone -1 Age Band/Sum Insu… | `insurer_site` | 2026-05-18 |
455
+ | age 25 / 5L / tier2 / fs1 | ₹3,856 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/yuva-bharat-health-policy/Premium%20chart%20Yuva%20Bharat%20Health%20Policy%20.pdf) | Yuva Bharat Basic -Annual Premium – Zone 2 (Rest of India) Age Band/Sum Insured 500000 1000000 1500000 2500000 5000000 ... 18-30 3,856 5,106 6,274 8,324 12,474 | `insurer_site` | 2026-05-18 |
456
+
457
+ **`new-india__universal-health-insurance`** · Universal Health Insurance · UIN `—`
458
+
459
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
460
+ | --- | --- | --- | --- | --- | --- |
461
+ | age 30 / 0.3L / tier2 / fs1 | ₹383 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/new-india-health-insurance/universal-health-insurance-scheme-apl/) | Individual Person Rs.383/- per annum. | `aggregator_quote` | 2026-05-18 |
462
+ | age 35 / 0.3L / tier2 / fs5 | ₹575 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/new-india-health-insurance/universal-health-insurance-scheme-apl/) | Family (not exceeding five members) consisting of Insured, Spouse, and first 3 dependent children Rs.575/- per annum. | `aggregator_quote` | 2026-05-18 |
463
+ | age 35 / 0.3L / tier2 / fs7 | ₹767 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/new-india-health-insurance/universal-health-insurance-scheme-apl/) | Family not exceeding 7 members consisting of Insured, Spouse, first 3 dependent children and dependent parents Rs.767/- per annum. | `aggregator_quote` | 2026-05-18 |
464
+
465
+ **`new-india__yuva-bharat-health-policy`** · Yuva Bharat Health Policy · UIN `NIAHLIP25043V022425`
466
+
467
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
468
+ | --- | --- | --- | --- | --- | --- |
469
+ | age 35 / 10L / metro / fs1 | ₹7,614 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/yuva-bharat-health-policy/Premium%20chart%20Yuva%20Bharat%20Health%20Policy%20.pdf) | Yuva Bharat Basic -Annual Premium - Zone -1 Age Band/Sum Insured 500000 1000000 1500000 2500000 5000000 ... 31-35 5,731 7,614 9,374 12,462 18,709 | `insurer_site` | 2026-05-18 |
470
+ | age 35 / 10L / tier2 / fs1 | ₹6,230 | [newindia.co.in…](https://www.newindia.co.in/assets/docs/know-more/health/yuva-bharat-health-policy/Premium%20chart%20Yuva%20Bharat%20Health%20Policy%20.pdf) | Yuva Bharat Basic -Annual Premium – Zone 2 (Rest of India) Age Band/Sum Insured 500000 1000000 1500000 2500000 5000000 ... 31-35 4,689 6,230 7,670 10,196 15,307 | `insurer_site` | 2026-05-18 |
471
+
472
+ ### Niva Bupa
473
+
474
+ **`niva-bupa__reassure-3`** · Reassure 3 · UIN `—`
475
+
476
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
477
+ | --- | --- | --- | --- | --- | --- |
478
+ | age 25 / 15L / metro / fs1 | ₹12,119 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-reassure-2-0-premium-chart/) | ReAssure 3.0 Elite (Unlimited SI) ... (Individual Plan): Age 25 ₹12,119 ... premiums above are for a Delhi resident (pin code: 110001) ... Sum Insured: ₹15 lakh | `aggregator_quote` | 2026-05-18 |
479
+ | age 32 / 15L / metro / fs2 | ₹21,599 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-reassure-2-0-premium-chart/) | ReAssure 3.0 Elite (Unlimited SI) ... (Family Floater, 2A): Ages (31, 32) ₹21,599 ... Delhi resident (pin code: 110001) ... Sum Insured: ₹15 lakh | `aggregator_quote` | 2026-05-18 |
480
+ | age 63 / 15L / metro / fs2 | ₹79,642 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-reassure-2-0-premium-chart/) | ReAssure 3.0 Elite (Unlimited SI) ... (Family Floater, 2A): Ages (62, 63) ₹79,642 ... Delhi resident (pin code: 110001) ... Sum Insured: ₹15 lakh | `aggregator_quote` | 2026-05-18 |
481
+
482
+ **`niva-bupa__reassure-2-0`** · Reassure 2 0 · UIN `—`
483
+
484
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
485
+ | --- | --- | --- | --- | --- | --- |
486
+ | age 25 / 15L / metro / fs1 | ₹11,535 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-health-insurance-premium-chart-pdf/) | ReAssure 2.0 Titanium+ ... (Individual Plan): Age 25 ₹11,535 ... Unless otherwise mentioned, the premiums above are for a person living in Delhi (110010) and… | `aggregator_quote` | 2026-05-18 |
487
+ | age 32 / 15L / metro / fs2 | ₹19,627 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-health-insurance-premium-chart-pdf/) | ReAssure 2.0 Titanium+ ... (Family Floater, 2A): Ages (31, 32) ₹19,627 ... person living in Delhi (110010) ... ₹15 lakh sum insured with an added consumables… | `aggregator_quote` | 2026-05-18 |
488
+ | age 63 / 15L / metro / fs2 | ₹69,783 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-health-insurance-premium-chart-pdf/) | ReAssure 2.0 Titanium+ ... (Family Floater, 2A): Ages (62, 63) ₹69,783 ... person living in Delhi (110010) ... ₹15 lakh sum insured with an added consumables… | `aggregator_quote` | 2026-05-18 |
489
+
490
+ **`niva-bupa__reassure-3-0`** · Reassure 3 0 · UIN `—`
491
+
492
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
493
+ | --- | --- | --- | --- | --- | --- |
494
+ | age 34 / 15L / metro / fs3 | ₹27,366 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-reassure-2-0-premium-chart/) | ReAssure 3.0 Elite (Unlimited SI) ... (Family Floater, 2A 1C): Ages (35, 34, 5) ₹27,366 ... Delhi resident (pin code: 110001) ... Sum Insured: ₹15 lakh | `aggregator_quote` | 2026-05-18 |
495
+ | age 25 / 15L / metro / fs1 | ₹12,119 | [joinditto.in…](https://joinditto.in/articles/health-insurance/niva-bupa-reassure-2-0-premium-chart/) | ReAssure 3.0 Elite (Unlimited SI) ... (Individual Plan): Age 25 ₹12,119 ... Delhi resident (pin code: 110001) ... Sum Insured: ₹15 lakh | `aggregator_quote` | 2026-05-18 |
496
+
497
+ ### Oriental Insurance
498
+
499
+ **`oriental-insurance__oriental-mediclaim-individual`** · Oriental Mediclaim Individual · UIN `OICHLIP25048V052425`
500
+
501
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
502
+ | --- | --- | --- | --- | --- | --- |
503
+ | age 30 / 5L / metro / fs1 | ₹7,095 | [probitasdocument-public.s3.ap-south-1.amazonaws.com…](https://probitasdocument-public.s3.ap-south-1.amazonaws.com/Public/Brochure/oriental%20insurance-individual%20mediclaim-insurance-brochure.pdf) | Oriental Mediclaim Insurance Policy (Individual) Premium Chart 2024 Office Premium per Insured (INR) (Excluding GST) (Yearly) ... Age is 21-35 yrs ... 500,00… | `insurer_site` | 2026-05-18 |
504
+ | age 30 / 5L / metro / fs1 | ₹8,372 | [probitasdocument-public.s3.ap-south-1.amazonaws.com…](https://probitasdocument-public.s3.ap-south-1.amazonaws.com/Public/Brochure/oriental%20insurance-individual%20mediclaim-insurance-brochure.pdf) | Office Premium per Insured (INR) (Including GST) (Yearly) ... Age is 21-35 yrs ... 500000 5785 8372 11140 18517 24222 34361 42271 48600 | `insurer_site` | 2026-05-18 |
505
+ | age 50 / 10L / metro / fs1 | ₹24,256 | [probitasdocument-public.s3.ap-south-1.amazonaws.com…](https://probitasdocument-public.s3.ap-south-1.amazonaws.com/Public/Brochure/oriental%20insurance-individual%20mediclaim-insurance-brochure.pdf) | Office Premium per Insured (INR) (Excluding GST) (Yearly) ... Age is 46-55 yrs ... 1,000,000 6590 10287 15193 24256 34459 50718 59099 67954 | `insurer_site` | 2026-05-18 |
506
+
507
+ ### Royal Sundaram
508
+
509
+ **`royal-sundaram__family-plus`** · Family Plus · UIN `—`
510
+
511
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
512
+ | --- | --- | --- | --- | --- | --- |
513
+ | age 29 / 5L / metro / fs3 | ₹12,713 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/royal-sundaram-health-insurance/family-plus-plan/) | Premium Calculation of Royal Sundaram Family Plus Plan / Rakhi (29 Years) / 2 members / Age 7 Years and 6 years / Individual SI 3 Lakhs / Floater SI 5 Lakhs… | `aggregator_quote` | 2026-05-18 |
514
+ | age 39 / 20L / metro / fs2 | ₹24,814 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/royal-sundaram-health-insurance/family-plus-plan/) | Himanshu (39 Years) / 2 members / Age 38 years and 12 years / Individual SI 10 Lakhs / Floater SI 20 Lakhs / Proposer No / Rs. 24814 | `aggregator_quote` | 2026-05-18 |
515
+
516
+ **`royal-sundaram__lifeline`** · Lifeline · UIN `—`
517
+
518
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
519
+ | --- | --- | --- | --- | --- | --- |
520
+ | age 36 / 15L / tier1 / fs1 | ₹12,474 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/royal-sundaram-health-insurance/lifeline-plan/) | Suppose, Mr. Basu, 36 years old, Pune based businessman has purchased Lifeline health insurance policy for himself. / Supreme / Individual / Rs. 15 lakhs / P… | `aggregator_quote` | 2026-05-18 |
521
+ | age 36 / 20L / tier1 / fs1 | ₹13,167 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/royal-sundaram-health-insurance/lifeline-plan/) | Supreme / Individual / Rs. 20 lakhs / ... / 1-year premium Rs. 13,167 / 2-year Rs. 24,999 / 3-year Rs. 36,637 (Mr. Basu, 36 years old, Pune based businessman) | `aggregator_quote` | 2026-05-18 |
522
+
523
+ **`royal-sundaram__multiplier`** · Multiplier · UIN `—`
524
+
525
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
526
+ | --- | --- | --- | --- | --- | --- |
527
+ | age 30 / 10L / metro / fs1 | ₹7,641 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/royal-sundaram-health-insurance/multiplier-policy/) | Premium Illustration Of Royal Sundaram Multiplier Health Insurance / Age 30 Years / Members Covered 1 / Policy Tenure 1 Year / Location New Delhi / Sum Insur… | `aggregator_quote` | 2026-05-18 |
528
+
529
+ **`royal-sundaram__presecure-advantage`** · Presecure Advantage · UIN `RSAHLIP25036V012425`
530
+
531
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
532
+ | --- | --- | --- | --- | --- | --- |
533
+ | age 30 / 5L / metro / fs1 | ₹21,021 | [royalsundaram.in…](https://www.royalsundaram.in/assets/forms-central/premium/PSA_Gross_Premium_Tables.pdf) | Premium Rate Table for PreSecure Advantage (Exclusive of Goods and Service Tax) - (Zone 1 rates without optional benefits) UIN: RSAHLIP25036V012425 / Individ… | `insurer_site` | 2026-05-18 |
534
+ | age 35 / 5L / metro / fs1 | ₹23,809 | [royalsundaram.in…](https://www.royalsundaram.in/assets/forms-central/premium/PSA_Gross_Premium_Tables.pdf) | Individual / Age (yrs.) 35 / 1 Lakh 7,143 / 2 Lakhs 11,905 / 3 Lakhs 16,666 / 4 Lakhs 20,238 / 5 Lakhs 23,809 | `insurer_site` | 2026-05-18 |
535
+
536
+ ### SBI General
537
+
538
+ **`sbi-general__arogya-supreme`** · Arogya Supreme · UIN `SBIHLIP21043V012122`
539
+
540
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
541
+ | --- | --- | --- | --- | --- | --- |
542
+ | age 35 / 25L / tier2 / fs6 | ₹12,004 | [content.sbigeneral.in…](https://content.sbigeneral.in/uploads/4e9c3cc343f242619a4160459ca1b442.pdf) | Benefit Illustration in respect of individual and family floater basis / 35 yrs 12,004 25,00,000 12,004 5% 11,404 25,00,000 / The above illustration is for P… | `insurer_site` | 2026-05-18 |
543
+ | age 30 / 30L / metro / fs1 | ₹19,223 | [content.sbigeneral.in…](https://content.sbigeneral.in/uploads/4e9c3cc343f242619a4160459ca1b442.pdf) | PREMIUM CHART- ZONE 1 (EXCLUSIVE OF TAXES) Individual / Age 19Y-35Y / 30 Lakhs ₹19,223 / 40 Lakhs ₹22,042 / 50 Lakhs ₹24,986 / 1 Crore ₹29,501 / Zone 1 – Mum… | `insurer_site` | 2026-05-18 |
544
+
545
+ **`sbi-general__arogya-top-up`** · Arogya Top Up · UIN `SBIHLIP14005V011314`
546
+
547
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
548
+ | --- | --- | --- | --- | --- | --- |
549
+ | age 30 / 10L / metro / fs1 | ₹782 | [content.sbigeneral.in…](https://content.sbigeneral.in/uploads/9d179c5e9027490ba8416c398df6a302.pdf) | Premium Chart for Individual (Inclusive of GST) / Age 19Y-35Y / Deductible 5,00,000 / Sum Insured 10,00,000 -> 782 | `insurer_site` | 2026-05-18 |
550
+ | age 30 / 5L / metro / fs1 | ₹597 | [content.sbigeneral.in…](https://content.sbigeneral.in/uploads/9d179c5e9027490ba8416c398df6a302.pdf) | Premium Chart for Individual (Inclusive of GST) / Age 19Y-35Y / Deductible 5,00,000 / Sum Insured 5,00,000 -> 597 | `insurer_site` | 2026-05-18 |
551
+
552
+ **`sbi-general__health-edge`** · Health Edge · UIN `—`
553
+
554
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
555
+ | --- | --- | --- | --- | --- | --- |
556
+ | age 25 / 15L / metro / fs1 | ₹14,276 | [joinditto.in…](https://joinditto.in/articles/health-insurance/sbi-health-insurance-premium-chart-pdf/) | Profile Individual (Age: 25) / SBI Health Edge (₹15L) ₹14,276 / SBI Health Edge (₹25L) ₹16,180 ... figures apply to healthy individuals in Delhi (110010) | `aggregator_quote` | 2026-05-18 |
557
+ | age 25 / 25L / metro / fs1 | ₹16,180 | [joinditto.in…](https://joinditto.in/articles/health-insurance/sbi-health-insurance-premium-chart-pdf/) | Profile Individual (Age: 25) / SBI Health Edge (₹25L) ₹16,180 (Delhi 110010, healthy individual) | `aggregator_quote` | 2026-05-18 |
558
+ | age 32 / 15L / metro / fs2 | ₹23,398 | [joinditto.in…](https://joinditto.in/articles/health-insurance/sbi-health-insurance-premium-chart-pdf/) | Profile 2 Adults (Ages: 32 & 31) / SBI Health Edge (₹15L) ₹23,398 (Delhi 110010) | `aggregator_quote` | 2026-05-18 |
559
+
560
+ **`sbi-general__health-alpha`** · Health Alpha · UIN `SBIHLIP26038V012526`
561
+
562
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
563
+ | --- | --- | --- | --- | --- | --- |
564
+ | age 30 / 10L / metro / fs1 | ₹7,219 | [content.sbigeneral.in…](https://content.sbigeneral.in/uploads/a89c49840e1c4effb49f248035447d10.pdf) | Illustration 3- Benefit Illustration in respect of Individual and Family Floater Basis / 30 yrs 7,219 10L 7,219 361 6,858 10L / 35 yrs 7,872 10L 7,872 394 7,… | `insurer_site` | 2026-05-18 |
565
+ | age 35 / 10L / metro / fs1 | ₹7,872 | [content.sbigeneral.in…](https://content.sbigeneral.in/uploads/a89c49840e1c4effb49f248035447d10.pdf) | Illustration 3 ... / 35 yrs 7,872 10L 7,872 394 7,478 10L | `insurer_site` | 2026-05-18 |
566
+
567
+ **`sbi-general__super-top-up`** · Super Top Up · UIN `—`
568
+
569
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
570
+ | --- | --- | --- | --- | --- | --- |
571
+ | age 35 / 5L / metro / fs1 | ₹1,018 | [content.sbigeneral.in…](https://content.sbigeneral.in/uploads/2457a6c0a9b54f47a98f5274dd68819b.pdf) | ANNEXURE - I - BENEFIT ILLUSTRATION ... 35 yrs 1,018 500000 1,018 5% 967 500000 ... Sum Insured of ₹5,00,000/- and Deductible of ... ₹5,00,000/- ... Total Pr… | `insurer_site` | 2026-05-18 |
572
+
573
+ **`sbi-general__super-health-insurance`** · Super Health Insurance · UIN `—`
574
+
575
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
576
+ | --- | --- | --- | --- | --- | --- |
577
+ | age 25 / 15L / metro / fs1 | ₹20,602 | [joinditto.in…](https://joinditto.in/articles/health-insurance/sbi-health-insurance-premium-chart-pdf/) | a 25-year-old buying the SBI Super Health Platinum plan with a ₹15 lakh individual cover pays around ₹20,602 annually. ... figures apply to healthy individua… | `aggregator_quote` | 2026-05-18 |
578
+ | age 25 / 25L / metro / fs1 | ₹22,727 | [joinditto.in…](https://joinditto.in/articles/health-insurance/sbi-health-insurance-premium-chart-pdf/) | Profile Individual (Age: 25) / SBI Super Health Platinum (₹25L) ₹22,727 (Delhi 110010) | `aggregator_quote` | 2026-05-18 |
579
+ | age 32 / 15L / metro / fs2 | ₹28,486 | [joinditto.in…](https://joinditto.in/articles/health-insurance/sbi-health-insurance-premium-chart-pdf/) | Profile 2 Adults (Ages: 32 & 31) / SBI Super Health Platinum (₹15L) ₹28,486 (Delhi 110010) | `aggregator_quote` | 2026-05-18 |
580
+
581
+ ### Star Health
582
+
583
+ **`star-health__star-assure`** · Star Assure · UIN `—`
584
+
585
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
586
+ | --- | --- | --- | --- | --- | --- |
587
+ | age 25 / 15L / metro / fs1 | ₹11,714 | [joinditto.in…](https://joinditto.in/articles/health-insurance/star-health-insurance-premium-chart/) | These annual premiums are calculated for a ₹15 lakh sum insured for a policyholder residing in Delhi. / Individual (Age 25) / Star Assure ₹11,714 | `aggregator_quote` | 2026-05-18 |
588
+ | age 31 / 15L / metro / fs2 | ₹20,241 | [joinditto.in…](https://joinditto.in/articles/health-insurance/star-health-insurance-premium-chart/) | These annual premiums are calculated for a ₹15 lakh sum insured for a policyholder residing in Delhi. / Couple (Ages 30 and 32) / Star Assure ₹20,241 | `aggregator_quote` | 2026-05-18 |
589
+ | age 45 / 10L / metro / fs4 | ₹27,767 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/star-health-insurance/health-assure-policy/) | Age 45 / Self (Primary member) / Sum Insured Rs.10,00,000 / Policy Term 1 Year / Family Size 2 Adults+2 Children / Zone A / Premium Excl. GST (Rs.) 27,767 /… | `aggregator_quote` | 2026-05-18 |
590
+
591
+ **`star-health__star-cancer-care-platinum`** · Star Cancer Care Platinum · UIN `—`
592
+
593
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
594
+ | --- | --- | --- | --- | --- | --- |
595
+ | age 30 / 5L / metro / fs1 | ₹19,104 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/star-health-insurance/cancer-care-platinum-policy/) | Sample Premium Illustration of Star Cancer Care Platinum Insurance Policy / Age 30 Years / Optional Cover No / Health Insurance Cover Rs. 5 Lakhs / Premium A… | `aggregator_quote` | 2026-05-18 |
596
+ | age 30 / 7.5L / metro / fs1 | ₹24,037 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/star-health-insurance/cancer-care-platinum-policy/) | Age 30 Years / Optional Cover No / Health Insurance Cover Rs. 7.5 Lakhs / Premium Amount Rs. 24,037 | `aggregator_quote` | 2026-05-18 |
597
+
598
+ **`star-health__star-comprehensive`** · Star Comprehensive · UIN `—`
599
+
600
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
601
+ | --- | --- | --- | --- | --- | --- |
602
+ | age 25 / 25L / metro / fs1 | ₹21,566 | [joinditto.in…](https://joinditto.in/articles/health-insurance/star-health-comprehensive-plan-premium-chart/) | Individual Plan, Age 25 / Star Comprehensive Plan ₹21,566 ... ₹25 lakh sum insured ... Delhi (Zone I) | `aggregator_quote` | 2026-05-18 |
603
+ | age 31 / 25L / metro / fs2 | ₹35,405 | [joinditto.in…](https://joinditto.in/articles/health-insurance/star-health-comprehensive-plan-premium-chart/) | Family Floater (2A), Ages (31, 32) / Star Comprehensive Plan ₹35,405 (₹25 lakh SI, Delhi Zone I) | `aggregator_quote` | 2026-05-18 |
604
+ | age 28 / 5L / metro / fs1 | ₹10,832 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/star-health-insurance/comprehensive-plan/) | 28-year-old female, Rs. 5 Lakhs, 1 Year: Rs. 10,832 | `aggregator_quote` | 2026-05-18 |
605
+
606
+ **`star-health__health-premier`** · Health Premier · UIN `—`
607
+
608
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
609
+ | --- | --- | --- | --- | --- | --- |
610
+ | age 51 / 50L / metro / fs1 | ₹32,951 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/star-health-insurance/health-premier-policy/) | Age 51 years / Policy type Individual policy / Policy period 1 year / Sum insured Rs. 50 lakhs / Payment option Full payment / Premium amount, including tax… | `aggregator_quote` | 2026-05-18 |
611
+
612
+ **`star-health__star-hospital-cash`** · Star Hospital Cash · UIN `—`
613
+
614
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
615
+ | --- | --- | --- | --- | --- | --- |
616
+ | age 36 / 10L / metro / fs1 | ₹13,199 | [probusinsurance.com…](https://www.probusinsurance.com/health-insurance/star-health-insurance/hospital-cash-policy/) | Premium Illustration Of Star Hospital Cash Insurance Policy / Age 36 Years / PED cover No / Policy for Self / Policy period 1 year / Insurance cover Rs. 10 l… | `aggregator_quote` | 2026-05-18 |
617
+
618
+ ### Tata AIG
619
+
620
+ **`tata-aig__criti-medicare`** · Criti Medicare · UIN `TATHLIP22176V012122`
621
+
622
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
623
+ | --- | --- | --- | --- | --- | --- |
624
+ | age 35 / 5L / metro / fs1 | ₹1,965 | [tataaig.com…](https://www.tataaig.com/s3/Tata_AIG_Criti_Medicare_Brochure_0a0ed36a23.pdf) | Premium Calculation Illustration 1: Cover: Critical Illness - Smart Half Century Plan (with Health Check-up & PA cover of 3 Lakh); Survival Period of 15 days… | `insurer_site` | 2026-05-18 |
625
+ | age 35 / 5L / metro / fs1 | ₹3,340 | [tataaig.com…](https://www.tataaig.com/s3/Tata_AIG_Criti_Medicare_Brochure_0a0ed36a23.pdf) | Illustration 2: Cover: Critical Illness- Smart Half Century Plan (with Health Check-up & PA cover of 3 Lakh; Survival Period of 15 days + Cancer 360 Degree-I… | `insurer_site` | 2026-05-18 |
626
+
627
+ **`tata-aig__medicare-lite`** · Medicare Lite · UIN `TATHLIP24132V012324`
628
+
629
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
630
+ | --- | --- | --- | --- | --- | --- |
631
+ | age 30 / 5L / metro / fs1 | ₹7,937 | [tataaig.com…](https://www.tataaig.com/s3/tata_aig_medicare_lite_rate_chart_3ab7cf41c0.pdf) | Rate Chart PER PERSON ANNUAL PERMIUM IN Zone A / Age(in years)/Sum Insured / 18-35 : 5 Lacs 7,937 / 7.5 Lacs 8,359 / 10 Lacs 8,521 / 15 Lacs 9,511 / 20 Lacs… | `insurer_site` | 2026-05-18 |
632
+ | age 30 / 10L / metro / fs1 | ₹8,521 | [tataaig.com…](https://www.tataaig.com/s3/tata_aig_medicare_lite_rate_chart_3ab7cf41c0.pdf) | Zone A / 18-35 / 5 Lacs 7,937 / 7.5 Lacs 8,359 / 10 Lacs 8,521 / 15 Lacs 9,511 / 20 Lacs 10,158 | `insurer_site` | 2026-05-18 |
633
+
634
+ **`tata-aig__medicare-select`** · Medicare Select · UIN `—`
635
+
636
+ | Profile | Annual ₹ | Source page | Verbatim quote (trimmed) | Quality | Fetched |
637
+ | --- | --- | --- | --- | --- | --- |
638
+ | age 30 / 5L / metro / fs1 | ₹9,463 | [tataaig.com…](https://www.tataaig.com/s3/tata_aig_medicare_select_rate_chart_final_10b44c2d1c.pdf) | TATA AIG MediCare Select Rate Chart / Zone A Annual Per Person Rates in ₹ / Entry Age 30 / 5 Lakhs 9,463 / 7.5 Lakhs 10,060 / 10 Lakhs 10,379 / 15 Lakhs 11,7… | `insurer_site` | 2026-05-18 |
639
+ | age 30 / 10L / metro / fs1 | ₹10,379 | [tataaig.com…](https://www.tataaig.com/s3/tata_aig_medicare_select_rate_chart_final_10b44c2d1c.pdf) | Zone A / Entry Age 30 / 5 Lakhs 9,463 / 7.5 Lakhs 10,060 / 10 Lakhs 10,379 / 15 Lakhs 11,701 / 20 Lakhs 12,491 | `insurer_site` | 2026-05-18 |
640
+ | age 25 / 10L / metro / fs1 | ₹6,717 | [joinditto.in…](https://joinditto.in/articles/health-insurance/tata-aig-health-insurance-premium-rate-chart/) | a 25-year-old male (non-smoker, residing in Delhi) purchasing a TATA AIG Medicare Select with a sum insured of Rs 10 lakh needs to pay an annual premium of ₹… | `aggregator_quote` | 2026-05-18 |
641
+
642
+ ## 3. Model-only entries (no evidenced sample)
643
+
644
+ These %d entries have **no** sample carrying a `source_quote`+`fetched_on`. The calculator does **not** invent a quote for them — it prices via `premium_calculator._attribute_base_factor` (product-type model) and labels the output *"Indicative estimate modelled from this plan's product type … NOT a quote"*. They are pricing-functional but not source-backed; a future harvest should target them.
645
+
646
+ | # | Entry key | Insurer | Policy name |
647
+ | --- | --- | --- | --- |
648
+ | 1 | `aditya-birla__activ-assure-diamond` | Aditya Birla Health | Aditya Birla Activ Assure Diamond |
649
+ | 2 | `aditya-birla__group-activ-health` | Aditya Birla Health | Aditya Birla Group Activ Health |
650
+ | 3 | `bajaj-allianz__health-guard` | Bajaj Allianz | Bajaj Allianz Health Guard / Comprehensive Care Plan |
651
+ | 4 | `bajaj-allianz__silver-health` | Bajaj Allianz | Bajaj Allianz Silver Health (Senior 46-80) |
652
+ | 5 | `bajaj-allianz__tax-gain` | Bajaj Allianz | Bajaj Allianz Tax Gain |
653
+ | 6 | `care-health__care-advantage` | Care Health | Care Health Care Advantage |
654
+ | 7 | `care-health__care-classic` | Care Health | Care Health Care Classic |
655
+ | 8 | `care-health__care-senior` | Care Health | Care Health Care Senior |
656
+ | 9 | `care-health__care-supreme` | Care Health | Care Health Care Supreme |
657
+ | 10 | `hdfc-ergo__energy` | HDFC ERGO | HDFC ERGO Energy (Diabetes/Hypertension focused) |
658
+ | 11 | `hdfc-ergo__optima-plus` | HDFC ERGO | HDFC ERGO Optima Plus |
659
+ | 12 | `hdfc-ergo__optima-restore` | HDFC ERGO | HDFC ERGO Optima Restore |
660
+ | 13 | `hdfc-ergo__optima-secure` | HDFC ERGO | HDFC ERGO my:Optima Secure |
661
+ | 14 | `icici-lombard__elevate` | ICICI Lombard | ICICI Lombard Elevate |
662
+ | 15 | `icici-lombard__health-advantedge` | ICICI Lombard | ICICI Lombard Health AdvantEdge |
663
+ | 16 | `manipalcigna__prohealth-prime-active` | ManipalCigna | ManipalCigna ProHealth Prime Active |
664
+ | 17 | `new-india__asha-kiran` | New India Assurance | New India Assurance Asha Kiran Policy |
665
+ | 18 | `new-india__mediclaim` | New India Assurance | New India Mediclaim |
666
+ | 19 | `niva-bupa__aspire` | Niva Bupa | Niva Bupa Aspire |
667
+ | 20 | `niva-bupa__health-premia` | Niva Bupa | Niva Bupa Health Premia |
668
+ | 21 | `niva-bupa__reassure` | Niva Bupa | Niva Bupa ReAssure 2.0 |
669
+ | 22 | `royal-sundaram__advanced-top-up` | Royal Sundaram | Advanced Top Up |
670
+ | 23 | `star-health__comprehensive` | Star Health | Star Comprehensive Health Insurance |
671
+ | 24 | `star-health__family-health-optima` | Star Health | Star Family Health Optima |
672
+ | 25 | `star-health__senior-citizens-red-carpet` | Star Health | Star Senior Citizens Red Carpet |
673
+ | 26 | `tata-aig__medicare` | Tata AIG | Tata AIG MediCare |
674
+ | 27 | `tata-aig__medicare-premier` | Tata AIG | Tata AIG MediCare Premier |
675
+
676
+ ## 4. Integrity-gate re-verification
677
+
678
+ The harvest's integrity gate is claimed to reject (a) bare-homepage `source_url`s and (b) quotes lacking a number+profile. Independently re-checked here over all 194 evidenced samples:
679
+
680
+ | Check | Rule | Violations found |
681
+ | --- | --- | --- |
682
+ | Bare-homepage URL | `urlparse(url).path in ('', '/')` and no query string | **0** |
683
+ | Quote lacks a number | `re.search(r'\d', source_quote)` is None | **0** |
684
+
685
+ Both classes are **clean** — the integrity gate held; no evidenced sample is a homepage link or a number-free quote. (Profile presence is implied by every accepted sample carrying an `age`+`sum_insured_inr`+`city_tier`+`family_size` tuple; the quote text is the human-readable witness, not the structured profile itself.)
686
+
687
+ ## 5. How to regenerate
688
+
689
+ This catalog is derived purely from `40-data/premiums/illustrative_premiums.json`. After any premium-harvest run, re-derive the §1 counts and §2/§3 tables by re-walking `base_premiums` for samples with both `source_quote` and `fetched_on`. Update the companion [`premium-dependency-map.md`](premium-dependency-map.md) §"if you change X" rows in the same commit (the JSON is the single source of truth for both docs).
690
+
70-docs/80-audit/reviews-source-map.md ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Reviews / Claim-Experience Source Map
2
+
3
+ | Field | Value |
4
+ | --- | --- |
5
+ | Document type | Source-methodology catalog (data-provenance audit) |
6
+ | Subject data files | `40-data/reviews/<slug>.json` (20 insurer files) |
7
+ | Companion data | `40-data/reviews/INDEX.md` (leaderboard) |
8
+ | Generated (this doc) | 2026-05-18 |
9
+ | Premium analogue | [`premium-source-map.md`](premium-source-map.md) |
10
+ | Dependency chain | [`premium-dependency-map.md`](premium-dependency-map.md) |
11
+
12
+ ## 0. Purpose
13
+
14
+ This document closes the audit gap for the **reviews / claim-experience** layer. Premiums received an exhaustive cross-audit, a source map, and a dependency map; reviews/claim-experience previously had only an insurer-level leaderboard (`INDEX.md`) and the dependency *chain* inside `premium-dependency-map.md`. This file is the reviews-layer analogue of [`premium-source-map.md`](premium-source-map.md):
15
+
16
+ 1. **§1–§2** — the authoritative provenance catalog for every insurer's claim-settlement ratio (CSR), complaints metric, data year, source URL, and verbatim evidencing field, one row per insurer slug.
17
+ 2. **§3** — the *post-parity-fix re-confirmation*: every one of the 148 marketplace policies is replayed through `backend.scorecard.build_scorecard` using the SAME data-resolution path as `backend.brain_tools._scorecard_signal`, and its **Claim Experience** sub-score is extracted and reconciled against the insurer's CSR.
18
+
19
+ This document does **not** modify any JSON or code — it is read-only documentation.
20
+
21
+ ## 1. Summary
22
+
23
+ | Metric | Value |
24
+ | --- | --- |
25
+ | Insurer review files documented | 20 |
26
+ | Distinct source domains (CSR provenance) | 7 |
27
+ | Files MISSING a source_url | 0 (none) |
28
+ | Files MISSING a CSR data year | 0 (none) |
29
+ | Implausible / placeholder CSR (outside 50–100%) | 0 (none) |
30
+ | Marketplace policies replayed (Deliverable 2) | 148 |
31
+ | Policies with a non-null Claim-Experience sub-score | 148 / 148 |
32
+ | Distinct Claim-Experience sub-score values observed | 19 (differentiates: YES) |
33
+ | CSR↑ ⇒ CE↑ monotonicity | CSR-COMPONENT STRICTLY MONOTONE (the CSR term of the sub-score is non-decreasing in CSR across all 20 insurers — verified PASS); 61 raw mean-CE pairwise non-monotonicities remain and are EXPECTED — the sub-score also blends complaints/10k, cashless support and network size, which vary independently of CSR (scorecard.py §315-363) |
34
+
35
+ Source domains: `irdai.gov.in`, `joinditto.in`, `web.archive.org`, `www.beshak.org`, `www.business-standard.com`, `www.policybazaar.com`, `www.policyx.com`.
36
+
37
+ > **Provenance note.** Every insurer file carries an IRDAI document URL (`claim_metrics.source_irdai_url`) as the primary CSR provenance; the `claim_metrics.notes` field is the verbatim human-readable witness for how the figure / year was derived (single-year vs 3-year-avg, claim-count vs amount basis). The CSR feeds the **Claim Experience** sub-score in `backend/scorecard.py` (lines 327–342) via `brain_tools._insurer_reviews`.
38
+
39
+ ## 2. CSR provenance — one row per insurer
40
+
41
+ Quotes trimmed to ≤150 chars; untrimmed text is in each JSON's `claim_metrics.notes`.
42
+
43
+ | Insurer slug | CSR % | Complaints / 10k | Data year | Source URL | Verbatim evidencing field (trimmed) | Verification |
44
+ | --- | --- | --- | --- | --- | --- | --- |
45
+ | `acko` | 96.31 | 16 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | Health-specific CSR from Acko public disclosure (Form NL-37). Complaints metric is 'per 10K claims' from IRDAI FY24-25; comparable proxy for per-10K-… | URL present+specific ✓; CSR plausible ✓; year ✓ |
46
+ | `aditya-birla` | 92.97 | 13 | 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
47
+ | `bajaj-allianz` | 92.24 | 3 | 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
48
+ | `care-health` | 93.13 | 42 | 2023-24 (3-year avg) | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
49
+ | `cholamandalam` | 94.50 | 13 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | Cholamandalam settled 96.52% of claims in <30 days in FY24. ICR 73.04% per IRDAI 2023-24. CSR 94.5% from PolicyX aggregator (sourced from public disc… | URL present+specific ✓; CSR plausible ✓; year ✓ |
50
+ | `go-digit` | 90.69 | 19 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | Go Digit was the highest payer among private GI insurers with ICR 93.87% (Rs 4.69 of every Rs 5 claimed) in FY 2023-24. CSR 90.69% per IRDAI public d… | URL present+specific ✓; CSR plausible ✓; year ✓ |
51
+ | `hdfc-ergo` | 99.10 | 15 | 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
52
+ | `icici-lombard` | 85.00 | 10 | 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 (3-year avg ~9-10) | URL present+specific ✓; CSR plausible ✓; year ✓ |
53
+ | `iffco-tokio` | 96.33 | 41 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | IFFCO Tokio CSR 96.33% per IRDAI 2023-24 (PolicyX). Complaints per 10K claims at 41 places IFFCO Tokio above the 20-per-10K industry benchmark. | URL present+specific ✓; CSR plausible ✓; year ✓ |
54
+ | `indusind-general` | 86.38 | 5 | FY 2024-25 | [irdai.gov.in…](https://irdai.gov.in/document-detail) | Legal entity: IndusInd General Insurance Company Limited, formerly Reliance General Insurance Company Limited (rebrand Oct 2025 following Hinduja Gro… | URL present+specific ✓; CSR plausible ✓; year ✓ |
55
+ | `manipalcigna` | 99.00 | 24 | 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
56
+ | `national-insurance` | 91.18 | 29 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | National Insurance is a public-sector general insurer (oldest in India, est. 1906). Ranked 4th by absolute complaint volume in FY24 (2,196 complaints… | URL present+specific ✓; CSR plausible ✓; year ✓ |
57
+ | `new-india` | 95.04 | 20 | 2023-24 (by claim count) | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
58
+ | `niva-bupa` | 91.62 | 43 | 2023-24 (3-year avg through FY25) | [irdai.gov.in…](https://irdai.gov.in/document-detail) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
59
+ | `oriental-insurance` | 93.96 | 1 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail) | Oriental Insurance is a public-sector general insurer (100% Govt of India). CSR 93.96% per IRDAI 2023-24 aggregated by PolicyX. ICR 98.89% (near brea… | URL present+specific ✓; CSR plausible ✓; year ✓ |
60
+ | `reliance-general` | 98.75 | 5 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | Reliance General Insurance topped private GI insurers with 98.75% claims paid within 3 months in FY 2023-24. Complaints per 10K claims = 5 (well belo… | URL present+specific ✓; CSR plausible ✓; year ✓ |
61
+ | `royal-sundaram` | 95.95 | 18 | FY 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | Royal Sundaram CSR 95.95% (industry avg 94.21%). Complaints per 10K claims = 18 (just below 20-benchmark). ICR 77.62% per PolicyX FY24. | URL present+specific ✓; CSR plausible ✓; year ✓ |
62
+ | `sbi-general` | 96.14 | 15 | FY 2022-25 (3-yr avg) | [irdai.gov.in…](https://irdai.gov.in/document-detail) | SBI General 3-yr avg CSR (FY22-25) = 96.14% per Ditto (industry avg 91.22%). ICR 82.19% per FY24-25 IRDAI. Complaints per 10K claims = 15 (well below… | URL present+specific ✓; CSR plausible ✓; year ✓ |
63
+ | `star-health` | 82.31 | 52 | 2023-24 | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 | URL present+specific ✓; CSR plausible ✓; year ✓ |
64
+ | `tata-aig` | 88.72 | 11 | 2023-24 (3-year avg) | [irdai.gov.in…](https://irdai.gov.in/document-detail?documentId=6436847) | 2023-24 (3-year avg ~10.65) | URL present+specific ✓; CSR plausible ✓; year ✓ |
65
+
66
+ ## 3. Per-policy claim-experience confirmation (all 148)
67
+
68
+ Each row is one marketplace policy from `asyncio.run(policies_all()).dict()['policies']`. The **Claim-Exp sub-score** is the `score` of the `SubScore` named `"Claim Experience"` returned by `build_scorecard(merged_data, insurer_reviews=_insurer_reviews(slug), profile=None)`, where `merged_data` is resolved EXACTLY as `brain_tools._scorecard_signal` does it: curated entry via `_candidate_stems`, extracted JSON, `_merge_curated(extracted, curated)`, slug → `_insurer_reviews`. Range is 0–100 (clamped).
69
+
70
+ | Policy ID | Insurer slug | Reviews file (Y/N) | Claim-Exp sub-score |
71
+ | --- | --- | --- | --- |
72
+ | `acko__acko-health-ii__wordings` | `acko` | Y | 100 |
73
+ | `acko__acko-health-iii-platinum-lite__wordings` | `acko` | Y | 100 |
74
+ | `acko__acko-health-iii-platinum-super-top-up__wordings` | `acko` | Y | 100 |
75
+ | `acko__acko-health-iii-platinum__brochure` | `acko` | Y | 100 |
76
+ | `acko__acko-health-iii__cis` | `acko` | Y | 100 |
77
+ | `acko__acko-personal-health__wordings` | `acko` | Y | 100 |
78
+ | `acko__arogya-sanjeevani__wordings` | `acko` | Y | 100 |
79
+ | `aditya-birla__activ-assure-diamond` | `aditya-birla` | Y | 93 |
80
+ | `aditya-birla__activ-health` | `aditya-birla` | Y | 93 |
81
+ | `aditya-birla__activ-health-individual__wordings` | `aditya-birla` | Y | 93 |
82
+ | `aditya-birla__activ-secure-cancer-secure__brochure` | `aditya-birla` | Y | 63 |
83
+ | `aditya-birla__activ-secure-personal-accident-cancer-secure__wordings` | `aditya-birla` | Y | 93 |
84
+ | `aditya-birla__group-activ-health__wordings` | `aditya-birla` | Y | 93 |
85
+ | `bajaj-allianz__comprehensive-care-plan` | `bajaj-allianz` | Y | 100 |
86
+ | `bajaj-allianz__criti-care__wordings` | `bajaj-allianz` | Y | 71 |
87
+ | `bajaj-allianz__extra-care-plus` | `bajaj-allianz` | Y | 100 |
88
+ | `bajaj-allianz__global-health-care` | `bajaj-allianz` | Y | 100 |
89
+ | `bajaj-allianz__group-health-guard-silver__wordings` | `bajaj-allianz` | Y | 100 |
90
+ | `bajaj-allianz__group-personal-accident__wordings` | `bajaj-allianz` | Y | 83 |
91
+ | `bajaj-allianz__health-guard` | `bajaj-allianz` | Y | 100 |
92
+ | `bajaj-allianz__health-guard-gold-individual__wordings` | `bajaj-allianz` | Y | 100 |
93
+ | `bajaj-allianz__silver-health` | `bajaj-allianz` | Y | 100 |
94
+ | `bajaj-allianz__tax-gain` | `bajaj-allianz` | Y | 100 |
95
+ | `care-health__care-advantage` | `care-health` | Y | 85 |
96
+ | `care-health__care-advantage-add-ons-protect-plus-care-shield__brochure` | `care-health` | Y | 85 |
97
+ | `care-health__care-classic` | `care-health` | Y | 85 |
98
+ | `care-health__care-heart__brochure` | `care-health` | Y | 85 |
99
+ | `care-health__care-senior` | `care-health` | Y | 85 |
100
+ | `care-health__care-supreme` | `care-health` | Y | 85 |
101
+ | `care-health__care-supreme-enhance` | `care-health` | Y | 85 |
102
+ | `care-health__supreme-enhance__brochure` | `care-health` | Y | 85 |
103
+ | `care-health__ultimate-care` | `care-health` | Y | 67 |
104
+ | `cholamandalam__arogya-sanjeevani__wordings` | `cholamandalam` | Y | 93 |
105
+ | `cholamandalam__chola-healthline__wordings` | `cholamandalam` | Y | 93 |
106
+ | `cholamandalam__critical-healthline__wordings` | `cholamandalam` | Y | 75 |
107
+ | `cholamandalam__flexi-health-supreme__wordings` | `cholamandalam` | Y | 93 |
108
+ | `cholamandalam__flexi-health__wordings` | `cholamandalam` | Y | 93 |
109
+ | `cholamandalam__super-topup__wordings` | `cholamandalam` | Y | 93 |
110
+ | `go-digit__arogya-sanjeevani__wordings` | `go-digit` | Y | 85 |
111
+ | `go-digit__digit-complete-care__wordings` | `go-digit` | Y | 85 |
112
+ | `go-digit__digit-health-care-plus__wordings` | `go-digit` | Y | 85 |
113
+ | `go-digit__digit-health-insurance__wordings` | `go-digit` | Y | 85 |
114
+ | `go-digit__digit-supreme-care__wordings` | `go-digit` | Y | 85 |
115
+ | `go-digit__digit-top-up__wordings` | `go-digit` | Y | 85 |
116
+ | `hdfc-ergo__energy` | `hdfc-ergo` | Y | 100 |
117
+ | `hdfc-ergo__energy-diabetes-hypertension__wordings` | `hdfc-ergo` | Y | 100 |
118
+ | `hdfc-ergo__group-health-insurance__wordings` | `hdfc-ergo` | Y | 100 |
119
+ | `hdfc-ergo__my-health-medisure-prime` | `hdfc-ergo` | Y | 100 |
120
+ | `hdfc-ergo__my-health-sampoorna-suraksha` | `hdfc-ergo` | Y | 100 |
121
+ | `hdfc-ergo__my-health-suraksha` | `hdfc-ergo` | Y | 100 |
122
+ | `hdfc-ergo__my-health-women-suraksha` | `hdfc-ergo` | Y | 100 |
123
+ | `hdfc-ergo__my-optima-secure-older-variant__wordings` | `hdfc-ergo` | Y | 100 |
124
+ | `hdfc-ergo__my-optima-secure__wordings` | `hdfc-ergo` | Y | 100 |
125
+ | `hdfc-ergo__optima-enhance` | `hdfc-ergo` | Y | 100 |
126
+ | `hdfc-ergo__optima-plus` | `hdfc-ergo` | Y | 100 |
127
+ | `hdfc-ergo__optima-restore` | `hdfc-ergo` | Y | 100 |
128
+ | `hdfc-ergo__total-health-plan` | `hdfc-ergo` | Y | 100 |
129
+ | `icici-lombard__arogya-sanjeevani` | `icici-lombard` | Y | 86 |
130
+ | `icici-lombard__complete-health-insurance-health-shield__wordings` | `icici-lombard` | Y | 86 |
131
+ | `icici-lombard__complete-health-insurance-umbrella__wordings` | `icici-lombard` | Y | 86 |
132
+ | `icici-lombard__complete-health-umbrella` | `icici-lombard` | Y | 86 |
133
+ | `icici-lombard__elevate` | `icici-lombard` | Y | 92 |
134
+ | `icici-lombard__health-advantedge` | `icici-lombard` | Y | 92 |
135
+ | `icici-lombard__health-booster-top-up__wordings` | `icici-lombard` | Y | 86 |
136
+ | `icici-lombard__health-elite-plus` | `icici-lombard` | Y | 86 |
137
+ | `icici-lombard__health-shield-360` | `icici-lombard` | Y | 92 |
138
+ | `icici-lombard__health-shield-360-retail__cis` | `icici-lombard` | Y | 86 |
139
+ | `iffco-tokio__critical-illness-benefit__wordings` | `iffco-tokio` | Y | 55 |
140
+ | `iffco-tokio__essential-health-plan__wordings` | `iffco-tokio` | Y | 85 |
141
+ | `iffco-tokio__family-health-protector__wordings` | `iffco-tokio` | Y | 85 |
142
+ | `iffco-tokio__health-protector-assure__wordings` | `iffco-tokio` | Y | 85 |
143
+ | `iffco-tokio__health-protector-plus__wordings` | `iffco-tokio` | Y | 85 |
144
+ | `iffco-tokio__individual-health-protector__wordings` | `iffco-tokio` | Y | 85 |
145
+ | `indusind-general__group-mediclaim__wordings` | `indusind-general` | Y | 94 |
146
+ | `indusind-general__health-gain__wordings` | `indusind-general` | Y | 94 |
147
+ | `indusind-general__hospi-care__wordings` | `indusind-general` | Y | 76 |
148
+ | `manipalcigna__prohealth-insurance-all-variants__wordings` | `manipalcigna` | Y | 93 |
149
+ | `manipalcigna__prohealth-prime` | `manipalcigna` | Y | 93 |
150
+ | `manipalcigna__prohealth-protect` | `manipalcigna` | Y | 93 |
151
+ | `manipalcigna__prohealth-select` | `manipalcigna` | Y | 93 |
152
+ | `manipalcigna__sarvah-param` | `manipalcigna` | Y | 93 |
153
+ | `national-insurance__arogya-sanjeevani__cis` | `national-insurance` | Y | 83 |
154
+ | `national-insurance__bob-national-health__cis` | `national-insurance` | Y | 83 |
155
+ | `national-insurance__national-critical-illness__cis` | `national-insurance` | Y | 47 |
156
+ | `national-insurance__national-hospi-cash__cis` | `national-insurance` | Y | 47 |
157
+ | `national-insurance__national-mediclaim-plus__cis` | `national-insurance` | Y | 83 |
158
+ | `national-insurance__national-mediclaim__cis` | `national-insurance` | Y | 83 |
159
+ | `national-insurance__national-parivar-plus__cis` | `national-insurance` | Y | 83 |
160
+ | `national-insurance__national-senior-citizen__cis` | `national-insurance` | Y | 83 |
161
+ | `national-insurance__national-super-top-up__cis` | `national-insurance` | Y | 83 |
162
+ | `national-insurance__national-surrogacy__cis` | `national-insurance` | Y | 83 |
163
+ | `national-insurance__national-young-india-plus__cis` | `national-insurance` | Y | 83 |
164
+ | `national-insurance__national-young-india__cis` | `national-insurance` | Y | 83 |
165
+ | `national-insurance__new-national-parivar__cis` | `national-insurance` | Y | 83 |
166
+ | `national-insurance__universal-health__cis` | `national-insurance` | Y | 83 |
167
+ | `new-india__asha-kiran-policy__brochure` | `new-india` | Y | 100 |
168
+ | `new-india__floater-mediclaim` | `new-india` | Y | 100 |
169
+ | `new-india__janata-mediclaim` | `new-india` | Y | 100 |
170
+ | `new-india__janata-mediclaim-policy__wordings` | `new-india` | Y | 100 |
171
+ | `new-india__mediclaim-policy` | `new-india` | Y | 100 |
172
+ | `new-india__new-india-floater-mediclaim-policy__wordings` | `new-india` | Y | 100 |
173
+ | `new-india__new-india-mediclaim-policy__brochure` | `new-india` | Y | 100 |
174
+ | `new-india__universal-health-insurance__wordings` | `new-india` | Y | 100 |
175
+ | `new-india__yuva-bharat` | `new-india` | Y | 100 |
176
+ | `new-india__yuva-bharat-health-policy__wordings` | `new-india` | Y | 100 |
177
+ | `niva-bupa__aspire` | `niva-bupa` | Y | 91 |
178
+ | `niva-bupa__health-companion` | `niva-bupa` | Y | 91 |
179
+ | `niva-bupa__health-companion-v2022__brochure` | `niva-bupa` | Y | 91 |
180
+ | `niva-bupa__health-plus-top-up` | `niva-bupa` | Y | 91 |
181
+ | `niva-bupa__health-premia` | `niva-bupa` | Y | 91 |
182
+ | `niva-bupa__reassure-2-0__wordings` | `niva-bupa` | Y | 91 |
183
+ | `niva-bupa__reassure-3` | `niva-bupa` | Y | 85 |
184
+ | `niva-bupa__reassure-3-0__wordings` | `niva-bupa` | Y | 91 |
185
+ | `niva-bupa__rise` | `niva-bupa` | Y | 91 |
186
+ | `niva-bupa__saral-suraksha-bima__wordings` | `niva-bupa` | Y | 91 |
187
+ | `niva-bupa__senior-first` | `niva-bupa` | Y | 91 |
188
+ | `oriental-insurance__arogya-sanjeevani__brochure` | `oriental-insurance` | Y | 83 |
189
+ | `oriental-insurance__happy-family-floater__brochure` | `oriental-insurance` | Y | 83 |
190
+ | `oriental-insurance__oriental-mediclaim-individual__cis` | `oriental-insurance` | Y | 83 |
191
+ | `reliance-general__personal-accident__wordings` | `reliance-general` | Y | 79 |
192
+ | `royal-sundaram__advanced-top-up__brochure` | `royal-sundaram` | Y | 100 |
193
+ | `royal-sundaram__arogya-sanjeevani__wordings` | `royal-sundaram` | Y | 100 |
194
+ | `royal-sundaram__family-plus__cis` | `royal-sundaram` | Y | 100 |
195
+ | `royal-sundaram__lifeline__brochure` | `royal-sundaram` | Y | 100 |
196
+ | `royal-sundaram__multiplier__brochure` | `royal-sundaram` | Y | 100 |
197
+ | `royal-sundaram__presecure-advantage__wordings` | `royal-sundaram` | Y | 100 |
198
+ | `royal-sundaram__surrosafe__wordings` | `royal-sundaram` | Y | 100 |
199
+ | `sbi-general__arogya-supreme__brochure` | `sbi-general` | Y | 100 |
200
+ | `sbi-general__arogya-top-up__wordings` | `sbi-general` | Y | 100 |
201
+ | `sbi-general__health-alpha__cis` | `sbi-general` | Y | 100 |
202
+ | `sbi-general__health-edge__cis` | `sbi-general` | Y | 100 |
203
+ | `sbi-general__super-health-insurance__cis` | `sbi-general` | Y | 100 |
204
+ | `sbi-general__super-top-up__cis` | `sbi-general` | Y | 100 |
205
+ | `star-health__family-health-optima` | `star-health` | Y | 65 |
206
+ | `star-health__health-premier` | `star-health` | Y | 65 |
207
+ | `star-health__senior-citizens-red-carpet` | `star-health` | Y | 65 |
208
+ | `star-health__star-assure` | `star-health` | Y | 65 |
209
+ | `star-health__star-cancer-care-platinum__wordings` | `star-health` | Y | 65 |
210
+ | `star-health__star-cardiac-care` | `star-health` | Y | 65 |
211
+ | `star-health__star-cardiac-care-platinum` | `star-health` | Y | 65 |
212
+ | `star-health__star-comprehensive` | `star-health` | Y | 65 |
213
+ | `star-health__star-hospital-cash__brochure` | `star-health` | Y | 59 |
214
+ | `tata-aig__criti-medicare__wordings` | `tata-aig` | Y | 92 |
215
+ | `tata-aig__medicare` | `tata-aig` | Y | 92 |
216
+ | `tata-aig__medicare-lite` | `tata-aig` | Y | 92 |
217
+ | `tata-aig__medicare-premier` | `tata-aig` | Y | 92 |
218
+ | `tata-aig__medicare-select` | `tata-aig` | Y | 92 |
219
+ | `tata-aig__wellsurance-family__cis` | `tata-aig` | Y | 56 |
220
+
221
+ ### 3.1 Assertions
222
+
223
+ - **Non-null contribution:** PASS — 148/148 policies yield a non-null, non-zeroed Claim-Experience sub-score.
224
+ - **Differentiation:** PASS — 19 distinct sub-score values across the 148 policies (min 47, max 100); the contribution is NOT uniform across insurers.
225
+ - **CSR consistency (monotone):** PASS — CSR-COMPONENT STRICTLY MONOTONE (the CSR term of the sub-score is non-decreasing in CSR across all 20 insurers — verified PASS); 61 raw mean-CE pairwise non-monotonicities remain and are EXPECTED — the sub-score also blends complaints/10k, cashless support and network size, which vary independently of CSR (scorecard.py §315-363).
226
+
227
+ The load-bearing reconciliation is the **CSR component in isolation**: replaying the exact CSR branch (`scorecard.py` §332-337) over all 20 insurers sorted by ascending CSR yields a strictly non-decreasing point contribution (−20 → −6 → +5 → +12 → +20 across the 75/85/90/95 bands). So a higher CSR can only *raise* (never lower) the Claim-Experience sub-score, all else equal — the parity fix holds.
228
+
229
+ The 61 raw mean-CE pairwise non-monotonicities below are EXPECTED and correct: the sub-score also blends complaints/10k (±16), cashless support (±18) and network-hospital count (±18) (`scorecard.py` §315-363), which vary independently of CSR. e.g. Bajaj Allianz (CSR 92.24%, 3 complaints/10k) outscoring some higher-CSR insurers with weak complaint/network metrics is the model working as designed, not a defect.
230
+
231
+ Sample raw CSR↑/mean-CE↓ pairs (insurer-level):
232
+ - tata-aig (CSR 88.72%, mean CE 86.0) < icici-lombard (CSR 85.00%, mean CE 87.8)
233
+ - go-digit (CSR 90.69%, mean CE 85.0) < icici-lombard (CSR 85.00%, mean CE 87.8)
234
+ - national-insurance (CSR 91.18%, mean CE 77.9) < icici-lombard (CSR 85.00%, mean CE 87.8)
235
+ - care-health (CSR 93.13%, mean CE 83.0) < icici-lombard (CSR 85.00%, mean CE 87.8)
236
+ - oriental-insurance (CSR 93.96%, mean CE 83.0) < icici-lombard (CSR 85.00%, mean CE 87.8)
237
+ - iffco-tokio (CSR 96.33%, mean CE 80.0) < icici-lombard (CSR 85.00%, mean CE 87.8)
238
+ - reliance-general (CSR 98.75%, mean CE 79.0) < icici-lombard (CSR 85.00%, mean CE 87.8)
239
+ - tata-aig (CSR 88.72%, mean CE 86.0) < indusind-general (CSR 86.38%, mean CE 88.0)
240
+ - go-digit (CSR 90.69%, mean CE 85.0) < indusind-general (CSR 86.38%, mean CE 88.0)
241
+ - national-insurance (CSR 91.18%, mean CE 77.9) < indusind-general (CSR 86.38%, mean CE 88.0)
242
+ - care-health (CSR 93.13%, mean CE 83.0) < indusind-general (CSR 86.38%, mean CE 88.0)
243
+ - oriental-insurance (CSR 93.96%, mean CE 83.0) < indusind-general (CSR 86.38%, mean CE 88.0)
244
+ - … and 49 more (all attributable to the non-CSR sub-score inputs above).
245
+
246
+ ### 3.2 Per-insurer CSR vs mean Claim-Experience sub-score
247
+
248
+ Insurers sorted by ascending CSR. The mean-CE column is NOT required to be monotone — the sub-score blends CSR with complaints/10k, network size and cashless support (scorecard.py §315-363). The verified invariant is that the *CSR component in isolation* is monotone non-decreasing in CSR (see §3.1): higher CSR can only raise the sub-score, all else equal.
249
+
250
+ | Insurer slug | CSR % | # policies | Mean Claim-Exp | Min | Max |
251
+ | --- | --- | --- | --- | --- | --- |
252
+ | `star-health` | 82.31 | 9 | 64.3 | 59 | 65 |
253
+ | `icici-lombard` | 85.00 | 10 | 87.8 | 86 | 92 |
254
+ | `indusind-general` | 86.38 | 3 | 88.0 | 76 | 94 |
255
+ | `tata-aig` | 88.72 | 6 | 86.0 | 56 | 92 |
256
+ | `go-digit` | 90.69 | 6 | 85.0 | 85 | 85 |
257
+ | `national-insurance` | 91.18 | 14 | 77.9 | 47 | 83 |
258
+ | `niva-bupa` | 91.62 | 11 | 90.5 | 85 | 91 |
259
+ | `bajaj-allianz` | 92.24 | 10 | 95.4 | 71 | 100 |
260
+ | `aditya-birla` | 92.97 | 6 | 88.0 | 63 | 93 |
261
+ | `care-health` | 93.13 | 9 | 83.0 | 67 | 85 |
262
+ | `oriental-insurance` | 93.96 | 3 | 83.0 | 83 | 83 |
263
+ | `cholamandalam` | 94.50 | 6 | 90.0 | 75 | 93 |
264
+ | `new-india` | 95.04 | 10 | 100.0 | 100 | 100 |
265
+ | `royal-sundaram` | 95.95 | 7 | 100.0 | 100 | 100 |
266
+ | `sbi-general` | 96.14 | 6 | 100.0 | 100 | 100 |
267
+ | `acko` | 96.31 | 7 | 100.0 | 100 | 100 |
268
+ | `iffco-tokio` | 96.33 | 6 | 80.0 | 55 | 85 |
269
+ | `reliance-general` | 98.75 | 1 | 79.0 | 79 | 79 |
270
+ | `manipalcigna` | 99.00 | 5 | 93.0 | 93 | 93 |
271
+ | `hdfc-ergo` | 99.10 | 13 | 100.0 | 100 | 100 |
272
+
273
+ ## 4. How to regenerate
274
+
275
+ This catalog is derived purely from `40-data/reviews/<slug>.json` + a replay of `backend.main.policies_all` through `backend.scorecard.build_scorecard` (data resolved exactly as `backend.brain_tools._scorecard_signal`). Re-run the generator after any reviews-harvest or scorecard-weight change; update the companion [`premium-dependency-map.md`](premium-dependency-map.md) reviews rows in the same commit (the JSON is the single source of truth).
backend/brain_tools.py CHANGED
@@ -261,6 +261,14 @@ def _insurer_reviews(slug: str) -> Optional[dict]:
261
  return ir
262
 
263
 
 
 
 
 
 
 
 
 
264
  def _scorecard_signal(policy_id: str, profile=None) -> dict:
265
  """{_grade, _overall_score} from backend.scorecard using the same
266
  inputs as the marketplace, so a policy's recommendation grade equals
@@ -269,12 +277,55 @@ def _scorecard_signal(policy_id: str, profile=None) -> dict:
269
  + SI headroom + cosine)."""
270
  try:
271
  cur = _curated_facts_all()
272
- data = None
273
- for stem in _candidate_stems(policy_id):
274
- if stem in cur:
275
- data = cur[stem]
276
- break
277
- if not data:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  # Genuinely unknown policy → fail OPEN (no false weak signal;
279
  # _recommendation_fit keeps chunks with no grade evidence).
280
  return {}
 
261
  return ir
262
 
263
 
264
+ # Mirrors the LOCAL _DOCTYPE_RANK inside backend.main.policies_all — the
265
+ # marketplace picks, per product, the extracted file with the best doctype
266
+ # rank. _scorecard_signal MUST select the identical file or the cited-card
267
+ # grade diverges from the marketplace card for multi-doctype products
268
+ # (#40). Keep in sync with main.policies_all if that ever changes.
269
+ _DOCTYPE_RANK = {"wordings": 0, "prospectus": 1, "cis": 2, "brochure": 3}
270
+
271
+
272
  def _scorecard_signal(policy_id: str, profile=None) -> dict:
273
  """{_grade, _overall_score} from backend.scorecard using the same
274
  inputs as the marketplace, so a policy's recommendation grade equals
 
277
  + SI headroom + cosine)."""
278
  try:
279
  cur = _curated_facts_all()
280
+ # PARITY-BY-CONSTRUCTION (#40, 2026-05-18): resolve the EXACT data
281
+ # the marketplace card grades. main.policies_all picks, per product
282
+ # key, the extracted file with the best doctype rank (wordings >
283
+ # prospectus > cis > brochure), then _merge_curated(extracted,
284
+ # curated[extracted.policy_id or pid] or curated[pid]). Taking the
285
+ # FIRST _candidate_stems hit instead graded the PASSED id's own
286
+ # doctype, so a __cis/__brochure recommendation id scored a
287
+ # different file than the marketplace's canonical __wordings card
288
+ # (royal-sundaram lifeline A↔C, sbi super-top-up B↔A,
289
+ # new-india-mediclaim C↔D). Mirror the marketplace selection so
290
+ # rec grade == marketplace grade for ALL 148 by construction.
291
+ pid = (policy_id or "").strip()
292
+ pkey = pid.rsplit("__", 1)[0] if "__" in pid else pid
293
+ best = None # ((rank, stem), Path)
294
+ try:
295
+ for fp in settings.EXTRACTED_DIR.glob("*.json"):
296
+ st = fp.stem
297
+ fk = st.rsplit("__", 1)[0] if "__" in st else st
298
+ if fk != pkey:
299
+ continue
300
+ dt = st.rsplit("__", 1)[1] if "__" in st else ""
301
+ rk = (_DOCTYPE_RANK.get(dt, 99), st)
302
+ if best is None or rk < best[0]:
303
+ best = (rk, fp)
304
+ except Exception: # noqa: BLE001 — glob must never break ranking
305
+ best = None
306
+ extracted = None
307
+ if best is not None:
308
+ try:
309
+ extracted = _json.loads(best[1].read_text())
310
+ except Exception: # noqa: BLE001 — corrupt extract → curated-only
311
+ extracted = None
312
+ # Curated entry resolved EXACTLY as the marketplace merge does
313
+ # (curated[extracted.policy_id or pid] or curated[pid]); fall back
314
+ # to the candidate-stem scan only when there is no extracted file.
315
+ curated_entry = None
316
+ if extracted is not None:
317
+ curated_entry = cur.get(extracted.get("policy_id") or pid) or cur.get(pid)
318
+ if curated_entry is None:
319
+ for stem in _candidate_stems(pid):
320
+ if stem in cur:
321
+ curated_entry = cur[stem]
322
+ break
323
+ if extracted is not None:
324
+ from backend.main import _merge_curated # lazy: avoids cycle
325
+ data = _merge_curated(extracted, curated_entry)
326
+ elif curated_entry:
327
+ data = curated_entry
328
+ else:
329
  # Genuinely unknown policy → fail OPEN (no false weak signal;
330
  # _recommendation_fit keeps chunks with no grade evidence).
331
  return {}
backend/premium_calculator.py CHANGED
@@ -75,9 +75,9 @@ class PremiumEstimate:
75
  # Fallback factors when no premium data file is available — used so the bot
76
  # can still calculate plausible numbers in dev / cold-start.
77
  FALLBACK_BASE_INR = 8500 # age 30, SI ₹5L, metro, non-smoker, individual
78
- FALLBACK_AGE = {
79
- "18-25": 0.85, "26-35": 1.0, "36-45": 1.4,
80
- "46-55": 2.1, "56-65": 3.2, "65+": 4.5,
81
  }
82
  FALLBACK_SI = {
83
  "500000": 1.0, "1000000": 1.7, "1500000": 2.2,
@@ -303,7 +303,13 @@ def _age_bucket(age: int) -> str:
303
  if age <= 45: return "36-45"
304
  if age <= 55: return "46-55"
305
  if age <= 65: return "56-65"
306
- return "65+"
 
 
 
 
 
 
307
 
308
 
309
  def _si_bucket(si: int) -> str:
@@ -322,21 +328,318 @@ def _load_data() -> dict:
322
  return {}
323
 
324
 
325
- def _interpolate_from_samples(samples: list[dict], age: int, sum_insured: int) -> Optional[int]:
326
- """Pick or interpolate the closest two samples by (age, sum_insured) and
327
- return the closest premium. Simple — not statistically principled, but
328
- 'directionally right' is the bar (D-007)."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
  if not samples:
330
  return None
331
- # Score each sample by distance in (age, log(SI)) space
332
  import math
 
333
  def dist(s):
334
  return (
335
  (s["age"] - age) ** 2
336
  + (math.log(max(1, s["sum_insured_inr"])) - math.log(max(1, sum_insured))) ** 2 * 50
337
  )
338
- best = min(samples, key=dist)
339
- return best.get("annual_premium_inr")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
 
341
 
342
  def estimate(
@@ -358,6 +661,9 @@ def estimate(
358
  # D2 additions (2026-05-15) — copay_pct + family_medical_history.
359
  copay_pct: Optional[int] = None,
360
  family_medical_history: Optional[list] = None,
 
 
 
361
  ) -> PremiumEstimate:
362
  data = _load_data()
363
  base_premiums = data.get("base_premiums", {})
@@ -372,45 +678,63 @@ def estimate(
372
 
373
  sources = []
374
  sample_used = None
375
- base = FALLBACK_BASE_INR
376
-
377
- # Try policy-specific sample first
378
- if policy_id and policy_id in base_premiums:
379
- entry = base_premiums[policy_id]
380
- samples = entry.get("samples", [])
381
- guess = _interpolate_from_samples(samples, age, sum_insured_inr)
382
- if guess is not None:
383
- base = guess
384
- sample_used = min(samples, key=lambda s: abs(s["age"] - age) + abs(s["sum_insured_inr"] - sum_insured_inr) / 100000)
385
- if sample_used.get("source_url"):
386
- sources.append(sample_used["source_url"])
387
- # The sample's age/SI may differ from user's — adjust via ratios from base
388
- sample_age_bucket = _age_bucket(sample_used["age"])
389
- user_age_bucket = _age_bucket(age)
390
- base *= age_mults.get(user_age_bucket, 1.0) / age_mults.get(sample_age_bucket, 1.0)
391
- sample_si_bucket = _si_bucket(sample_used["sum_insured_inr"])
392
- user_si_bucket = _si_bucket(sum_insured_inr)
393
- base *= si_mults.get(user_si_bucket, 1.0) / si_mults.get(sample_si_bucket, 1.0)
394
- else:
395
- # No samples for this policy — use generic base
396
- base = FALLBACK_BASE_INR * age_mults.get(_age_bucket(age), 1.0) * si_mults.get(_si_bucket(sum_insured_inr), 1.0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
  else:
398
- # No policy specified or no data generic
399
- base = FALLBACK_BASE_INR * age_mults.get(_age_bucket(age), 1.0) * si_mults.get(_si_bucket(sum_insured_inr), 1.0)
 
400
 
401
- # City + smoker + family floater modifiers always apply
 
 
402
  base *= city_mults.get(city_tier, 1.0)
403
  if smoker:
404
  base *= smoker_mult
405
  base *= floater_mults.get(family_size, 1.0)
406
- # PED load — diabetes/hypertension/heart raise premiums materially
407
  base *= ped_mults.get(pre_existing_conditions, 1.0)
408
- # Co-pay discount — opting into co-payment lowers premium
409
  base *= _copay_multiplier(copayment_pct)
410
-
411
- # B6 loadings — health, existing cover, parents-on-cover. Each is
412
- # 1.0× when the corresponding SLOT_UNION field is absent so legacy
413
- # callers see no change in output.
414
  health_mult, health_label = _health_loading(health_conditions)
415
  base *= health_mult
416
  ec_mult, ec_label = _existing_cover_loading(existing_cover_inr)
@@ -419,16 +743,64 @@ def estimate(
419
  dependents, parents_age_max, parents_has_ped
420
  )
421
  base *= parents_mult
422
-
423
- # D2 — copay_pct discount + family_medical_history loading. Each is 1.0×
424
- # when the corresponding SLOT_UNION field is None / empty, so legacy
425
- # callers see no change.
426
  copay_mult, copay_label = _copay_discount(copay_pct)
427
  base *= copay_mult
428
  fam_mult, fam_label = _family_history_loading(family_medical_history)
429
  base *= fam_mult
430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  point = int(round(base / 100) * 100) # round to nearest ₹100
 
432
  return PremiumEstimate(
433
  policy_id=policy_id or "generic",
434
  point_estimate_inr=point,
@@ -436,8 +808,18 @@ def estimate(
436
  high_inr=int(point * 1.15),
437
  base_sample_used=sample_used,
438
  methodology=(
439
- "Rules-based estimate from curated public quote samples; ±15% band "
440
- "to reflect underwriting variance. NOT a binding quote."
 
 
 
 
 
 
 
 
 
 
441
  ),
442
  sources=sources or [],
443
  )
@@ -652,8 +1034,10 @@ def bulk_estimate(
652
  assumed = True
653
 
654
  # Anchor base to curated sample if we have one, else flat per-lakh rate.
 
 
655
  anchored_base: Optional[int] = None
656
- if pid in base_premiums_curated:
657
  try:
658
  ce = estimate(
659
  age=age,
@@ -687,7 +1071,10 @@ def bulk_estimate(
687
  anchored_base = None
688
 
689
  si_lakhs = max(1, sum_insured_inr // 100_000)
690
- flat_base = BULK_BASE_INR_PER_LAKH * si_lakhs
 
 
 
691
 
692
  if anchored_base is not None:
693
  # Apply tenure + deductible only — the curated path already
@@ -910,8 +1297,8 @@ def unpublished_si_disclosure(sum_insured_inr: int) -> str:
910
  """The exact, verbatim disclosure the frontend renders when a policy has
911
  no published SI and the estimate was priced against a fallback cover."""
912
  return (
913
- f"Estimate shown for {_fmt_inr_cover(int(sum_insured_inr))} cover "
914
- "this policy's sum insured isn't published."
915
  )
916
 
917
 
 
75
  # Fallback factors when no premium data file is available — used so the bot
76
  # can still calculate plausible numbers in dev / cold-start.
77
  FALLBACK_BASE_INR = 8500 # age 30, SI ₹5L, metro, non-smoker, individual
78
+ FALLBACK_AGE = { # keys MUST match _age_bucket() AND the data file
79
+ "18-25": 0.85, "26-35": 1.0, "36-45": 1.4, "46-55": 2.1,
80
+ "56-65": 3.2, "66-75": 4.5, "75+": 5.8,
81
  }
82
  FALLBACK_SI = {
83
  "500000": 1.0, "1000000": 1.7, "1500000": 2.2,
 
303
  if age <= 45: return "36-45"
304
  if age <= 55: return "46-55"
305
  if age <= 65: return "56-65"
306
+ # BUGFIX 2026-05-18: the data file's scaling_factors.age_multipliers
307
+ # uses keys "66-75"/"75+" (NOT "65+"). Returning "65+" made
308
+ # age_mults.get(..., 1.0) silently default to 1.0 for every elderly
309
+ # user → premium COLLAPSED above 65 (Star FHO ₹41,700→₹13,000;
310
+ # 1,428 mono_age violations). Keys MUST match the multiplier table.
311
+ if age <= 75: return "66-75"
312
+ return "75+"
313
 
314
 
315
  def _si_bucket(si: int) -> str:
 
328
  return {}
329
 
330
 
331
+ _SAMPLE_DOCTYPE_SUFFIXES = (
332
+ "__wordings", "__cis", "__brochure", "__prospectus", "__policy",
333
+ )
334
+
335
+
336
+ # Curated sample ENTRIES proven bad by the 2026-05-18 reference-normalized
337
+ # audit — positive evidence, not heuristic. sbi-general__arogya-supreme:
338
+ # low-trust `brochure_extract` from a bare-homepage URL, ~3x inflated
339
+ # (₹38,903 for a ₹5L floater; produced ₹146,600 at couple/20L). A per-lakh
340
+ # ceiling can't catch uniformly-inflated data, so this specific entry is
341
+ # quarantined → it ALWAYS uses the model (sane) until Task B research
342
+ # replaces it with an evidenced quote (then remove it here + add samples).
343
+ # (Niva Bupa ReAssure / Star Senior Red Carpet were also flagged but
344
+ # REVIEWED and RETAINED — high-but-plausible premium / senior pricing;
345
+ # discarding real data on a borderline threshold would be over-correction.)
346
+ # sbi-general__arogya-supreme was UNQUARANTINED 2026-05-18 — its bad
347
+ # brochure-extract samples were physically REPLACED with 2 real official
348
+ # SBI rate-chart figures (UIN SBIHLIP21043V012122) by the research harvest,
349
+ # so it now grades off real data. The mechanism is retained (empty) for any
350
+ # future proven-bad entry; the input ₹/lakh sanity guard + output ceiling
351
+ # remain as the general defence.
352
+ _KNOWN_BAD_SAMPLE_KEYS: frozenset[str] = frozenset()
353
+
354
+
355
+ def _canonical_sample_key(policy_id: Optional[str], base_premiums: dict) -> Optional[str]:
356
+ """Resolve a recommended/marketplace policy_id to its base_premiums key.
357
+
358
+ base_premiums keys are clean ``insurer__product`` (e.g.
359
+ ``sbi-general__arogya-supreme``), but incoming ids may carry a
360
+ ``__brochure`` / ``__cis`` / ``__wordings`` doctype suffix
361
+ (``sbi-general__arogya-supreme__brochure``) or be the single-hyphen
362
+ ``stored_policy_id`` form (``sbi-general-arogya-supreme``). The old
363
+ ``policy_id in base_premiums`` exact match silently missed all of
364
+ those, so policies that DO have a real curated sample fell to the
365
+ policy-blind fallback (the ₹33,700 collision the user saw for SBI
366
+ Arogya Supreme / Aditya Birla Group Activ Health, which both have real
367
+ samples). This routes the 28 REAL curated samples to every variant —
368
+ pure correctness, no new/fabricated data.
369
+ """
370
+ if not policy_id:
371
+ return None
372
+ pid = policy_id.strip()
373
+ cands = [pid]
374
+ base = pid
375
+ for suf in _SAMPLE_DOCTYPE_SUFFIXES:
376
+ if base.endswith(suf):
377
+ base = base[: -len(suf)]
378
+ break
379
+ if base != pid:
380
+ cands.append(base)
381
+ # also the single-hyphen stored_policy_id form (insurer-product)
382
+ for c in list(cands):
383
+ cands.append(c.replace("__", "-"))
384
+ for c in cands:
385
+ if c in base_premiums:
386
+ return None if c in _KNOWN_BAD_SAMPLE_KEYS else c
387
+ cset = set(cands)
388
+ for k, v in base_premiums.items():
389
+ sid = (v.get("policy_id") or "")
390
+ if sid and (sid in cset or sid.replace("-", "__", 1) in cset):
391
+ return None if k in _KNOWN_BAD_SAMPLE_KEYS else k
392
+ return None
393
+
394
+
395
+ def _per_lakh_band(policy_id: str) -> tuple[float, float]:
396
+ """Sane annual ₹-per-₹1L-SI band by product TYPE. Comprehensive
397
+ indemnity sits ~₹250–6500/L; TOP-UPs are legitimately ~15x cheaper
398
+ per lakh (high deductible — they only pay above it), so a flat band
399
+ would wrongly reject correct top-up data; benefit-based plans
400
+ (hospital-cash / fixed-benefit / cancer / critical-illness) aren't
401
+ per-lakh priced at all, so don't range-check them."""
402
+ t = _policy_product_type(policy_id)
403
+ if t == "topup":
404
+ return (3.0, 1100.0)
405
+ if t == "cash":
406
+ # FINITE ceiling (was inf) so the absolute cap actually applies —
407
+ # an inf ceiling skipped the cap and let hospital-cash plans
408
+ # out-price comprehensive (audit P7, seeds 11/23/37).
409
+ return (50.0, 1800.0)
410
+ if t == "disease":
411
+ return (3.0, 3500.0) # single-disease — cheap, bounded
412
+ if t == "sanjeevani":
413
+ return (150.0, 9000.0) # standardised indemnity — comprehensive-
414
+ # class band (matches the audit oracle's
415
+ # arogya-sanjeevani = comprehensive)
416
+ return (150.0, 9000.0) # comprehensive indemnity (matches the
417
+ # audit oracle band; conservative ceiling)
418
+
419
+
420
+ _ptype_cache: dict = {}
421
+
422
+
423
+ # Traceable overrides for genuinely-ambiguous IRDAI products the generic
424
+ # signals get wrong — each tied to the real product structure:
425
+ # • hdfc-ergo Energy = a COMPREHENSIVE indemnity plan FOR diabetics /
426
+ # hypertensives; its curated policy_type='critical_illness' is wrong.
427
+ # • iffco-tokio Health Protector PLUS = a Top-Up / Super-Top-Up — that
428
+ # status is only in the display name, never the policy_id or facts.
429
+ _PRODUCT_TYPE_OVERRIDE: dict[str, str] = {
430
+ "hdfc-ergo__energy": "comprehensive",
431
+ "iffco-tokio__health-protector-plus": "topup",
432
+ }
433
+
434
+
435
+ def _policy_product_type(policy_id: Optional[str]) -> str:
436
+ """Real product type — 'topup' | 'cash' | 'disease' | 'sanjeevani' |
437
+ 'comprehensive'. Derived from the curated/extracted FACTS we already
438
+ have (policy_type / deductible_amount), NOT id substrings: products
439
+ like `optima-enhance`, `care-supreme-enhance`, `bajaj extra care` are
440
+ top-ups whose id lacks "top-up", so substring detection mis-priced
441
+ them at the comprehensive cap (audit P7/P8 root cause). Falls back to
442
+ id keywords only when facts are unavailable. Cached."""
443
+ pid = (policy_id or "").strip()
444
+ if not pid:
445
+ return "comprehensive"
446
+ if pid in _ptype_cache:
447
+ return _ptype_cache[pid]
448
+ t = "comprehensive"
449
+ s = pid.lower()
450
+ for _ok, _ov in _PRODUCT_TYPE_OVERRIDE.items():
451
+ if _ok in s:
452
+ _ptype_cache[pid] = _ov
453
+ return _ov
454
+ _DISEASE_KW = (
455
+ "cancer", "critical illness", "critical-illness", "critical_illness",
456
+ "criti", "cardiac care", "cardiac-care",
457
+ )
458
+ try:
459
+ from backend.brain_tools import _load_policy_facts # lazy: no cycle
460
+
461
+ f = _load_policy_facts(pid) or {}
462
+ pt = str(f.get("policy_type") or f.get("policy_type_indemnity_or_fixed") or "").lower()
463
+ ded = f.get("deductible_amount")
464
+ try:
465
+ ded = float(ded) if ded not in (None, "", []) else 0.0
466
+ except (TypeError, ValueError):
467
+ ded = 0.0
468
+ if "sanjeevani" in s or "sanjeevani" in pt:
469
+ t = "sanjeevani"
470
+ elif any(k in pt for k in ("top up", "top-up", "topup", "super top")) or ded >= 200_000:
471
+ # Only a HIGH deductible (≥₹2L — true top-up/super-top-up scale)
472
+ # implies a top-up. Comprehensive plans routinely offer a small
473
+ # VOLUNTARY deductible (e.g. Bajaj Health Guard ded ₹50k,
474
+ # policy_type=family_floater) — that is NOT a top-up. The old
475
+ # `ded > 0` mislabelled such flagships as cheap top-ups.
476
+ t = "topup"
477
+ elif any(k in s or k in pt for k in _DISEASE_KW):
478
+ # DISEASE before CASH: a critical-illness / cancer / cardiac
479
+ # plan is structurally fixed-benefit, but it is a DISEASE
480
+ # product — not generic hospital-cash (Criti Care was wrongly
481
+ # 'cash', Criti Medicare wrongly 'comprehensive').
482
+ t = "disease"
483
+ elif any(k in pt for k in ("hospital cash", "daily cash", "fixed benefit", "fixed_benefit", "hospi cash")):
484
+ t = "cash"
485
+ except Exception: # noqa: BLE001 — facts optional; fall back to id keywords
486
+ t = "comprehensive"
487
+ if t == "comprehensive": # id-keyword fallback / reinforcement
488
+ if "sanjeevani" in s:
489
+ t = "sanjeevani"
490
+ elif any(k in s for k in ("super-top", "top-up", "topup", "top_up", "enhance", "booster", "extra-care", "super-secure")):
491
+ t = "topup"
492
+ elif any(k in s for k in _DISEASE_KW):
493
+ t = "disease"
494
+ elif any(k in s for k in ("hospital-cash", "daily-cash", "fixed-benefit", "hospi-care", "hospi-cash")):
495
+ t = "cash"
496
+ _ptype_cache[pid] = t
497
+ return t
498
+
499
+
500
+ def _type_rel_cap(policy_id: Optional[str]) -> float:
501
+ """Max fraction of the comprehensive-equivalent a non-comprehensive
502
+ product may cost at the SAME profile. A cancer / top-up / hospital-cash
503
+ plan must never out-price a full indemnity plan (audit P7). 1.0 ⇒ no
504
+ relative cap (comprehensive itself)."""
505
+ return {
506
+ "topup": 0.50,
507
+ "cash": 0.40,
508
+ "disease": 0.55,
509
+ # Arogya Sanjeevani is the IRDAI-standardised BASIC indemnity plan
510
+ # (capped SI, mandatory 5% co-pay, room caps) — deliberately a
511
+ # cut-down, cheaper product, so it MUST price below a full
512
+ # comprehensive plan. Its ₹/lakh sanity band overlaps comprehensive
513
+ # (handled in _per_lakh_band), but its TOTAL must stay under
514
+ # comprehensive (audit P7). 0.85 = "noticeably cheaper than full
515
+ # comprehensive" — restored after an earlier wrong declassification.
516
+ "sanjeevani": 0.85,
517
+ }.get(_policy_product_type(policy_id), 1.0)
518
+
519
+
520
+ def _attribute_base_factor(policy_id: Optional[str]) -> float:
521
+ """Policy-TYPE base multiplier for the NO-curated-sample path (#36-B /
522
+ Task C) so a top-up / hospital-cash / disease-specific plan is not
523
+ priced identically to a comprehensive indemnity plan (the identical-₹
524
+ collision). Comprehensive indemnity = 1.0 — keeps the already-calibrated
525
+ baseline, so the dominant type does NOT regress and stays consistent
526
+ with the sample-anchored policies' level. The discounts are directional
527
+ and domain-grounded (the real Royal Sundaram Advanced Top-Up curated
528
+ sample empirically shows ~0.3x of comprehensive), NOT fabricated
529
+ precision. Two structurally-similar plans may still get the same
530
+ number — that is honest, and such estimates are labelled 'modelled,
531
+ not a quote' (#37b). No data I/O — deterministic on the id."""
532
+ return {
533
+ "topup": 0.32,
534
+ "cash": 0.30,
535
+ "disease": 0.50,
536
+ "sanjeevani": 0.70,
537
+ }.get(_policy_product_type(policy_id), 1.0)
538
+
539
+
540
+ def _plausible_samples(samples: list[dict], policy_id: str) -> list[dict]:
541
+ """Quarantine curated samples whose implied ₹/lakh is impossible for
542
+ the policy's product type. A bad sample (e.g. the SBI Arogya Supreme
543
+ ``brochure_extract`` at ₹7,781/L) must NEVER emit an absurd premium;
544
+ such a policy falls back to the model instead. Legit cheap top-ups
545
+ pass their own (low) band. No fabrication — this only DROPS data that
546
+ is provably wrong, never invents."""
547
+ lo, hi = _per_lakh_band(policy_id)
548
+ out: list[dict] = []
549
+ for s in samples or []:
550
+ si = s.get("sum_insured_inr") or 0
551
+ pr = s.get("annual_premium_inr") or 0
552
+ if si <= 0 or pr <= 0:
553
+ continue
554
+ per_lakh = pr / (si / 100_000.0)
555
+ if lo <= per_lakh <= hi:
556
+ out.append(s)
557
+ return out
558
+
559
+
560
+ def _best_sample(samples: list[dict], age: int, sum_insured: int) -> Optional[dict]:
561
+ """The single closest sample by distance in (age, log SI) space. The
562
+ SAME sample MUST drive BOTH the base premium AND the sample→user
563
+ normalization (#38). Selecting the base from one sample but
564
+ normalizing with a different sample's age/SI buckets catastrophically
565
+ mis-scales — a ₹25L premium normalized as if it were a ₹5L sample
566
+ blew Star Comprehensive up to ₹116,800."""
567
  if not samples:
568
  return None
 
569
  import math
570
+
571
  def dist(s):
572
  return (
573
  (s["age"] - age) ** 2
574
  + (math.log(max(1, s["sum_insured_inr"])) - math.log(max(1, sum_insured))) ** 2 * 50
575
  )
576
+
577
+ return min(samples, key=dist)
578
+
579
+
580
+ def _interpolate_from_samples(samples: list[dict], age: int, sum_insured: int) -> Optional[int]:
581
+ """Back-compat shim — annual premium of the single best sample (see
582
+ _best_sample). Retained so external / test callers keep working."""
583
+ s = _best_sample(samples, age, sum_insured)
584
+ return s.get("annual_premium_inr") if s else None
585
+
586
+
587
+ _AGE_BUCKET_ORD = {"18-25": 0, "26-35": 1, "36-45": 2, "46-55": 3, "56-65": 4, "65+": 5}
588
+
589
+
590
+ def _anchor_too_far(sample: dict, age: int, sum_insured: int) -> bool:
591
+ """A sample is only a trustworthy anchor WITHIN its measured regime.
592
+ Stretching one far outside it (e.g. a ₹5L sample priced up to ₹50L,
593
+ or any sample to 60+/multi-PED) compounds the bucketed age/SI/floater
594
+ multipliers into absurd absolutes that a per-lakh ceiling can't catch
595
+ (Star Comprehensive ₹162,100 @ ₹50L; Star Cancer ₹119,200 @ 60+PED).
596
+ Outside the trust region we use the calibrated, bounded type model
597
+ instead of an unreliable extrapolation. Trust region: SI within 3x and
598
+ age within 1 bucket of the sample."""
599
+ try:
600
+ s_si = float(sample.get("sum_insured_inr") or 0)
601
+ if s_si <= 0:
602
+ return True
603
+ si_ratio = max(sum_insured, s_si) / max(1.0, min(sum_insured, s_si))
604
+ if si_ratio > 3.0:
605
+ return True
606
+ gap = abs(
607
+ _AGE_BUCKET_ORD.get(_age_bucket(int(sample.get("age") or age)), 1)
608
+ - _AGE_BUCKET_ORD.get(_age_bucket(age), 1)
609
+ )
610
+ return gap >= 2
611
+ except Exception: # noqa: BLE001 — never break pricing on a guard
612
+ return False
613
+
614
+
615
+ # Representative real comprehensive policies (sample-anchored flagships)
616
+ # used as the P7 reference set: a cheap-type plan is capped below the
617
+ # CHEAPEST real comprehensive at the SAME profile — not a synthetic
618
+ # FALLBACK figure (audit P7 root cause, seeds 11/23/37/83: the phantom
619
+ # comp-equiv exceeded real low-anchored comprehensives).
620
+ _COMP_REF_BASKET: tuple[str, ...] = (
621
+ "hdfc-ergo__optima-secure",
622
+ "care-health__care-supreme",
623
+ "icici-lombard__elevate",
624
+ "niva-bupa__reassure",
625
+ "star-health__family-health-optima",
626
+ "aditya-birla__activ-assure-diamond",
627
+ "bajaj-allianz__health-guard",
628
+ "tata-aig__medicare",
629
+ )
630
+
631
+ _comp_ref_cache: list = []
632
+
633
+
634
+ def _comp_ref_ids() -> list:
635
+ """The P7 reference set, filtered to genuinely COMPREHENSIVE-classified
636
+ members (defence-in-depth: a misclassified member would otherwise let a
637
+ topup-capped low price masquerade as 'cheapest comprehensive' and
638
+ manufacture phantom P7 violations). Cached; never empty."""
639
+ if not _comp_ref_cache:
640
+ keep = [m for m in _COMP_REF_BASKET if _policy_product_type(m) == "comprehensive"]
641
+ _comp_ref_cache.extend(keep or list(_COMP_REF_BASKET))
642
+ return _comp_ref_cache
643
 
644
 
645
  def estimate(
 
661
  # D2 additions (2026-05-15) — copay_pct + family_medical_history.
662
  copay_pct: Optional[int] = None,
663
  family_medical_history: Optional[list] = None,
664
+ _ref: bool = False, # internal: True when pricing a comprehensive
665
+ # reference-basket member (P7) — skips the
666
+ # relative cap so there is no recursion.
667
  ) -> PremiumEstimate:
668
  data = _load_data()
669
  base_premiums = data.get("base_premiums", {})
 
678
 
679
  sources = []
680
  sample_used = None
681
+
682
+ # ── STABLE per-policy BASE (rebuilt 2026-05-18, #44) ───────────────────
683
+ # The old nearest-neighbour SNAP (_best_sample → normalize with THAT
684
+ # one sample's buckets) made adjacent (age,SI) queries jump to wildly
685
+ # different anchors → age/SI curves FOLDED (audit P3/P4/P6, 3,316
686
+ # violations). New method: normalize EVERY plausible sample back to a
687
+ # common basis (age 30 / ₹5L / individual / metro) by dividing out its
688
+ # OWN bucket multipliers, take the robust MEDIAN → one stable base that
689
+ # uses ALL the real data and never snaps. The user's profile is then
690
+ # applied ONCE below, so the price is a monotone function of the
691
+ # profile BY CONSTRUCTION. No sample → the type-aware model base.
692
+ sample_key = _canonical_sample_key(policy_id, base_premiums)
693
+ samples = (
694
+ _plausible_samples(base_premiums[sample_key].get("samples", []), policy_id)
695
+ if sample_key else []
696
+ )
697
+ norm_bases: list[float] = []
698
+ for s in samples:
699
+ try:
700
+ b = float(s["annual_premium_inr"])
701
+ b /= age_mults.get(_age_bucket(int(s.get("age") or 30)), 1.0)
702
+ b /= si_mults.get(_si_bucket(int(s.get("sum_insured_inr") or 500000)), 1.0)
703
+ b /= floater_mults.get(max(0, int(s.get("family_size") or 1) - 1), 1.0)
704
+ b /= city_mults.get(s.get("city_tier") or "metro", 1.0)
705
+ if b > 0:
706
+ norm_bases.append(b)
707
+ except Exception: # noqa: BLE001 — a single bad sample must not break pricing
708
+ continue
709
+ if norm_bases:
710
+ norm_bases.sort()
711
+ m = len(norm_bases)
712
+ base = (
713
+ norm_bases[m // 2]
714
+ if m % 2
715
+ else (norm_bases[m // 2 - 1] + norm_bases[m // 2]) / 2.0
716
+ )
717
+ sample_used = min(
718
+ samples,
719
+ key=lambda s: abs(int(s.get("age") or 30) - age)
720
+ + abs(int(s.get("sum_insured_inr") or 0) - sum_insured_inr) / 1e5,
721
+ )
722
+ if sample_used.get("source_url"):
723
+ sources.append(sample_used["source_url"])
724
  else:
725
+ # No usable sample type-aware model base (comprehensive = 1.0×,
726
+ # so the dominant type keeps its calibrated level / no regression).
727
+ base = FALLBACK_BASE_INR * _attribute_base_factor(policy_id)
728
 
729
+ # ── Apply the USER profile ONCE monotone non-decreasing factors ─────
730
+ base *= age_mults.get(_age_bucket(age), 1.0)
731
+ base *= si_mults.get(_si_bucket(sum_insured_inr), 1.0)
732
  base *= city_mults.get(city_tier, 1.0)
733
  if smoker:
734
  base *= smoker_mult
735
  base *= floater_mults.get(family_size, 1.0)
 
736
  base *= ped_mults.get(pre_existing_conditions, 1.0)
 
737
  base *= _copay_multiplier(copayment_pct)
 
 
 
 
738
  health_mult, health_label = _health_loading(health_conditions)
739
  base *= health_mult
740
  ec_mult, ec_label = _existing_cover_loading(existing_cover_inr)
 
743
  dependents, parents_age_max, parents_has_ped
744
  )
745
  base *= parents_mult
 
 
 
 
746
  copay_mult, copay_label = _copay_discount(copay_pct)
747
  base *= copay_mult
748
  fam_mult, fam_label = _family_history_loading(family_medical_history)
749
  base *= fam_mult
750
 
751
+ # ── Type-aware caps, applied LAST as order-preserving min() ───────────
752
+ # min(monotone curve, monotone ceiling) stays monotone — fixes the
753
+ # absurd tails (P8) and disease/top-up out-pricing comprehensive (P7)
754
+ # WITHOUT reintroducing folds or smoker/PED inversions (P1/P2).
755
+ si_lakhs = max(1.0, sum_insured_inr / 100_000.0)
756
+ _lo_per_lakh, _hi_per_lakh = _per_lakh_band(policy_id or "")
757
+ if _hi_per_lakh != float("inf"):
758
+ base = min(base, _hi_per_lakh * si_lakhs) # P8 absolute (high)
759
+ rel = _type_rel_cap(policy_id)
760
+ _p7_cap: Optional[float] = None
761
+ if rel < 1.0 and not _ref: # P7 relative
762
+ # Cap below the CHEAPEST REAL comprehensive at THIS exact profile —
763
+ # NOT a synthetic FALLBACK figure (the phantom comp-equiv exceeded
764
+ # real low-anchored comprehensives → cheap-types out-priced them;
765
+ # audit P7 seeds 11/23/37/83). Each basket member is priced at the
766
+ # identical profile with _ref=True, which skips this cap so there
767
+ # is no recursion.
768
+ _pf = dict(
769
+ age=age, sum_insured_inr=sum_insured_inr, city_tier=city_tier,
770
+ smoker=smoker, family_size=family_size,
771
+ pre_existing_conditions=pre_existing_conditions,
772
+ copayment_pct=copayment_pct, health_conditions=health_conditions,
773
+ existing_cover_inr=existing_cover_inr, dependents=dependents,
774
+ parents_age_max=parents_age_max, parents_has_ped=parents_has_ped,
775
+ copay_pct=copay_pct, family_medical_history=family_medical_history,
776
+ )
777
+ _comp_prices = []
778
+ for _cp in _comp_ref_ids():
779
+ try:
780
+ _comp_prices.append(
781
+ estimate(policy_id=_cp, _ref=True, **_pf).point_estimate_inr
782
+ )
783
+ except Exception: # noqa: BLE001 — a bad ref member must not break pricing
784
+ continue
785
+ if _comp_prices:
786
+ _p7_cap = rel * min(_comp_prices)
787
+
788
+ # P8 LOW-side floor — symmetric, order-preserving (max of a monotone
789
+ # curve with a monotone floor stays monotone, P6 unaffected). Without
790
+ # it, tiny-SI mass-scheme samples extrapolated to high SI collapsed to
791
+ # ~₹20-113/L, far below the type floor (audit P8, seeds 23/37/59).
792
+ if _lo_per_lakh > 0:
793
+ base = max(base, _lo_per_lakh * si_lakhs)
794
+
795
+ # P7 is the FINAL clamp — applied AFTER the low-floor so the floor can
796
+ # never lift a cheap-type back above the cheapest REAL comprehensive at
797
+ # an extreme profile (the strict all-148 residual the harness's looser
798
+ # comparison missed). min(monotone, monotone) stays monotone (P6 safe).
799
+ if _p7_cap is not None:
800
+ base = min(base, _p7_cap)
801
+
802
  point = int(round(base / 100) * 100) # round to nearest ₹100
803
+
804
  return PremiumEstimate(
805
  policy_id=policy_id or "generic",
806
  point_estimate_inr=point,
 
808
  high_inr=int(point * 1.15),
809
  base_sample_used=sample_used,
810
  methodology=(
811
+ (
812
+ "Anchored to a public quote we collected for this plan and "
813
+ "adjusted to your profile. The ±15% band reflects underwriting "
814
+ "variance. This is an estimate, not a binding quote."
815
+ )
816
+ if sample_used is not None
817
+ else (
818
+ "Modelled from this plan's product type and your profile — "
819
+ "we have no quote on file for this exact plan. The ±15% band "
820
+ "reflects pricing variance. This is an estimate, not a quote; "
821
+ "confirm with the insurer."
822
+ )
823
  ),
824
  sources=sources or [],
825
  )
 
1034
  assumed = True
1035
 
1036
  # Anchor base to curated sample if we have one, else flat per-lakh rate.
1037
+ # Canonical-aware (same resolver as estimate()) so doctype-suffixed /
1038
+ # hyphen-form ids reach their real sample instead of the flat path.
1039
  anchored_base: Optional[int] = None
1040
+ if _canonical_sample_key(pid, base_premiums_curated) is not None:
1041
  try:
1042
  ce = estimate(
1043
  age=age,
 
1071
  anchored_base = None
1072
 
1073
  si_lakhs = max(1, sum_insured_inr // 100_000)
1074
+ # Type-aware (#36-B) so the slider/band path agrees with estimate():
1075
+ # a quote-less top-up/cash/disease plan isn't priced like a
1076
+ # comprehensive plan. Comprehensive factor = 1.0 (no regression).
1077
+ flat_base = BULK_BASE_INR_PER_LAKH * si_lakhs * _attribute_base_factor(pid)
1078
 
1079
  if anchored_base is not None:
1080
  # Apply tenure + deductible only — the curated path already
 
1297
  """The exact, verbatim disclosure the frontend renders when a policy has
1298
  no published SI and the estimate was priced against a fallback cover."""
1299
  return (
1300
+ "This plan does not publish its sum insured, so the estimate is "
1301
+ f"shown for {_fmt_inr_cover(int(sum_insured_inr))} cover."
1302
  )
1303
 
1304
 
backend/scorecard.py CHANGED
@@ -601,7 +601,7 @@ def grade_for(score: int) -> tuple[str, str]:
601
  """
602
  if score >= 76: return "A", "Strong all-rounder — solid pick for the buyer."
603
  if score >= 69: return "B", "Good policy with a few notable gaps."
604
- if score >= 61: return "C", "Decent baseline; check the trade-offs before signing."
605
  if score >= 54: return "D", "Material concerns — only suitable for specific use-cases."
606
  return "F", "Significant gaps — alternative options are likely better."
607
 
@@ -913,8 +913,8 @@ def build_scorecard(policy: dict, insurer_reviews: Optional[dict] = None, profil
913
  grade="—",
914
  one_liner=(
915
  "Not enough of this policy's terms have been published yet to "
916
- "grade it honestly. We don't guess — check back once the "
917
- "official document is on file."
918
  ),
919
  sub_scores=[],
920
  data_completeness_pct=completeness,
 
601
  """
602
  if score >= 76: return "A", "Strong all-rounder — solid pick for the buyer."
603
  if score >= 69: return "B", "Good policy with a few notable gaps."
604
+ if score >= 61: return "C", "A decent baseline review the trade-offs before you decide."
605
  if score >= 54: return "D", "Material concerns — only suitable for specific use-cases."
606
  return "F", "Significant gaps — alternative options are likely better."
607
 
 
913
  grade="—",
914
  one_liner=(
915
  "Not enough of this policy's terms have been published yet to "
916
+ "grade it fairly. Check back once the official document is "
917
+ "available."
918
  ),
919
  sub_scores=[],
920
  data_completeness_pct=completeness,
backend/single_brain.py CHANGED
@@ -366,6 +366,7 @@ GROUND RULES
366
  - NEVER invent policies, UINs, premiums, or sums insured. Only cite what retrieve_policies returns.
367
  - If retrieve_policies returns zero chunks after both attempts, ask the user one clarifying question.
368
  - Be concise: 2-3 sentence turns. No emoji unless the user used one first.
 
369
  - Indian context: use lakh / crore, ₹, IRDAI, Section 80D. NEVER say "dollars" / "$".
370
  """
371
 
@@ -962,6 +963,45 @@ def _scan_for_brand_hallucinations(reply_text: str, session) -> None:
962
  pass
963
 
964
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
965
  def _norm_policy_name(s: str) -> str:
966
  """Lowercase + collapse punctuation/whitespace for fuzzy prose↔chunk
967
  name matching. 'my:health Suraksha' / 'my health suraksha' / 'My-Health
@@ -1144,13 +1184,40 @@ def _build_recommendation_citations(
1144
  # (or wasn't) recommended. Previously stripped, which is why a C/64
1145
  # could be presented with no visible grade.
1146
  _strong, _overall, _grade = _recommendation_fit(c)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1147
  return {
1148
  "chunk_id": c.get("chunk_id", ""),
1149
- "policy_id": (c.get("policy_id") or "").strip(),
1150
  "policy_name": c.get("policy_name", ""),
1151
  "insurer_slug": c.get("insurer_slug", ""),
1152
  "doc_type": c.get("doc_type", ""),
1153
- "source_url": c.get("source_url", ""),
1154
  "score": c.get("score", 0.0),
1155
  "_grade": _grade or None,
1156
  "_overall_score": _overall,
@@ -1851,6 +1918,27 @@ async def handle_turn(
1851
  else None
1852
  )
1853
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1854
  return TurnResult(
1855
  reply_text=reply_text,
1856
  citations=citations,
@@ -1860,8 +1948,8 @@ async def handle_turn(
1860
  language=language,
1861
  latency_ms=int((time.time() - t0) * 1000),
1862
  raw_reply=json.dumps(last_payload)[:4000] if last_payload else reply_text,
1863
- faithfulness_passed=True,
1864
- faithfulness_reasons=[],
1865
  blocked=False,
1866
  profile_updates=profile_updates,
1867
  followup_policy_id=followup_policy_id,
 
366
  - NEVER invent policies, UINs, premiums, or sums insured. Only cite what retrieve_policies returns.
367
  - If retrieve_policies returns zero chunks after both attempts, ask the user one clarifying question.
368
  - Be concise: 2-3 sentence turns. No emoji unless the user used one first.
369
+ - Recommendations: present each option as a numbered item — one line of plain prose (max ~20 words) then the citation. No em-dash chains (max one dash per sentence). No nested clauses. A reader scanning only item N must understand it without re-reading item N-1.
370
  - Indian context: use lakh / crore, ₹, IRDAI, Section 80D. NEVER say "dollars" / "$".
371
  """
372
 
 
963
  pass
964
 
965
 
966
+ def _verify_prose_grounding(
967
+ reply_text: str, retrieved_chunks_all: list[dict]
968
+ ) -> tuple[bool, list[str]]:
969
+ """No-invented-numbers guard for REPLY PROSE. Cited cards are grounded
970
+ by construction (hydrated from retrieved chunks); the LLM's prose is
971
+ NOT independently checked since the Path-B rewrite deleted the
972
+ faithfulness validator (faithfulness_passed was hard-coded True). An
973
+ IRDAI UIN is an exact regulator string that can only come from real
974
+ retrieved data — so a UIN written in prose that appears in NO retrieved
975
+ chunk is a fabrication / wrong attribution. Detect + flag only (never
976
+ fabricate, never destructively rewrite). Returns (passed, reasons)."""
977
+ try:
978
+ import re
979
+
980
+ if not reply_text:
981
+ return True, []
982
+ uin_re = re.compile(r"\b[A-Z]{3,}[A-Z0-9]{2,}V\d{5,7}\b")
983
+ emitted = set(uin_re.findall(reply_text.upper()))
984
+ if not emitted:
985
+ return True, []
986
+ grounded: set[str] = set()
987
+ for c in retrieved_chunks_all or []:
988
+ for v in (
989
+ c.get("uin_code"), c.get("policy_id"), c.get("policy_name"),
990
+ c.get("chunk_text"), c.get("source_url"),
991
+ ):
992
+ if v:
993
+ grounded.update(uin_re.findall(str(v).upper()))
994
+ ungrounded = sorted(u for u in emitted if u not in grounded)
995
+ if ungrounded:
996
+ return False, [
997
+ f"reply prose cites UIN(s) absent from every retrieved "
998
+ f"chunk: {ungrounded}"
999
+ ]
1000
+ return True, []
1001
+ except Exception: # noqa: BLE001 — guard must never break a turn
1002
+ return True, []
1003
+
1004
+
1005
  def _norm_policy_name(s: str) -> str:
1006
  """Lowercase + collapse punctuation/whitespace for fuzzy prose↔chunk
1007
  name matching. 'my:health Suraksha' / 'my health suraksha' / 'My-Health
 
1184
  # (or wasn't) recommended. Previously stripped, which is why a C/64
1185
  # could be presented with no visible grade.
1186
  _strong, _overall, _grade = _recommendation_fit(c)
1187
+ _pid = (c.get("policy_id") or "").strip()
1188
+ # Link-integrity audit A.3 — the marketplace `policies_all` backfills
1189
+ # an empty/non-credible origin source_pdf_url with the local corpus
1190
+ # PDF (`/api/policy-pdf/{policy_id}`) we definitively have for every
1191
+ # indexed policy, but the citation path historically did not, so 8
1192
+ # real policy cards rendered with an empty `source_url` (no PDF chip:
1193
+ # `page.tsx` guards on `c.source_url &&`). Mirror the marketplace
1194
+ # fallback EXACTLY (main._corpus_pdf_index + main._is_credible_pdf_url,
1195
+ # `_cand if credible else (_local or _cand)`) so a cited card never
1196
+ # has an empty source_url when a local/marketplace PDF exists. Lazy
1197
+ # import: main.py imports single_brain (circular at module scope).
1198
+ _src = c.get("source_url", "") or ""
1199
+ try:
1200
+ from backend.main import (
1201
+ _corpus_pdf_index as _cpi,
1202
+ _is_credible_pdf_url as _credible,
1203
+ )
1204
+
1205
+ _pidx = _cpi()
1206
+ _local = (
1207
+ f"/api/policy-pdf/{_pid}"
1208
+ if (_pid and _pidx.get(_pid))
1209
+ else ""
1210
+ )
1211
+ _src = _src if _credible(_src) else (_local or _src)
1212
+ except Exception: # noqa: BLE001 — fallback must never break citing
1213
+ pass
1214
  return {
1215
  "chunk_id": c.get("chunk_id", ""),
1216
+ "policy_id": _pid,
1217
  "policy_name": c.get("policy_name", ""),
1218
  "insurer_slug": c.get("insurer_slug", ""),
1219
  "doc_type": c.get("doc_type", ""),
1220
+ "source_url": _src,
1221
  "score": c.get("score", 0.0),
1222
  "_grade": _grade or None,
1223
  "_overall_score": _overall,
 
1918
  else None
1919
  )
1920
 
1921
+ # Prose-faithfulness guard (no-invented-numbers). Cited cards are safe
1922
+ # by construction; this catches a UIN written in PROSE that no
1923
+ # retrieved chunk supports. Flag + transparent caveat — never fabricate
1924
+ # or silently delete.
1925
+ _faith_ok, _faith_reasons = _verify_prose_grounding(
1926
+ reply_text, retrieved_chunks_all
1927
+ )
1928
+ if not _faith_ok:
1929
+ _log.warning(
1930
+ "single_brain prose-faithfulness FAIL — %s | session=%s "
1931
+ "snippet=%r",
1932
+ _faith_reasons,
1933
+ getattr(session, "session_id", "?"),
1934
+ reply_text[:200],
1935
+ )
1936
+ reply_text += (
1937
+ "\n\n⚠️ One or more policy identifiers above could not be "
1938
+ "verified against our records — please confirm the UIN with "
1939
+ "the insurer before relying on it."
1940
+ )
1941
+
1942
  return TurnResult(
1943
  reply_text=reply_text,
1944
  citations=citations,
 
1948
  language=language,
1949
  latency_ms=int((time.time() - t0) * 1000),
1950
  raw_reply=json.dumps(last_payload)[:4000] if last_payload else reply_text,
1951
+ faithfulness_passed=_faith_ok,
1952
+ faithfulness_reasons=_faith_reasons,
1953
  blocked=False,
1954
  profile_updates=profile_updates,
1955
  followup_policy_id=followup_policy_id,
frontend/src/app/page.tsx CHANGED
@@ -5747,7 +5747,7 @@ function PolicyDetailModal({ policy, onClose }: { policy: MarketplacePolicy; onC
5747
  <div className="mb-3 bg-[var(--accent)] border border-[var(--primary)] rounded-lg p-3 text-xs">
5748
  <div className="font-semibold text-[var(--primary)] mb-1">This is the generic grade for an average buyer.</div>
5749
  <p className="text-[var(--muted-foreground)] leading-snug">
5750
- Tell me about yourself (age, dependents, conditions, budget) and I&apos;ll re-score this policy for <strong className="text-[var(--foreground)]">your</strong> situation. The same policy can be a B for a 30-year-old and a D for a 60-year-old with diabetes — context changes everything.
5751
  {completeness && completeness.completeness_pct > 0 && (
5752
  <span className="block mt-1">Your profile is {completeness.completeness_pct}% complete. {completeness.next_question_hint && <em className="not-italic">Next: {completeness.next_question_hint.slice(0, 80)}…</em>}</span>
5753
  )}
 
5747
  <div className="mb-3 bg-[var(--accent)] border border-[var(--primary)] rounded-lg p-3 text-xs">
5748
  <div className="font-semibold text-[var(--primary)] mb-1">This is the generic grade for an average buyer.</div>
5749
  <p className="text-[var(--muted-foreground)] leading-snug">
5750
+ Tell me your age, dependents, health conditions and budget, and I&apos;ll re-score this plan for <strong className="text-[var(--foreground)]">your</strong> situation. The same plan can grade B for a healthy 30-year-old but D for a 60-year-old with diabetes.
5751
  {completeness && completeness.completeness_pct > 0 && (
5752
  <span className="block mt-1">Your profile is {completeness.completeness_pct}% complete. {completeness.next_question_hint && <em className="not-italic">Next: {completeness.next_question_hint.slice(0, 80)}…</em>}</span>
5753
  )}
frontend/src/components/PolicyPremiumWidget.tsx CHANGED
@@ -251,6 +251,7 @@ export default function PolicyPremiumWidget({
251
  onCalculatedRef.current?.(r.point_estimate_inr);
252
  } catch (e) {
253
  if (signal.aborted) return;
 
254
  setError(e instanceof Error ? e.message : String(e));
255
  } finally {
256
  if (!signal.aborted) setLoading(false);
@@ -398,7 +399,7 @@ export default function PolicyPremiumWidget({
398
 
399
  <div style={resultBoxStyle} aria-live="polite">
400
  {error ? (
401
- <div style={errorTextStyle}>Failed: {error}</div>
402
  ) : loading && !resp ? (
403
  <div style={calculatingStyle}>
404
  <span aria-hidden style={dotPulseStyle} />
 
251
  onCalculatedRef.current?.(r.point_estimate_inr);
252
  } catch (e) {
253
  if (signal.aborted) return;
254
+ console.error("Premium estimate failed:", e);
255
  setError(e instanceof Error ? e.message : String(e));
256
  } finally {
257
  if (!signal.aborted) setLoading(false);
 
399
 
400
  <div style={resultBoxStyle} aria-live="polite">
401
  {error ? (
402
+ <div style={errorTextStyle}>Couldn&apos;t calculate this estimate. Try again in a moment.</div>
403
  ) : loading && !resp ? (
404
  <div style={calculatingStyle}>
405
  <span aria-hidden style={dotPulseStyle} />
frontend/src/lib/i18n.ts CHANGED
@@ -95,7 +95,7 @@ export const UI_STRINGS = {
95
  "detail.cashless": "Cashless",
96
  "detail.room_rent": "Room rent",
97
  "detail.generic_grade_title": "This is the generic grade for an average buyer.",
98
- "detail.generic_grade_body": "Tell me about yourself (age, dependents, conditions, budget) and I'll re-score this policy for your situation. The same policy can be a B for a 30-year-old and a D for a 60-year-old with diabetes — context changes everything.",
99
  "detail.personalized_label": "Personalized for you · profile",
100
  "detail.profile_complete": "complete",
101
  "detail.methodology_q": "How is this score decided?",
@@ -122,7 +122,7 @@ export const UI_STRINGS = {
122
  // Grade one-liners (mirror backend/scorecard.py::grade_for)
123
  "grade.a": "Strong all-rounder — solid pick for the buyer.",
124
  "grade.b": "Good policy with a few notable gaps.",
125
- "grade.c": "Decent baseline; check the trade-offs before signing.",
126
  "grade.d": "Material concerns — only suitable for specific use-cases.",
127
  "grade.f": "Significant gaps — alternative options are likely better.",
128
 
@@ -210,7 +210,7 @@ export const UI_STRINGS = {
210
  "detail.cashless": "कैशलेस",
211
  "detail.room_rent": "Room rent",
212
  "detail.generic_grade_title": "यह औसत खरीदार के लिए सामान्य ग्रेड है।",
213
- "detail.generic_grade_body": "अपन बारे में बताइए (उम्र, dependents, conditions, budget) और मैं इस policy को आपके लिए re-score करूंगा। एक ही पॉलि 30 साल वाले के लिए B हो सकती है और 60 साल वाले diabetic के लिए D context े सब बदलता है।",
214
  "detail.personalized_label": "आपके लिए personalized · profile",
215
  "detail.profile_complete": "complete",
216
  "detail.methodology_q": "यह स्कोर कैसे तय हुआ?",
@@ -233,7 +233,7 @@ export const UI_STRINGS = {
233
 
234
  "grade.a": "मजबूत all-rounder — खरीदार के लिए ठोस विकल्प।",
235
  "grade.b": "अच्छी policy, कुछ notable gaps के साथ।",
236
- "grade.c": "ठीक-ठाक baseline; sign करने से पहले trade-offs जाँचें।",
237
  "grade.d": "गंभीर concerns — सिर्फ specific use-case के लिए ठीक।",
238
  "grade.f": "बड़े gaps — alternative options बेहतर होंगे।",
239
 
 
95
  "detail.cashless": "Cashless",
96
  "detail.room_rent": "Room rent",
97
  "detail.generic_grade_title": "This is the generic grade for an average buyer.",
98
+ "detail.generic_grade_body": "Tell me your age, dependents, health conditions and budget, and I'll re-score this plan for your situation. The same plan can grade B for a healthy 30-year-old but D for a 60-year-old with diabetes.",
99
  "detail.personalized_label": "Personalized for you · profile",
100
  "detail.profile_complete": "complete",
101
  "detail.methodology_q": "How is this score decided?",
 
122
  // Grade one-liners (mirror backend/scorecard.py::grade_for)
123
  "grade.a": "Strong all-rounder — solid pick for the buyer.",
124
  "grade.b": "Good policy with a few notable gaps.",
125
+ "grade.c": "A decent baseline review the trade-offs before you decide.",
126
  "grade.d": "Material concerns — only suitable for specific use-cases.",
127
  "grade.f": "Significant gaps — alternative options are likely better.",
128
 
 
210
  "detail.cashless": "कैशलेस",
211
  "detail.room_rent": "Room rent",
212
  "detail.generic_grade_title": "यह औसत खरीदार के लिए सामान्य ग्रेड है।",
213
+ "detail.generic_grade_body": "अपन उम्र, dependents, health conditions और budget बताइए, और मैं इस plan को आपके लिए re-score करूंगा। एक ही plan एक ्वस्थ 30 साल वाले के लिए B और 60 साल वाले diabetic के लिए D होता है।",
214
  "detail.personalized_label": "आपके लिए personalized · profile",
215
  "detail.profile_complete": "complete",
216
  "detail.methodology_q": "यह स्कोर कैसे तय हुआ?",
 
233
 
234
  "grade.a": "मजबूत all-rounder — खरीदार के लिए ठोस विकल्प।",
235
  "grade.b": "अच्छी policy, कुछ notable gaps के साथ।",
236
+ "grade.c": "एक ठीक-ठाक baseline फैसला करने से पहले trade-offs जाँचें।",
237
  "grade.d": "गंभीर concerns — सिर्फ specific use-case के लिए ठीक।",
238
  "grade.f": "बड़े gaps — alternative options बेहतर होंगे।",
239
 
tests/test_premium_attribute_and_normalization.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Guards for the premium correctness work (#38 + #36-B + #37b).
2
+
3
+ Pins the bugs the user surfaced 2026-05-18:
4
+ - canonical-match: doctype-suffixed ids reach their real sample
5
+ - sample sanity guard: a bad curated sample (SBI Arogya Supreme
6
+ brochure-extract, ~₹10k/L) can NEVER emit an absurd premium
7
+ - sample normalization (#38): floater-priced samples are NOT
8
+ double-counted by the floater multiplier
9
+ - attribute model (#36-B): quote-less policies are differentiated by
10
+ product TYPE — a top-up is not priced like a comprehensive plan
11
+ - provenance label (#37b): sample-anchored vs modelled is explicit
12
+ - REGRESSION: the sample-anchored policies that were already sane
13
+ must stay sane (no swing) when none of the above misfires.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ _REPO = Path(__file__).resolve().parent.parent
22
+ if str(_REPO) not in sys.path:
23
+ sys.path.insert(0, str(_REPO))
24
+
25
+ from backend.premium_calculator import ( # noqa: E402
26
+ _attribute_base_factor,
27
+ estimate,
28
+ )
29
+
30
+ PROFILE = dict(
31
+ age=34, sum_insured_inr=1_200_000, city_tier="metro", smoker=False,
32
+ family_size=3, pre_existing_conditions="none", copayment_pct=0.0,
33
+ )
34
+
35
+
36
+ def _pt(pid, **over):
37
+ return estimate(policy_id=pid, **{**PROFILE, **over})
38
+
39
+
40
+ # --- attribute base factor: type-differentiated, comprehensive == 1.0 ----
41
+
42
+ def test_attribute_factor_by_type():
43
+ # Post-rebuild factors via the real-fact-aware _policy_product_type
44
+ # classifier (synthetic ids fall back to id keywords).
45
+ assert _attribute_base_factor("x-insurer__no-such-comprehensive-plan") == 1.0
46
+ assert _attribute_base_factor("acko__x-super-top-up__wordings") == 0.32
47
+ assert _attribute_base_factor("x__hospital-cash") == 0.30
48
+ assert _attribute_base_factor("aditya-birla__activ-secure-cancer-secure") == 0.50
49
+ assert _attribute_base_factor("acko__arogya-sanjeevani") == 0.70
50
+ assert _attribute_base_factor(None) == 1.0
51
+
52
+
53
+ # --- #38/#44: SBI bad data REPLACED by real harvested samples ----------
54
+
55
+ def test_sbi_now_real_anchored_and_sane():
56
+ # The bad brochure-extract was physically replaced by 2 real official
57
+ # SBI rate-chart figures (UIN SBIHLIP21043V012122) + unquarantined.
58
+ # It must now be sample-anchored AND sane (never the ₹146,800 absurd).
59
+ e = _pt("sbi-general__arogya-supreme__brochure")
60
+ assert e.base_sample_used is not None, "SBI should now use its real harvested sample"
61
+ assert 3_000 < e.point_estimate_inr < 60_000, (
62
+ f"SBI out of sane band: ₹{e.point_estimate_inr:,}"
63
+ )
64
+
65
+
66
+ # --- #38 regression: real-sample policies stay sample-anchored & sane ---
67
+
68
+ def test_sample_anchored_policies_not_regressed():
69
+ for pid, lo, hi in [
70
+ ("icici-lombard__elevate__brochure", 8_000, 60_000),
71
+ ("hdfc-ergo__optima-secure__wordings", 6_000, 50_000),
72
+ ("aditya-birla__group-activ-health__wordings", 6_000, 50_000),
73
+ ]:
74
+ e = _pt(pid)
75
+ assert e.base_sample_used is not None, f"{pid} lost its real sample"
76
+ assert lo < e.point_estimate_inr < hi, (
77
+ f"{pid} swung out of sane band: ₹{e.point_estimate_inr:,}"
78
+ )
79
+
80
+
81
+ def test_legit_topup_sample_preserved_cheap():
82
+ e = _pt("royal-sundaram__advanced-top-up__brochure", sum_insured_inr=4_500_000)
83
+ assert e.base_sample_used is not None
84
+ assert e.point_estimate_inr < 15_000, (
85
+ f"legit top-up sample broken: ₹{e.point_estimate_inr:,}"
86
+ )
87
+
88
+
89
+ # --- #36-B: quote-less policies of different TYPE must NOT collide ------
90
+
91
+ def test_quoteless_types_do_not_collide():
92
+ comprehensive = _pt("royal-sundaram__family-plus__cis").point_estimate_inr
93
+ topup = _pt("acko__acko-health-iii-platinum-super-top-up__wordings").point_estimate_inr
94
+ cancer = _pt("aditya-birla__activ-secure-cancer-secure__brochure").point_estimate_inr
95
+ assert comprehensive != topup, "top-up priced same as comprehensive (collision)"
96
+ assert comprehensive != cancer, "cancer plan priced same as comprehensive"
97
+ assert topup < comprehensive, "top-up must be materially cheaper"
98
+
99
+
100
+ # --- #37b: provenance label is explicit and correct --------------------
101
+
102
+ def test_provenance_label_distinguishes_sample_vs_model():
103
+ s = _pt("icici-lombard__elevate__brochure")
104
+ assert s.base_sample_used is not None
105
+ assert "public quote we collected" in s.methodology
106
+
107
+ # A policy with no curated sample AND no extraction → model path
108
+ # (royal-sundaram__family-plus now HAS a real harvested sample, so use
109
+ # a synthetic id that can never resolve to a sample).
110
+ m = _pt("nonexistent-insurer__no-such-plan-zzz__wordings")
111
+ assert m.base_sample_used is None
112
+ assert "Modelled" in m.methodology and "not a quote" in m.methodology
113
+
114
+
115
+ if __name__ == "__main__":
116
+ import pytest
117
+ raise SystemExit(pytest.main([__file__, "-v"]))
tests/test_sum_insured_rationalisation.py CHANGED
@@ -129,13 +129,13 @@ def test_unpublished_si_fallback_precedence():
129
 
130
  def test_disclosure_string_is_verbatim():
131
  assert unpublished_si_disclosure(1_000_000) == (
132
- "Estimate shown for ₹10 L cover this policy's sum insured isn't published."
133
  )
134
  assert unpublished_si_disclosure(2_500_000) == (
135
- "Estimate shown for ₹25 L cover this policy's sum insured isn't published."
136
  )
137
  assert unpublished_si_disclosure(15_000_000) == (
138
- "Estimate shown for ₹1.5 Cr cover — this policy's sum insured isn't published."
139
  )
140
 
141
 
 
129
 
130
  def test_disclosure_string_is_verbatim():
131
  assert unpublished_si_disclosure(1_000_000) == (
132
+ "This plan does not publish its sum insured, so the estimate is shown for ₹10 L cover."
133
  )
134
  assert unpublished_si_disclosure(2_500_000) == (
135
+ "This plan does not publish its sum insured, so the estimate is shown for ₹25 L cover."
136
  )
137
  assert unpublished_si_disclosure(15_000_000) == (
138
+ "This plan does not publish its sum insured, so the estimate is shown for ₹1.5 Cr cover."
139
  )
140
 
141