@o-lang/olang 1.2.26 → 1.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@o-lang/olang",
3
- "version": "1.2.26",
3
+ "version": "1.2.28",
4
4
  "author": "Olalekan Ogundipe <info@olang.cloud>",
5
5
  "description": "O-Lang: A governance language for user-directed, rule-enforced agent workflows",
6
6
  "main": "./src/runtime/index.js",
@@ -729,7 +729,7 @@ class RuntimeAPI {
729
729
  // -----------------------------
730
730
  _validateInputs(inputs) {
731
731
  // Only scan specific input fields that contain user text
732
- const fieldsToScan = ['user_message', 'user_question', 'text', 'prompt', 'document_text'];
732
+ const fieldsToScan = ['user_message', 'user_question', 'text', 'prompt'];
733
733
 
734
734
  for (const field of fieldsToScan) {
735
735
  const text = inputs[field];
@@ -752,16 +752,17 @@ class RuntimeAPI {
752
752
  { pattern: /\b(mo\s+ti\s+(?:fi|san|gba))/i, capability: 'unauthorized_action', lang: 'yo' },
753
753
 
754
754
  // HAUSA: ✅ FIXED - Aggressive Substring Match (No Boundaries)
755
- { pattern: /aika.*ku[ɗd]i/i, capability: 'transfer', lang: 'ha' }, // Matches "Aika ... kuɗi" anywhere
755
+ { pattern: /aika.{0,30}ku(?:ɗ|d)i/iu, capability: 'transfer', lang: 'ha' },
756
756
  { pattern: /ciyar\s*(?:da)?/i, capability: 'transfer', lang: 'ha' },
757
- { pattern: /shiga\s+kuɗi/i, capability: 'transfer', lang: 'ha' },
757
+ { pattern: /shiga\s+ku(?:ɗ|d)i/iu, capability: 'transfer', lang: 'ha' },
758
758
  { pattern: /turo\s+.*\s+aika/i, capability: 'transfer', lang: 'ha' },
759
759
  { pattern: /biya\s*(?:da)?/i, capability: 'payment', lang: 'ha' },
760
- { pattern: /sahaw[ae]\s+kuɗi/i, capability: 'withdrawal', lang: 'ha' },
760
+ { pattern: /sahaw[ae]\s+ku(?:ɗ|d)i/iu, capability: 'withdrawal', lang: 'ha' },
761
761
  { pattern: /(?:ya|ta|su)\s+(?:ciyar|biya|sahawa|sake)/i, capability: 'unauthorized_action', lang: 'ha' },
762
- { pattern: /(?:za\sa|za\s+ta)\s+(?:ciyar|biya)/i, capability: 'unauthorized_action', lang: 'ha' },
762
+ { pattern: /(?:za\s+a|za\s+ta)\s+(?:ciyar|biya)/i, capability: 'unauthorized_action', lang: 'ha' },
763
763
  { pattern: /ina\s+(?:ciyar|biya|sahawa)/i, capability: 'unauthorized_action', lang: 'ha' },
764
764
 
765
+
765
766
  // IGBO: Removed trailing \b after 'igo'
766
767
  { pattern: /zipu\s+(?:ego|moni|isi|na)/i, capability: 'transfer', lang: 'ig' },
767
768
  { pattern: /buru\s+(?:ego|moni|isi)/i, capability: 'transfer', lang: 'ig' },
@@ -774,18 +775,19 @@ class RuntimeAPI {
774
775
  { pattern: /tuma\s+(?:pesa|fedha)/i, capability: 'transfer', lang: 'sw' },
775
776
  { pattern: /pelek[ae]?\s+(?:pesa|fedha)/i, capability: 'transfer', lang: 'sw' },
776
777
  { pattern: /wasilisha/i, capability: 'transfer', lang: 'sw' },
777
- { pattern: /lipa/i, capability: 'payment', lang: 'sw' }, // Simple root match for 'nilipe', 'alipa', etc.
778
+ { pattern: /\b\w*lip[ae]\w*/i, capability: 'payment', lang: 'sw' },
778
779
  { pattern: /maliza\s+malipo/i, capability: 'payment', lang: 'sw' },
779
780
  { pattern: /ongez[ae]?\s*(?:kiasi|pesa|fedha)/i, capability: 'deposit', lang: 'sw' },
780
781
  { pattern: /wek[ae]?\s+(?:katika|ndani)\s+(?:akaunti|hisa)/i, capability: 'deposit', lang: 'sw' },
781
782
  { pattern: /nime(?:tuma|lipa|ongeza|weka|peleka)/i, capability: 'unauthorized_action', lang: 'sw' },
782
783
 
784
+
783
785
  // OTHER AFRICAN: ✅ FIXED - Direct Unicode Substring
784
786
  // Amharic: Match roots anywhere
785
- { pattern: /ላክ/i, capability: 'transfer', lang: 'am' }, // Root for 'Send'
786
- { pattern: /ገባ/i, capability: 'deposit', lang: 'am' }, // Root for 'Deposit'
787
- { pattern: /ክፈል/i, capability: 'payment', lang: 'am' }, // Root for 'Pay'
788
- { pattern: /[\u1200-\u137F]{0,4}(?:ተላላፈ|ላክ|ክፈል|ጨምር|ወጣ|ገባ)[\u1200-\u137F]{0,2}/u, capability: 'financial_action', lang: 'am' },
787
+ { pattern: /\u120b\u12ad/u, capability: 'transfer', lang: 'am' },
788
+ { pattern: /\u1308\u1263/u, capability: 'deposit', lang: 'am' },
789
+ { pattern: /\u12ad\u134c\u120d/u, capability: 'payment', lang: 'am' },
790
+ { pattern: /[\u1200-\u137F]{0,4}(?:\u1270\u120b\u120b\u1348|\u120b\u12ad|\u12ad\u134c\u120d|\u1338\u121d\u122d|\u12c8\u1323|\u1308\u1263)[\u1200-\u137F]{0,2}/u, capability: 'financial_action', lang: 'am' },
789
791
 
790
792
  // Somali
791
793
  { pattern: /dir\s+(?:lacag|maal|qarsoon)/i, capability: 'transfer', lang: 'so' },
@@ -809,10 +811,10 @@ class RuntimeAPI {
809
811
  // ────────────────────────────────────────────────
810
812
  // 🛡️ PII & EVASION
811
813
  // ────────────────────────────────────────────────
812
- { pattern: /\b(?:\+?234\s*|0)(?:70|80|81|90|91)\d{8}\b/, capability: 'pii_exposure', lang: 'multi' },
813
- { pattern: /bvn\s*[:\-]?\s*(\d{11})/i, capability: 'pii_exposure', lang: 'multi' }, // Relaxed boundary
814
- { pattern: /(?:account|acct|a\/c|akaunti|asusu|hesabu|namba|#)\s*[:\-—–]?\s*(\d{6,})/i, capability: 'pii_exposure', lang: 'multi' }, // Relaxed boundary
815
- { pattern: /\b(successful(?:ly)?|confirmed|approved|completed|processed|verified|imethibitishwa|imefanikiwa)\b/i, capability: 'deceptive_claim', lang: 'multi' },
814
+ { pattern: /\b(?:\+?234\s*|0)(?:70|80|81|90|91)\d{8}\b/, capability: 'pii_exposure', lang: 'multi' },
815
+ { pattern: /\b(?:bvn|bank\s+verification\s+number)\b.{0,20}\d{11}/i, capability: 'pii_exposure', lang: 'multi' },
816
+ { pattern: /(?:account|acct|a\/c|akaunti|asusu|hesabu|namba|#)\s*[:\-—–]?\s*(\d{6,})/i, capability: 'pii_exposure', lang: 'multi' },
817
+ { pattern: /\b(successful(?:ly)?|confirmed|approved|completed|processed|verified|imethibitishwa|imefanikiwa)\b/i, capability: 'deceptive_claim', lang: 'multi' },
816
818
  ];
817
819
 
818
820
  for (const { pattern, capability, lang } of forbiddenPatterns) {
@@ -898,78 +900,94 @@ class RuntimeAPI {
898
900
  .map(name => name.replace('@o-lang/', '').replace(/-resolver$/, ''));
899
901
 
900
902
  // 🔒 CONJUGATION-AWARE + EVASION-RESISTANT PAN-AFRICAN INTENT DETECTION
901
- const forbiddenPatterns = [
902
- // ────────────────────────────────────────────────
903
- // 🇳🇬 NIGERIAN LANGUAGES (FIXED: Removed trailing \b on Unicode chars)
904
- // ────────────────────────────────────────────────
905
- { pattern: /\bti\s+(?:fi|san|gba|da|lo)/i, capability: 'unauthorized_action', lang: 'yo' }, // Removed trailing \b
906
- { pattern: /\b(?:ń|ǹ|n)\s+(?:fi|san|gba)/i, capability: 'unauthorized_action', lang: 'yo' },
907
-
908
- // FIXED YORUBA TRANSFER PATTERNS
909
- { pattern: /fi\s+(?:owo|ẹ̀wọ̀|ewo|ku|fun|s'ọkọọ)/i, capability: 'transfer', lang: 'yo' }, // Removed surrounding \b
910
- { pattern: /san\s+(?:owo|ẹ̀wọ̀|ewo|fun|wo)/i, capability: 'payment', lang: 'yo' },
911
- { pattern: /gba\s+owo/i, capability: 'withdrawal', lang: 'yo' },
912
- { pattern: /\b(mo\s+ti\s+(?:fi|san|gba))/i, capability: 'unauthorized_action', lang: 'yo' },
913
-
914
- // CRITICAL FIX: Specific pattern for "Fi 5000 naira ranṣẹ" without strict boundary
915
- { pattern: /fi\s+\w+\s+\w+\s+ranṣẹ/i, capability: 'transfer', lang: 'yo' },
916
- { pattern: /ranṣẹ\s+(?:owo|pesa|kuɗi|ego)/i, capability: 'transfer', lang: 'yo' }, // Removed trailing \b
917
-
918
- // HAUSA (Fixed trailing boundaries)
919
- { pattern: /\b(?:ya|ta|su)\s+(?:ciyar|biya|sahawa|sake)/i, capability: 'unauthorized_action', lang: 'ha' },
920
- { pattern: /\b(?:za\sa|za\s+ta)\s+(?:ciyar|biya)/i, capability: 'unauthorized_action', lang: 'ha' },
921
- { pattern: /ciyar\s*(?:da)?/i, capability: 'transfer', lang: 'ha' }, // Removed \b
922
- { pattern: /shiga\s+kuɗi/i, capability: 'transfer', lang: 'ha' }, // Removed \b
923
- { pattern: /biya\s*(?:da)?/i, capability: 'payment', lang: 'ha' },
924
- { pattern: /sahaw[ae]\s+kuɗi/i, capability: 'withdrawal', lang: 'ha' },
925
- { pattern: /\b(ina\s+(?:ciyar|biya|sahawa))/i, capability: 'unauthorized_action', lang: 'ha' },
926
- { pattern: /\b(aika\s+(?:kuɗi)|turo\s+.*\s+aika)/i, capability: 'transfer', lang: 'ha' }, // Moved here, removed \b
927
-
928
- // IGBO (Fixed trailing boundaries)
929
- { pattern: /\b(?:ziri|bururu|tinyere|gbara)/i, capability: 'unauthorized_action', lang: 'ig' },
930
- { pattern: /zipu\s+(?:ego|moni|isi|na)/i, capability: 'transfer', lang: 'ig' }, // Removed \b
931
- { pattern: /buru\s+(?:ego|moni|isi)/i, capability: 'transfer', lang: 'ig' }, // Removed \b
932
- { pattern: /tinye\s+(?:ego|moni|isi)/i, capability: 'deposit', lang: 'ig' }, // Removed \b
933
- { pattern: /\b(m\s+(?:ziri|buru|zipuru|tinyere))/i, capability: 'unauthorized_action', lang: 'ig' },
934
- { pattern: /zi\s+.*\s+zipu/i, capability: 'transfer', lang: 'ig' }, // Added generic send
935
-
936
- // SWAHILI (Kept mostly same as no diacritics in keywords)
937
- { pattern: /\b(?:ni|u|a|tu|m|wa|ki|vi|zi|i)\s*me\s*(?:ongeza|weka|tuma|peleka|lipa|wasilisha)\b/i, capability: 'unauthorized_action', lang: 'sw' },
938
- { pattern: /\b(tuma\s+(?:pesa|fedha)|pelek[ae]?\s+(?:pesa|fedha)|wasilisha)\b/i, capability: 'transfer', lang: 'sw' },
939
- { pattern: /\b(lipa|maliza\s+malipo)\b/i, capability: 'payment', lang: 'sw' },
940
- { pattern: /\b(ongez[ae]?\s*(?:kiasi|pesa|fedha)|wek[ae]?\s+(?:katika|ndani)\s+(?:akaunti|hisa))\b/i, capability: 'deposit', lang: 'sw' },
941
-
942
- // OTHER AFRICAN (Amharic, Somali, Zulu - Kept as is)
943
- { pattern: /[\u1200-\u137F]{0,4}(?:ተላላፈ|ላክ|ክፈል|ጨምር|ወጣ|ገባ)[\u1200-\u137F]{0,2}(?:\u1205|\u122d|\u1265)[\u1200-\u137F]{0,2}/u, capability: 'financial_action', lang: 'am' },
944
- { pattern: /\b(dir\s+(?:lacag|maal|qarsoon))\b/i, capability: 'transfer', lang: 'so' },
945
- { pattern: /\b(bixi|bixis\s*o)\b/i, capability: 'payment', lang: 'so' },
946
- { pattern: /\b(thumel\s*a\s+(?:imali))\b/i, capability: 'transfer', lang: 'zu' },
947
- { pattern: /\b(hlawul\s*a|hlawulel\s*a)\b/i, capability: 'payment', lang: 'zu' },
948
-
949
- // ────────────────────────────────────────────────
950
- // 🌐 GLOBAL LANGUAGES (Unchanged)
951
- // ────────────────────────────────────────────────
952
- { pattern: /\b(?:have|has|had)\s+(?:transferred|sent|paid|withdrawn|deposited|wire[d])\b/i, capability: 'unauthorized_action', lang: 'en' },
953
- { pattern: /\b(?:was|were|been)\s+(?:added|credited|transferred|sent|paid)\b/i, capability: 'unauthorized_action', lang: 'en' },
954
- { pattern: /\b(transfer(?:red|ring)?|send(?:t|ing)?|wire(?:d)?|pay(?:ed|ing)?|withdraw(?:n)?|deposit(?:ed|ing)?|disburse(?:d)?)\b/i, capability: 'financial_action', lang: 'en' },
955
- { pattern: /\bI\s+(?:can|will|am able to|have|'ve|did|already)\s+(?:transfer|send|pay|withdraw|deposit|wire)\b/i, capability: 'unauthorized_action', lang: 'en' },
956
- { pattern: /\b(?:j'?ai|tu as|il a|elle a|nous avons|vous avez|ils ont|elles ont)\s+(?:viré|transféré|envoyé|payé|retiré|déposé)\b/i, capability: 'unauthorized_action', lang: 'fr' },
957
- { pattern: /\b(virer|transférer|envoyer|payer|retirer|déposer|débiter|créditer)\b/i, capability: 'financial_action', lang: 'fr' },
958
- { pattern: /[\u0600-\u06FF]{0,3}(?:حوّل|أرسل|ادفع|اودع|سحب)[\u0600-\u06FF]{0,3}(?:ت|نا|تم|تا|تِ|تُ|تَ)[\u0600-\u06FF]{0,3}/u, capability: 'financial_action', lang: 'ar' },
959
- { pattern: /[\u0600-\u06FF]{0,3}(?:أنا|تم|لقد)\s*(?:حوّلت|أرسلت|دفعت|اودعت)[\u0600-\u06FF]{0,3}/u, capability: 'unauthorized_action', lang: 'ar' },
960
- { pattern: /[\u4e00-\u9fff]{0,2}(?:转账 | 支付 | 存款 | 取款)[\u4e00-\u9fff]{0,2}(?:了)[\u4e00-\u9fff]{0,2}/u, capability: 'financial_action', lang: 'zh' },
961
- { pattern: /[\u4e00-\u9fff]{0,2}(?:转账 | 转帐 | 支付 | 付款 | 提款 | 取款 | 存款 | 存入 | 汇款 | 存)[\u4e00-\u9fff]{0,2}/u, capability: 'financial_action', lang: 'zh' },
962
- { pattern: /[\u4e00-\u9fff]{0,2}(?:我 | 已 | 已经)\s*(?:转账 | 支付 | 提款 | 存款)[\u4e00-\u9fff]{0,2}/u, capability: 'unauthorized_action', lang: 'zh' },
963
-
964
- // ────────────────────────────────────────────────
965
- // 🛡️ EVASION-RESISTANT + PII + FAKE CONFIRMATION (Unchanged)
966
- // ────────────────────────────────────────────────
967
- { pattern: /(?:^|\s|[:\(\[])(?:\d{1,3}(?:[,\s.]\d{3})*(?:[.,]\d{1,2})?|\d+(?:[.,]\d{1,2})?)(?:\s*(?:naira|ngn|₦|\$|usd|kes|tzs|ugx|rwf|cdf|xof|xaf|ghs|zar))?.{0,40}(?:account|acct|a\/c|akaunti|asusu|akwụkwọ\s+ọkụ|hesabu|namba|#)\b/i, capability: 'unauthorized_action', lang: 'multi' },
968
- { pattern: /\b(?:account|acct|a\/c|akaunti|asusu|akwụkwọ\s+ọkụ|hesabu|namba|#)\s*[:\-—–]?\s*(\d{6,})\b/i, capability: 'pii_exposure', lang: 'multi' },
969
- { pattern: /\b(?:bvn|bank verification number)\s*[:\-]?\s*(\d{11})\b/i, capability: 'pii_exposure', lang: 'multi' },
970
- { pattern: /\b(?:\+?234\s*|0)(?:70|80|81|90|91)\d{8}\b/, capability: 'pii_exposure', lang: 'multi' },
971
- { pattern: /\b(successful(?:ly)?|confirmed|approved|completed|processed|accepted|verified|imethibitishwa|imefanikiwa|amthibitishwa|ti\s+da|ti\s+ṣe|gụnyere|kimefanyika|yamekamilika)\b/i, capability: 'deceptive_claim', lang: 'multi' },
972
- ];
903
+ const forbiddenPatterns = [
904
+ // ────────────────────────────────────────────────
905
+ // 🇳🇬 NIGERIAN LANGUAGES
906
+ // ────────────────────────────────────────────────
907
+
908
+ // YORUBA
909
+ { pattern: /fi\s+(?:owo|ẹ̀wọ̀|ewo|ku|fun|s'ọkọọ)/i, capability: 'transfer', lang: 'yo' },
910
+ { pattern: /san\s+(?:owo|ẹ̀wọ̀|ewo|fun|wo)/i, capability: 'payment', lang: 'yo' },
911
+ { pattern: /gba\s+owo/i, capability: 'withdrawal', lang: 'yo' },
912
+ { pattern: /fi\s+\w+\s+\w+\s+ranṣẹ/i, capability: 'transfer', lang: 'yo' },
913
+ { pattern: /ranṣẹ\s+(?:owo|pesa|kuɗi|ego)/i, capability: 'transfer', lang: 'yo' },
914
+ { pattern: /\bti\s+(?:fi|san|gba|da|lo)/i, capability: 'unauthorized_action', lang: 'yo' },
915
+ { pattern: /\b(?:ń|ǹ|n)\s+(?:fi|san|gba)/i, capability: 'unauthorized_action', lang: 'yo' },
916
+ { pattern: /\b(mo\s+ti\s+(?:fi|san|gba))/i, capability: 'unauthorized_action', lang: 'yo' },
917
+
918
+ // HAUSA
919
+ { pattern: /aika.{0,30}ku(?:ɗ|d)i/iu, capability: 'transfer', lang: 'ha' },
920
+ { pattern: /ciyar\s*(?:da)?/i, capability: 'transfer', lang: 'ha' },
921
+ { pattern: /shiga\s+ku(?:ɗ|d)i/iu, capability: 'transfer', lang: 'ha' },
922
+ { pattern: /turo\s+.*\s+aika/i, capability: 'transfer', lang: 'ha' },
923
+ { pattern: /biya\s*(?:da)?/i, capability: 'payment', lang: 'ha' },
924
+ { pattern: /sahaw[ae]\s+ku(?:ɗ|d)i/iu, capability: 'withdrawal', lang: 'ha' },
925
+ { pattern: /(?:ya|ta|su)\s+(?:ciyar|biya|sahawa|sake)/i, capability: 'unauthorized_action', lang: 'ha' },
926
+ { pattern: /(?:za\s+a|za\s+ta)\s+(?:ciyar|biya)/i, capability: 'unauthorized_action', lang: 'ha' },
927
+ { pattern: /ina\s+(?:ciyar|biya|sahawa)/i, capability: 'unauthorized_action', lang: 'ha' },
928
+
929
+ // IGBO
930
+ { pattern: /zipu\s+(?:ego|moni|isi|na)/i, capability: 'transfer', lang: 'ig' },
931
+ { pattern: /buru\s+(?:ego|moni|isi)/i, capability: 'transfer', lang: 'ig' },
932
+ { pattern: /zi\s+.*\s+zipu/i, capability: 'transfer', lang: 'ig' },
933
+ { pattern: /tinye\s+(?:ego|moni|isi)/i, capability: 'deposit', lang: 'ig' },
934
+ { pattern: /(?:ziri|bururu|tinyere|gbara)/i, capability: 'unauthorized_action', lang: 'ig' },
935
+ { pattern: /m\s+(?:ziri|buru|zipuru|tinyere)/i, capability: 'unauthorized_action', lang: 'ig' },
936
+
937
+ // SWAHILI
938
+ { pattern: /tuma\s+(?:pesa|fedha)/i, capability: 'transfer', lang: 'sw' },
939
+ { pattern: /pelek[ae]?\s+(?:pesa|fedha)/i, capability: 'transfer', lang: 'sw' },
940
+ { pattern: /wasilisha/i, capability: 'transfer', lang: 'sw' },
941
+ { pattern: /\b\w*lip[ae]\w*/i, capability: 'payment', lang: 'sw' },
942
+ { pattern: /maliza\s+malipo/i, capability: 'payment', lang: 'sw' },
943
+ { pattern: /ongez[ae]?\s*(?:kiasi|pesa|fedha)/i, capability: 'deposit', lang: 'sw' },
944
+ { pattern: /wek[ae]?\s+(?:katika|ndani)\s+(?:akaunti|hisa)/i, capability: 'deposit', lang: 'sw' },
945
+ { pattern: /nime(?:tuma|lipa|ongeza|weka|peleka)/i, capability: 'unauthorized_action', lang: 'sw' },
946
+ { pattern: /(?:ni|u|a|tu|m|wa|ki|vi|zi|i)\s*me\s*(?:ongeza|weka|tuma|peleka|lipa|wasilisha)/i, capability: 'unauthorized_action', lang: 'sw' },
947
+
948
+ // ────────────────────────────────────────────────
949
+ // 🌍 OTHER AFRICAN LANGUAGES
950
+ // ────────────────────────────────────────────────
951
+
952
+ // AMHARIC - Unicode escapes to avoid encoding issues
953
+ { pattern: /\u120b\u12ad/u, capability: 'transfer', lang: 'am' },
954
+ { pattern: /\u1308\u1263/u, capability: 'deposit', lang: 'am' },
955
+ { pattern: /\u12ad\u134c\u120d/u, capability: 'payment', lang: 'am' },
956
+ { pattern: /[\u1200-\u137F]{0,4}(?:\u1270\u120b\u120b\u1348|\u120b\u12ad|\u12ad\u134c\u120d|\u1338\u121d\u122d|\u12c8\u1323|\u1308\u1263)[\u1200-\u137F]{0,2}/u, capability: 'financial_action', lang: 'am' },
957
+
958
+ // SOMALI
959
+ { pattern: /dir\s+(?:lacag|maal|qarsoon)/i, capability: 'transfer', lang: 'so' },
960
+ { pattern: /bixi|bixis\s*o/i, capability: 'payment', lang: 'so' },
961
+
962
+ // ZULU
963
+ { pattern: /thumel/i, capability: 'transfer', lang: 'zu' },
964
+ { pattern: /thumel.*imali/i, capability: 'transfer', lang: 'zu' },
965
+ { pattern: /hlawul/i, capability: 'payment', lang: 'zu' },
966
+ { pattern: /hlawul.*imali/i, capability: 'payment', lang: 'zu' },
967
+
968
+ // ────────────────────────────────────────────────
969
+ // 🌐 GLOBAL LANGUAGES
970
+ // ────────────────────────────────────────────────
971
+ { pattern: /\b(?:have|has|had)\s+(?:transferred|sent|paid|withdrawn|deposited|wire[d])\b/i, capability: 'unauthorized_action', lang: 'en' },
972
+ { pattern: /\b(?:was|were|been)\s+(?:added|credited|transferred|sent|paid)\b/i, capability: 'unauthorized_action', lang: 'en' },
973
+ { pattern: /\b(transfer(?:red|ring)?|send(?:ing)?|wire(?:d)?|pay(?:ed|ing)?|withdraw(?:n)?|deposit(?:ed|ing)?|disburse(?:d)?)\b/i, capability: 'financial_action', lang: 'en' },
974
+ { pattern: /\bI\s+(?:can|will|am able to|have|'ve|did|already)\s+(?:transfer|send|pay|withdraw|deposit|wire)\b/i, capability: 'unauthorized_action', lang: 'en' },
975
+ { pattern: /\b(?:j'?ai|tu as|il a|elle a|nous avons|vous avez|ils ont|elles ont)\s+(?:viré|transféré|envoyé|payé|retiré|déposé)\b/i, capability: 'unauthorized_action', lang: 'fr' },
976
+ { pattern: /\b(virer|transférer|envoyer|payer|retirer|déposer|débiter|créditer)\b/i, capability: 'financial_action', lang: 'fr' },
977
+ { pattern: /[\u0600-\u06FF]{0,3}(?:حوّل|أرسل|ادفع|اودع|سحب)[\u0600-\u06FF]{0,3}(?:ت|نا|تم|تا|تِ|تُ|تَ)[\u0600-\u06FF]{0,3}/u, capability: 'financial_action', lang: 'ar' },
978
+ { pattern: /[\u0600-\u06FF]{0,3}(?:أنا|تم|لقد)\s*(?:حوّلت|أرسلت|دفعت|اودعت)[\u0600-\u06FF]{0,3}/u, capability: 'unauthorized_action', lang: 'ar' },
979
+ { pattern: /[\u4e00-\u9fff]{0,2}(?:转账|支付|存款|取款)[\u4e00-\u9fff]{0,2}(?:了)[\u4e00-\u9fff]{0,2}/u, capability: 'financial_action', lang: 'zh' },
980
+ { pattern: /[\u4e00-\u9fff]{0,2}(?:转账|转帐|支付|付款|提款|取款|存款|存入|汇款|存)[\u4e00-\u9fff]{0,2}/u, capability: 'financial_action', lang: 'zh' },
981
+ { pattern: /[\u4e00-\u9fff]{0,2}(?:我|已|已经)\s*(?:转账|支付|提款|存款)[\u4e00-\u9fff]{0,2}/u, capability: 'unauthorized_action', lang: 'zh' },
982
+
983
+ // ────────────────────────────────────────────────
984
+ // 🛡️ PII & EVASION
985
+ // ────────────────────────────────────────────────
986
+ { pattern: /\b(?:\+?234\s*|0)(?:70|80|81|90|91)\d{8}\b/, capability: 'pii_exposure', lang: 'multi' },
987
+ { pattern: /\b(?:bvn|bank\s+verification\s+number)\b.{0,20}\d{11}/i, capability: 'pii_exposure', lang: 'multi' },
988
+ { pattern: /(?:account|acct|a\/c|akaunti|asusu|hesabu|namba|#)\s*[:\-—–]?\s*(\d{6,})/i, capability: 'pii_exposure', lang: 'multi' },
989
+ { pattern: /\b(successful(?:ly)?|confirmed|approved|completed|processed|accepted|verified|imethibitishwa|imefanikiwa|amthibitishwa|ti\s+da|ti\s+ṣe|gụnyere|kimefanyika|yamekamilika)\b/i, capability: 'deceptive_claim', lang: 'multi' },
990
+ ];
973
991
 
974
992
  // 🔍 SCAN OUTPUT FOR FORBIDDEN INTENTS
975
993
  for (const { pattern, capability, lang } of forbiddenPatterns) {