Summary
buildContextPrompt() in LifeOS/install/hooks/PromptProcessing.hook.ts (~L723) — the Haiku prompt that produces the tab title and the permanent session name — is written entirely in English: English examples ("Fixing auth bug.", "Fix Session Naming Hook Logic"), English verb-form rules ("Start with gerund (-ing verb)", "Start with a base-form action verb (Fix, Build, Debug…)").
The model reads those examples as an output-language contract. A conversation held in any other language gets its session translated into an English title: an Italian prompt about a delivery bug in child chats came back as Fix Child Chat Delivery Bug. The user later scans their session list and doesn't recognize their own conversations — the name is a summary of the work, in a language the conversation never used.
This is the missing half of the non-English work already landed: #1774 fixed accent-stripping in the deterministic path (\p{L}), #1718/#1845 made the inference validator shape-only so non-English names can pass. The pipeline now accepts non-English names — but the prompt never produces them.
Root cause
LLM prompts teach by example more than by rule. Twenty English examples with zero language instruction = "output English". Nothing downstream translates back; the name is stored verbatim in session-names.json.
Suggested fix
Add a language contract at the top of buildContextPrompt(), before TASK 1 — language-generic, not per-locale:
## LANGUAGE — read this before both tasks
Both outputs are written in the LANGUAGE OF THE USER'S MESSAGE. A message in Italian
(or Spanish, French, German, …) gets its tab title and session name in that language —
NEVER translate into English. English message → English outputs. Mixed or ambiguous →
the language the user wrote in.
Verb forms adapt per language: use that language's progressive/gerund form for the tab
title and its imperative/base form for the session name (English: "Fixing…" / "Fix …";
Italian: "Riparando…" / "Ripara …"). All other rules (word counts, Title Case, no
articles) apply unchanged in every language.
Plus at least one non-English example in the TASK 2 list, marked as a counter-example to translation, e.g.:
- "guarda che la chat figlia non ha consegnato il referto, va aggiustato" (Italian)
→ "Ripara Consegna Referto Chat Figlie" (NOT "Fix Child Chat Delivery Bug" — never translate)
One example in one language is enough to break the all-English pattern; the rule carries the generalization.
Verified
Applied locally and probed live through the real inference path (fresh session ids, actual Haiku calls):
No downstream change needed: the validator, storage, and dedup already handle non-ASCII names.
Summary
buildContextPrompt()inLifeOS/install/hooks/PromptProcessing.hook.ts(~L723) — the Haiku prompt that produces the tab title and the permanent session name — is written entirely in English: English examples ("Fixing auth bug.", "Fix Session Naming Hook Logic"), English verb-form rules ("Start with gerund (-ing verb)", "Start with a base-form action verb (Fix, Build, Debug…)").The model reads those examples as an output-language contract. A conversation held in any other language gets its session translated into an English title: an Italian prompt about a delivery bug in child chats came back as
Fix Child Chat Delivery Bug. The user later scans their session list and doesn't recognize their own conversations — the name is a summary of the work, in a language the conversation never used.This is the missing half of the non-English work already landed: #1774 fixed accent-stripping in the deterministic path (
\p{L}), #1718/#1845 made the inference validator shape-only so non-English names can pass. The pipeline now accepts non-English names — but the prompt never produces them.Root cause
LLM prompts teach by example more than by rule. Twenty English examples with zero language instruction = "output English". Nothing downstream translates back; the name is stored verbatim in
session-names.json.Suggested fix
Add a language contract at the top of
buildContextPrompt(), before TASK 1 — language-generic, not per-locale:Plus at least one non-English example in the TASK 2 list, marked as a counter-example to translation, e.g.:
One example in one language is enough to break the all-English pattern; the rule carries the generalization.
Verified
Applied locally and probed live through the real inference path (fresh session ids, actual Haiku calls):
Sistema Tracce Doppie Compendio Biologo(Italian, correct subject)Fix Nosleep Watchdog Timer Logic(unchanged behavior)Correggi Accenti Città Tracce Compendio— accents survive storage byte-exact, passisValidInferredSessionName(shape-only since PromptProcessing: session-name validator rejects inference names outside a hardcoded verb whitelist, while the deterministic fallback passes by construction #1718), and the follow-up tab-title derivation falls back cleanly to the first 4 words when the lead verb isn't in the EnglishACTION_VERBSset (no mangling).No downstream change needed: the validator, storage, and dedup already handle non-ASCII names.