# Indonesian (Bahasa, incl. colloquial Jakarta register) phantom-detection
# configuration. Added after a live hallucination narrated in Indonesian
# escaped every detector (#463): character-set language detection cannot
# distinguish Indonesian (pure ASCII Latin) from English, but the intent
# scan checks every loaded language's phrases at once, so these fire
# regardless of detection. Phrases are multi-word to keep cross-language
# collision risk low. All lower-case; matched against lowercased text.
#
# Expanded 2026-07-21 (#667): added full regex coverage, completion claims,
# and reasoning-leak phrases to match en.toml's structure.
intent_phrases = [
# Colloquial Jakarta register (gue/aku)
"sekarang gue ",
"sekarang aku ",
"sekarang saya ",
"biar gue ",
"biar aku ",
"biar saya ",
"gue akan ",
"aku akan ",
"saya akan ",
"akan gue ",
"akan aku ",
"akan saya ",
"gue load ",
"gue jalankan ",
"gue jalanin ",
"gue push ",
"gue commit ",
"gue cek ",
"gue baca ",
"gue lihat ",
"gue periksa ",
"gue update ",
"gue fix ",
"gue bikin ",
"gue buat ",
"gue hapus ",
"gue ganti ",
"gue tambah ",
"gue kurang ",
"gue ubah ",
"mari kita jalankan",
"mari kita cek",
"mari kita lihat",
"mari kita periksa",
"mari kita update",
"mari kita fix",
"mari kita buat",
"mari kita baca",
"coba gue ",
"coba aku ",
"coba saya ",
# Formal register (saya/kita)
"saya akan cek",
"saya akan periksa",
"saya akan lihat",
"saya akan baca",
"saya akan update",
"saya akan fix",
"saya akan buat",
"saya akan bikin",
"saya akan hapus",
"saya akan ganti",
"saya akan tambah",
"saya akan ubah",
"saya akan jalankan",
"saya akan push",
"saya akan commit",
"saya perlu cek",
"saya perlu periksa",
"saya perlu lihat",
"saya perlu baca",
"saya perlu update",
"saya perlu fix",
"saya perlu buat",
"saya perlu jalankan",
"saya harus cek",
"saya harus periksa",
"saya harus update",
"saya harus fix",
"saya harus buat",
"saya harus jalankan",
# "let me" equivalents
"biar saya cek",
"biar saya periksa",
"biar saya lihat",
"biar saya baca",
"biar saya update",
"biar saya fix",
"biar saya buat",
"biar saya jalankan",
"biar saya push",
"biar saya commit",
# "now" equivalents
"sekarang cek ",
"sekarang periksa ",
"sekarang lihat ",
"sekarang baca ",
"sekarang update ",
"sekarang fix ",
"sekarang buat ",
"sekarang jalankan ",
"sekarang push ",
"sekarang commit ",
"sekarang menambah",
"sekarang mengubah",
"sekarang menghapus",
"sekarang membuat",
"sekarang memperbaiki",
"sekarang memperbarui",
]
action_verbs = [
# Local playback / launching an artifact (see en.toml).
"memutar",
"diputar",
"membuka file",
"menjalankan file",
"dimuat",
"dijalankan",
"diperbarui",
"diperbaiki",
"dibuat",
"dihapus",
"diganti",
"ditambah",
"diubah",
"dikirim",
"di-commit",
"di-push",
"di-deploy",
"di-merge",
"di-install",
"diunduh",
"diunggah",
"disimpan",
"diselesaikan",
# Issue-tracker and review actions (see en.toml for the case that
# exposed the gap).
"ditutup",
"dibuka",
"dikomentari",
"ditugaskan",
"dilabeli",
# Self-update and lifecycle. A fabricated "Evolved from X to Y" with zero
# tool calls told the user their binary had replaced itself when it had
# not, leaving them to report bugs against a version they were not running.
"di-upgrade",
"di-restart",
"dibangun ulang",
"diinstal ulang",
# Claimed INVESTIGATION, not side effects. A zero-tool turn opening
# "Verified just now, real output:" produced a fabricated file dump with
# invented line numbers. Fabricated evidence is worse than a fabricated
# action: a fake push dies to one git log, a fake dump gets built on.
# Deliberately excludes read/checked/found/ran — all legitimate in
# ordinary conversation about context the model already has.
"diverifikasi",
"diaudit",
"diperiksa",
]
completion_claims = [
"sudah diperbarui",
"sudah diperbaiki",
"sudah dibuat",
"sudah dihapus",
"sudah diganti",
"sudah ditambah",
"sudah diubah",
"sudah dikirim",
"sudah di-commit",
"sudah di-push",
"sudah di-deploy",
"sudah selesai",
"sudah selesai semua",
"semua sudah diperbarui",
"semua sudah diperbaiki",
"file sudah diperbarui",
"kode sudah diperbaiki",
"perubahan sudah diterapkan",
"saya sudah memperbarui",
"saya sudah memperbaiki",
"saya sudah membuat",
"saya sudah menghapus",
"saya sudah commit",
"saya sudah push",
"pekerjaan sudah selesai dan tercatat",
"sudah dikirim dan tercatat",
]
# Regex patterns — Indonesian uses Latin script, so patterns mirror en.toml
# structure but with Indonesian intent phrases.
line_start_re = "(?im)^[\\s\\-*•>]*(?:(?:ok|oke|baik|siap|okeh)\\s*,?\\s+)?(?:sekarang\\s+)?(?:biar\\s+(?:gue|aku|saya)|gue|aku|saya\\s+akan|saya\\s+perlu|saya\\s+harus|mari\\s+kita|coba\\s+(?:gue|aku|saya))\\s+\\w"
work_announcement_re = "(?i)^[\\s\\-*•>]*(?:(?:(?:dan\\s+)?lalu|(?:dan\\s+)?kemudian|setelah\\s+itu|terus|dan)[,]?\\s+)?(?:(?:ok|oke|baik|siap|okeh)[,.!:]?\\s+)?(?:sekarang\\s+|biar\\s+(?:gue|aku|saya)\\s+)?(?:sedang\\s+)?(?:menjalankan|mengecek|memeriksa|membaca|membuat|memperbarui|memperbaiki|menghapus|mengganti|menambah|mengubah|mengirim|meng-commit|meng-push|meng-deploy|meng-install|mengunduh|mengunggah|menyimpan|menyelesaikan|menganalisis|menginvestigasi|mengumpulkan|mengambil|mengunduh)\\b[^.!?:\\n]{0,60}?(?:\\s+(?:sekarang|saat\\s+ini)(?:[.!…,:]+|\\s*(?:\\n|$))|\\.{3}|…|:\\s*(?:\\n|$))"
# Gerund-led plan announcement carrying NO imminence marker — "Setting up the
# plan, then mapping every call site before touching anything." Two reasons
# the patterns above cannot see it (#1261): the verb is a PREPARATION verb
# (mapping, planning, drafting, listing) that work_announcement_re never
# enumerated, and the clause is sequenced with then / before instead of ending
# in now / … / :, which that pattern requires and gerund_re expects at the
# front. Scanned by the zero-tool gate only: once a tool has run, the same
# shape can be a legitimate recap ("Updating the config fixed it, then the
# build passed").
plan_announcement_re = "(?im)^[\\s\\-*•>]*(?:(?:ok|oke|baik)[,.!:]?\\s+)?(?:saya\\s+|sedang\\s+|pertama\\s+|sekarang\\s+)?(?:menyiapkan|menyusun|memetakan|merencanakan|mempersiapkan|meninjau|mendaftar|mendokumentasikan|membuat|memperbarui|memeriksa|membaca|menjalankan|menganalisis|menyelidiki)\\b[^.!?\\n]{0,120}?\\b(?:lalu|kemudian|sebelum|setelah\\s+itu)\\b"
gerund_re = "(?im)(?:^|[.!?]\\s+)\\s*(?:sekarang\\s+)?(?:sedang\\s+)?(?:menjalankan|mengecek|memeriksa|membaca|membuat|memperbarui|memperbaiki|menghapus|mengganti|menambah|mengubah|mengirim|meng-commit|meng-push|meng-deploy|meng-install|mengunduh|mengunggah|menyimpan|menyelesaikan|menganalisis|menginvestigasi|mengumpulkan|mengambil)\\b"
trailing_colon_re = "(?im)(?:^|\\n)\\s*(?:biar\\s+(?:gue|aku|saya)|saya\\s+akan|sekarang\\s+(?:biar\\s+(?:gue|aku|saya)\\s+)?|mari\\s+kita)\\s+\\w[^:\\n]{0,80}:\\s*$"
now_imperative_re = "(?m)^[\\s\\-*]*(?:sekarang\\s+(?:biar\\s+(?:gue|aku|saya)\\s+)?|biar\\s+(?:gue|aku|saya)\\s+)\\w"
numbered_steps_re = "(?m)^\\s*\\d+\\.\\s+(?:perbarui|perbaiki|buat|hapus|ganti|tambah|ubah|cek|periksa|baca|jalankan|push|commit|deploy|install)"
past_tense_standalone_re = "(?m)^[\\s\\-*]*(?:sudah\\s+)?(?:diperbarui|diperbaiki|dibuat|dihapus|diganti|ditambah|diubah|dikirim|di-commit|di-push|di-deploy|di-merge|di-install|diunduh|diunggah|disimpan|diselesaikan)[.!]"
path_re = "(?:^|[\\s`(])(?:\\./)?[a-zA-Z_][\\w\\-]*/[\\w\\-/]*\\.\\w{1,6}(?:[\\s`),:;]|$)"
ext_re = "(?:^|[\\s`(])[\\w\\-]+\\.(?:rs|py|ts|tsx|js|jsx|go|sh|toml|yaml|yml|json|md)(?:[\\s`),:;]|$)"
backtick_code_re = "`[a-zA-Z_]\\w+`"
# Halusinasi pembuatan gambar (#747)
media_delivery_phrases = [
"ini dia",
"sudah jadi",
"sudah saya buat",
"saya generate",
"berhasil generate",
"sudah di-generate",
"sudah digenerate",
"hasilnya ini",
"sudah dibuat",
"sudah diedit",
"gambar sudah",
"sudah dikirim",
]
media_context_words = [
"gambar",
"foto",
"citra",
"render",
"latar",
"latar belakang",
"kecerahan",
"eksposur",
"kontras",
"logo",
]
# Framings that present a named command as ALREADY RUN. The command is
# language-neutral; the claim around it is not. See #789.
executed_framings = [
"menjalankan",
"sudah dijalankan",
"saya jalankan",
"diperiksa dengan",
"outputnya",
"hasilnya",
"dikonfirmasi dengan",
]
# Claims that a FILE or DOCUMENT was sent (#825). Paired with
# `file_context_words`: a claim of a delivered file in a turn that never
# invoked a document-sending tool is fabricating. Document sending is a
# newer capability than image generation, so the media checks (#747) did
# not cover it.
file_delivery_phrases = [
"file terkirim",
"sudah kirim file",
"saya kirim file",
"file dilampirkan",
"saya lampirkan",
"sudah dilampirkan",
"mengunggah file",
"dokumen terkirim",
"saya kirim dokumen",
"laporan terkirim",
"laporan sudah dikirim",
"filenya di atas",
"lihat lampiran",
"baru keluar dari oven",
"ini videonya",
"ini audionya",
"ada di atas",
"sudah di atas",
"putar saja",
"baru saja saya kirim",
"sudah saya kirim",
]
# Words marking the claimed deliverable as a file rather than a message.
file_context_words = [
"file",
"dokumen",
"laporan",
".md",
"lampiran",
"pdf",
"csv",
".mp4",
".mp3",
".wav",
".png",
".jpg",
"video",
"audio",
"gambar",
"mp4",
"mp3",
"wav",
"mov",
"png",
"jpg",
]
# Generic first-person intent: the verb is captured, not enumerated, so a
# verb missing from intent_phrases (e.g. "let me execute") is still caught.
generic_intent_re = "(?i)\\b(?:saya\\s+akan|aku\\s+akan|mari\\s+kita|biar\\s+saya)\\s+([a-z]{2,})"
# Verbs that follow that construction without promising any work.
intent_verb_exclusions = [
"tahu",
"jelaskan",
"menjelaskan",
"katakan",
"pikir",
"tunjukkan",
"bagikan",
"sebutkan",
]
# Context that turns a BARE tool name into a claim of tool usage (#1262).
# Multi-word names (`load_brain_file`) are unmistakable on their own, but
# `plan`, `bash`, `grep` and `ls` are ordinary words, so naming one proves
# nothing by itself. It proves something when the name is the OBJECT of an
# action the model attributes to itself: "Setting up the plan" in a turn that
# called no tool is a tool use that never happened. A marker must sit
# immediately before the name, optionally across one determiner, so an
# instruction addressed to the user ("run it in bash") stays untouched.
tool_use_markers = [
"menggunakan",
"gunakan",
"pakai",
"memakai",
"menjalankan",
"jalankan",
"memanggil",
"panggil",
"membuat",
"buat",
"menyiapkan",
"siapkan",
"menyusun",
"memperbarui",
"perbarui",
"membaca",
"baca",
"menulis",
"tulis",
"memeriksa",
"periksa",
"membuka",
"buka",
"memulai",
"mulai",
"lewat",
"via",
]
# Nouns that mark the preceding word as a tool by name ("the plan tool").
tool_nouns = [
"alat",
"tool",
"perkakas",
]
# Determiners allowed between a marker and the tool name, so "setting up THE
# plan" reads the same as "setting up plan". At most one, and only these:
# anything else between the two words means the name is not the marker's
# object. Empty for languages without articles.
tool_name_determiners = [
]