From 04a0900a2c36f0fbacfd871b4fffbbd50be9b3c8 Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Wed, 16 Sep 2026 19:50:15 +0200 Subject: [PATCH] =?UTF-8?q?fix(prompt):=20drop=20HOUSE=5FSTYLE=20=E2=80=94?= =?UTF-8?q?=20the=20shipped=20prompt=20now=20says=20it=20itself?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HOUSE_STYLE was appended after tutor-system.md because the old prompt never stated which language to teach in, and gpt-oss-20b delivered a unit-1.1 lesson in Korean. The 16 Sep prompt states the rule outright, twice — "everything you SAY is in English" — and the client now has proseIsKorean() to send a Korean explanation back. The appendix said itself that if the shipped prompt ever covered this, it should go. {{VARIETY}} also learns the fifth exercise type, recall. Co-Authored-By: Claude Opus 5 (1M context) --- app/src/domain/gate.ts | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/app/src/domain/gate.ts b/app/src/domain/gate.ts index 7df64ab..4ce3f7a 100644 --- a/app/src/domain/gate.ts +++ b/app/src/domain/gate.ts @@ -112,8 +112,8 @@ export function gateFor({ progress, bandQuery }: GateInputs): Gate { /* ── the prompt ──────────────────────────────────────────────────── */ -/** The four exercise types, so {{VARIETY}} can ask for a different one. */ -const TASK_TYPES = ["translate", "match", "build", "choice"] as const; +/** The five exercise types, so {{VARIETY}} can ask for a different one. */ +const TASK_TYPES = ["translate", "recall", "match", "build", "choice"] as const; export type TaskKind = (typeof TASK_TYPES)[number]; export const FOCUS_MODES = { @@ -150,34 +150,6 @@ export interface PromptInputs { focus: FocusMode; } -/** - * Assemble the system prompt. The template is prompt/tutor-system.md, - * shipped unchanged — this fills its three placeholders and nothing else. - */ -/* Appended by the app, after the shipped prompt — not an edit to it. - - tutor-system.md ships unchanged. Two things it leaves to inference, which - a strong model supplies on its own and a small local one does not: - - THE LANGUAGE OF EXPLANATION is never actually stated. The prompt says - "한글 and English only", but that rule is about retiring romanization, not - about which language to teach in. Everything else only implies it — - English translations, English glosses. gpt-oss-20b read the room - differently and delivered a whole grammar lesson in Korean, to a student - on unit 1.1 who cannot yet read it. - - NO MARKDOWN is stated outright at line 96, and was ignored anyway. It is - restated here because the consequence is invisible to the model: the app - renders **bold** and nothing else, so a table arrives as rows of literal - pipes and a heading as literal hashes. - - Both are reinforcement, never contradiction. If the shipped prompt and - this ever disagree, the shipped prompt is right and this should go. */ -const HOUSE_STYLE = ` -════ HOUSE STYLE ════ -Explain in English. Korean is the material — words, examples, exercise lines, anything you are asking him to read. It is not the language you teach in. He is a beginner working through the writing system; an explanation he cannot read teaches him nothing. -Plain text only. No tables, headings, bullet characters or code fences — the app renders **bold** and nothing else, so anything else reaches him as literal pipes and hashes.`; - /** * Substitute one placeholder — the one standing alone on its own line. * @@ -207,11 +179,15 @@ function fill(template: string, name: string, value: string): string { return template.replace(token, () => value); } +/** + * Assemble the system prompt. The template is prompt/tutor-system.md, + * shipped unchanged — this fills its three placeholders and nothing else. + */ export function assemblePrompt({ template, gate, recent, focus }: PromptInputs): string { let out = fill(template, "GATE", renderGate(gate)); out = fill(out, "VARIETY", varietyLine(recent)); out = fill(out, "FOCUS", focusLine(focus)); - return out + HOUSE_STYLE; + return out; } export { renderGate, REFERENCE_BAND };