Lesson code-editor starter templates are never localized — the comments inside the editable code (e.g. C# lesson 301: // return one label when flag is true, the other when false) always render in English even when UI + lesson text are Spanish. Verified in code:
LessonStrategyBase.Localization.cs → FinalizeAttemptWithLocale overlays Instructions / Hints / TutorialPanels only, and passes the original English built.CodeTemplate straight through to FinalizeAttemptCore.
The translation data model (CurriculumTranslationStore.LessonTranslationEntry) has no codeTemplate field — so a translated template can't even be expressed today.
Confirmed against Lesson301_IfElse.cs (the exact comment in the report) and the es/csharp.json entry for 301 (has translated instructions/hints, no template).
This is one structural root cause behind the entire per-language cluster.
(Older translation waves #267–274 and #196–203 are about instructions/lesson text — a different symptom, largely addressed by the #279 content work — and are NOT folded in here until individually re-confirmed.)
Plan
Phase 1 — Engineering (this epic's first PR)
Add an optional codeTemplate field to LessonTranslationEntry / LessonTranslation and the store loader.
In FinalizeAttemptWithLocale, when a translated codeTemplate exists, overlay it (with ApplySeedTokens for randomized lessons) before FinalizeAttemptCore.
Pilot end-to-end on one C# lesson (301) + unit coverage.
Phase 2 — Content fan-out (per track)
Author Spanish codeTemplate entries (comments only; keep identifiers/keywords as code) for every Challenge lesson, per track: C#, Python, JavaScript, C, C++, x86, Regex, SQL.
Known follow-up (track separately)
Offline/WASM path: the browser grader serves English attempts (LessonStrategyBase.Localization.cs is server-only). Connected mode is fixed by Phase 1; offline localization of the template needs a separate SPA/WASM change.
Acceptance criteria
Translation model + overlay support a localized code template (Phase 1).
C# pilot lesson serves Spanish comments in ?contentLocale=es with passing tests.
Per-track content added (Phase 2) for all Challenge lessons.
Spanish UI shows translated starter-comment text in connected mode across all 8 playgrounds.
Severity
Medium (localization completeness; comprehension for Spanish-speaking learners).
## Summary (confirmed root cause)
Lesson **code-editor starter templates are never localized** — the comments inside the editable code (e.g. C# lesson 301: `// return one label when flag is true, the other when false`) always render in English even when UI + lesson text are Spanish. Verified in code:
- `LessonStrategyBase.Localization.cs` → `FinalizeAttemptWithLocale` overlays **Instructions / Hints / TutorialPanels** only, and passes the original English `built.CodeTemplate` straight through to `FinalizeAttemptCore`.
- The translation data model (`CurriculumTranslationStore.LessonTranslationEntry`) has **no `codeTemplate` field** — so a translated template can't even be expressed today.
- Confirmed against `Lesson301_IfElse.cs` (the exact comment in the report) and the `es/csharp.json` entry for 301 (has translated instructions/hints, no template).
This is **one structural root cause** behind the entire per-language cluster.
## Consolidates
- #288 C# · #289 Python · #290 JavaScript · #291 C · #292 C++ · #293 x86 · #294 Regex · #295 SQL
(Older translation waves #267–274 and #196–203 are about *instructions/lesson text* — a different symptom, largely addressed by the #279 content work — and are NOT folded in here until individually re-confirmed.)
## Plan
### Phase 1 — Engineering (this epic's first PR)
- Add an optional `codeTemplate` field to `LessonTranslationEntry` / `LessonTranslation` and the store loader.
- In `FinalizeAttemptWithLocale`, when a translated `codeTemplate` exists, overlay it (with `ApplySeedTokens` for randomized lessons) before `FinalizeAttemptCore`.
- Pilot end-to-end on one C# lesson (301) + unit coverage.
### Phase 2 — Content fan-out (per track)
- Author Spanish `codeTemplate` entries (comments only; keep identifiers/keywords as code) for every Challenge lesson, per track: C#, Python, JavaScript, C, C++, x86, Regex, SQL.
### Known follow-up (track separately)
- **Offline/WASM path**: the browser grader serves English attempts (`LessonStrategyBase.Localization.cs` is server-only). Connected mode is fixed by Phase 1; offline localization of the template needs a separate SPA/WASM change.
## Acceptance criteria
- [ ] Translation model + overlay support a localized code template (Phase 1).
- [ ] C# pilot lesson serves Spanish comments in `?contentLocale=es` with passing tests.
- [ ] Per-track content added (Phase 2) for all Challenge lessons.
- [ ] Spanish UI shows translated starter-comment text in connected mode across all 8 playgrounds.
## Severity
Medium (localization completeness; comprehension for Spanish-speaking learners).
spikerj
added the bug label 2026-06-30 15:52:21 +00:00
Triage note — extra untranslated surfaces folded in from #288–#295
Reading the full reports, a few of the closed duplicates point at surfaces beyond the starter-template comments. Capturing them here so they aren't lost (each needs its own data/overlay work under Phase 2):
Starter-template comments (the structural fix, Phase 1 / PR #36): #288 C#, #290 JS, #291 C, #292 C++, #293 x86 (; Flat Assembler file), #295 SQL (-- Welcome to the SQL playground.). Python (#289) # replace this with your code is the auto-generated pass-placeholder annotation — needs localizing in AnnotatePlaceholdersForLanguage, not JSON.
"Lección Concepts" side panel still English (e.g. "Return a value", "Standard output stream", "Newline escape sequence") — reported in #289 (Python), #291 (C), #292 (C++). Separate concept-card content, not part of the attempt overlay.
Regex hints ("Pistas") in English — #294. This is the regex hint pipeline, overlaps older #273 / #202; not a code template at all.
SQL instructions still English ("Concept focus…", "Write a query…") — #295, overlaps older #274 / #203.
x86 terminal/emulator strings ("Initializing blink emulator… blink ready!") — #293; emulator UI, separate from lesson content.
PR #36 covers (1) for C# as the pilot. Suggest tracking (2)–(5) as explicit Phase-2 sub-items so per-surface ownership is clear.
### Triage note — extra untranslated surfaces folded in from #288–#295
Reading the full reports, a few of the closed duplicates point at surfaces **beyond** the starter-template comments. Capturing them here so they aren't lost (each needs its own data/overlay work under Phase 2):
1. **Starter-template comments** (the structural fix, Phase 1 / PR #36): #288 C#, #290 JS, #291 C, #292 C++, #293 x86 (`; Flat Assembler file`), #295 SQL (`-- Welcome to the SQL playground.`). Python (#289) `# replace this with your code` is the auto-generated `pass`-placeholder annotation — needs localizing in `AnnotatePlaceholdersForLanguage`, not JSON.
2. **"Lección Concepts" side panel** still English (e.g. "Return a value", "Standard output stream", "Newline escape sequence") — reported in #289 (Python), #291 (C), #292 (C++). Separate concept-card content, not part of the attempt overlay.
3. **Regex hints ("Pistas")** in English — #294. This is the regex hint pipeline, overlaps older #273 / #202; not a code template at all.
4. **SQL instructions** still English ("Concept focus…", "Write a query…") — #295, overlaps older #274 / #203.
5. **x86 terminal/emulator strings** ("Initializing blink emulator… blink ready!") — #293; emulator UI, separate from lesson content.
PR #36 covers (1) for C# as the pilot. Suggest tracking (2)–(5) as explicit Phase-2 sub-items so per-surface ownership is clear.
PR #36 (engine) merged to master. First content batch is up in spikersoft-backend PR #37: Spanish codeTemplate for the beginner C# path — Tier 01 Foundations (100-107), Tier 02 Operators (200-206), Tier 03 Control Flow (300, 302-307); 301 shipped with Phase 1. 23 C# lessons now serve Spanish starter comments.
Comments-only invariant is enforced by tests (line-count + non-comment-line equality vs English), so translations can't drift the actual code.
Remaining (per-track content):
C# Tiers 04-16 (~80 lessons)
Python (incl. pass-placeholder annotation in AnnotatePlaceholdersForLanguage)
JavaScript
C / C++
x86 / Regex / SQL
Non-template surfaces from triage note (concept panels, regex hints, x86 terminal)
### Phase 2 progress — content batch 1 (C# Tiers 1-3)
PR #36 (engine) merged to `master`. First content batch is up in spikersoft-backend PR #37: Spanish `codeTemplate` for the beginner C# path — Tier 01 Foundations (100-107), Tier 02 Operators (200-206), Tier 03 Control Flow (300, 302-307); 301 shipped with Phase 1. 23 C# lessons now serve Spanish starter comments.
Comments-only invariant is enforced by tests (line-count + non-comment-line equality vs English), so translations can't drift the actual code.
**Remaining (per-track content):**
- [ ] C# Tiers 04-16 (~80 lessons)
- [ ] Python (incl. `pass`-placeholder annotation in `AnnotatePlaceholdersForLanguage`)
- [ ] JavaScript
- [ ] C / C++
- [ ] x86 / Regex / SQL
- [ ] Non-template surfaces from triage note (concept panels, regex hints, x86 terminal)
Intentionally skipped (no prose to localize): lessons whose only comments are pure code skeletons (506, 507, 708, 709) or inline comments on code lines that would break the code-line guard (800, 805, 1603).
Seed-token placeholders ({className}, {propName}, etc.) preserved so ApplySeedTokens still binds randomized values.
All 38 CurriculumLocaleTests pass, including the SpanishCodeTemplates_OnlyDifferInComments_FromEnglish guard now covering the full C# track.
C# track status: complete (pending #38 merge). Remaining content work for other languages (Python, JavaScript, C, C++, SQL, x86, Regex) and the broader untranslated surfaces noted earlier in this epic (regex hints, concept panels, x86 terminal strings) are still open.
**Phase 2, Batch 2 — C# Tiers 4-16 (PR spikersoft-backend#38, open)**
Following PR #37 (Tiers 1-3), this batch finishes Spanish `codeTemplate` comment localization for the **entire C# curriculum**:
- Tier 04 Methods (400-406), Tier 05 Collections (500-505), Tier 06 Strings (600-605), Tier 07 Classes (700-707, 710), Tier 08 Inheritance (801-804), Tier 09 Generics (900-903), Tier 10 Exceptions (1000-1003), Tier 11 LINQ (1100-1105), Tier 12 Delegates (1200-1203), Tier 13 Patterns (1300-1303), Tier 14 Nullability (1400-1402), Tier 15 Async (1500-1503), Tier 16 Advanced (1600-1602, 1604).
- **Intentionally skipped** (no prose to localize): lessons whose only comments are pure code skeletons (506, 507, 708, 709) or inline comments on code lines that would break the code-line guard (800, 805, 1603).
- Seed-token placeholders (`{className}`, `{propName}`, etc.) preserved so `ApplySeedTokens` still binds randomized values.
- All 38 `CurriculumLocaleTests` pass, including the `SpanishCodeTemplates_OnlyDifferInComments_FromEnglish` guard now covering the full C# track.
**C# track status: complete** (pending #38 merge). Remaining content work for other languages (Python, JavaScript, C, C++, SQL, x86, Regex) and the broader untranslated surfaces noted earlier in this epic (regex hints, concept panels, x86 terminal strings) are still open.
Localized starter codeTemplate comments for all 74 Python challenge lessons in es/python.json. Same discipline as the C# track: only comment lines translated, code lines byte-identical to the live English (enforced by SpanishCodeTemplates_OnlyDifferInComments_FromEnglish, 38/38 locale tests green). Comment-less code skeletons and tutorial lessons were skipped (nothing to translate). Lesson 20105 uses the {value} seed key instead of the build-time-only {literal} interpolation token so no raw token leaks under Spanish.
Remaining es/*.json tracks already have title/instructions/hints translated; only codeTemplate comments are outstanding.
**Phase 2 — Python track done.** Opened spikersoft-backend PR #39 (`fix/issue-296-python-codetemplate-content` → `master`).
Localized starter `codeTemplate` comments for **all 74 Python challenge lessons** in `es/python.json`. Same discipline as the C# track: only comment lines translated, code lines byte-identical to the live English (enforced by `SpanishCodeTemplates_OnlyDifferInComments_FromEnglish`, 38/38 locale tests green). Comment-less code skeletons and tutorial lessons were skipped (nothing to translate). Lesson 20105 uses the `{value}` seed key instead of the build-time-only `{literal}` interpolation token so no raw token leaks under Spanish.
**Track status (content fan-out):**
- [x] C# — Phase 1 pilot #36, Tiers 1-3 #37, Tiers 4-16 #38 (merged)
- [x] Python — #39 (open)
- [ ] JavaScript
- [ ] C / C++ / SQL / x86 / Regex
Remaining `es/*.json` tracks already have title/instructions/hints translated; only `codeTemplate` comments are outstanding.
Localized starter codeTemplate comments for all 127 JavaScript challenge lessons in es/javascript.json. This track was unusually uniform — 125 of 127 templates share one generic boilerplate comment, with only the Hello World lesson (30100) bespoke. No seed-token interpolation in any JS template comment, so no leak risk there. Same discipline as C#/Python: only comments translated, code lines byte-identical to the live English (38/38 locale tests green).
Remaining tracks already have title/instructions/hints translated; only codeTemplate comments outstanding.
**Phase 2 — JavaScript track done.** Opened spikersoft-backend PR #40 (`fix/issue-296-javascript-codetemplate-content` → `master`).
Localized starter `codeTemplate` comments for **all 127 JavaScript challenge lessons** in `es/javascript.json`. This track was unusually uniform — 125 of 127 templates share one generic boilerplate comment, with only the Hello World lesson (30100) bespoke. No seed-token interpolation in any JS template comment, so no leak risk there. Same discipline as C#/Python: only comments translated, code lines byte-identical to the live English (38/38 locale tests green).
**Track status (content fan-out):**
- [x] C# — merged (#36, #37, #38)
- [x] Python — merged (#39)
- [x] JavaScript — #40 (open)
- [ ] C / C++ / SQL / x86 / Regex
Remaining tracks already have title/instructions/hints translated; only `codeTemplate` comments outstanding.
Pausing the content fan-out here. While starting the C track, found that the Phase 1 overlay can't actually reach the starter source for C, C++, x86, SQL, and Regex — those five strategies ship their starter(s) inside a JSON blob (TestCode) that the SPA's browser grader reads client-side, never through BuiltAttempt.CodeTemplate. Translating their es/*.jsoncodeTemplate fields the way we did for C#/Python/JS would have had zero visible effect.
Filed #299 with the root-cause detail and a proposed Phase 1.5 engineering fix (per-track translation model: single starter for Clang, per-dialect map for x86, per-theme map for SQL; Regex needs an audit first to see if it even has translatable comments).
**Pausing the content fan-out here.** While starting the C track, found that the Phase 1 overlay can't actually reach the starter source for **C, C++, x86, SQL, and Regex** — those five strategies ship their starter(s) inside a JSON blob (`TestCode`) that the SPA's browser grader reads client-side, never through `BuiltAttempt.CodeTemplate`. Translating their `es/*.json` `codeTemplate` fields the way we did for C#/Python/JS would have had **zero visible effect**.
Filed **#299** with the root-cause detail and a proposed Phase 1.5 engineering fix (per-track translation model: single starter for Clang, per-dialect map for x86, per-theme map for SQL; Regex needs an audit first to see if it even has translatable comments).
**Current state:**
- [x] C# — merged (#36, #37, #38)
- [x] Python — merged (#39)
- [x] JavaScript — merged (#40)
- [ ] C, C++, x86, SQL, Regex — **blocked on #299**
Resuming once #299's engineering lands.
Also resolved as part of that work: audited Regex and SQL and confirmed neither has any starter content to localize today (no lesson uses a non-empty starter for either track), so they're not blocked — there's simply nothing to translate for them right now. Will drop them from the "blocked" list below once #299 merges.
Once #41 merges, content fan-out can resume for C, C++, and x86 (translating codeTemplate/codeTemplates per lesson in es/c.json, es/cpp.json, es/x86.json, the same way Python/JavaScript were done).
Engineering fix for the C/C++/x86 blocker is up for review: spikersoft-backend PR #41 (https://git.spikersoft.com/spikerj/spikersoft-backend/pulls/41), resolving #299.
Also resolved as part of that work: audited Regex and SQL and confirmed neither has any starter content to localize today (no lesson uses a non-empty starter for either track), so they're **not blocked** — there's simply nothing to translate for them right now. Will drop them from the "blocked" list below once #299 merges.
Once #41 merges, content fan-out can resume for C, C++, and x86 (translating `codeTemplate`/`codeTemplates` per lesson in `es/c.json`, `es/cpp.json`, `es/x86.json`, the same way Python/JavaScript were done).
Status update: the engineering blocker (#299) is resolved and merged (spikersoft-backend PR #41). LocalizeEmbeddedStarter now lets Clang (C/C++) and x86 localize their plan-embedded starters, piloted on C lesson 80100 and x86 lesson 50100. Regex and SQL confirmed as no-ops (no translatable starter content exists today; tripwire test guards against silent regression if that changes).
Phase 2 content fan-out can now resume for C, C++, x86 whenever we pick it back up. SQL/Regex need no further work on this front.
Unrelated side-finding while auditing test coverage for this epic's work: filed and fixed a general regression guard (SpanishTranslations_NoUnresolvedSeedTokensLeak, in PR #41) for translations referencing seed-token names that don't exist for that lesson — generalizes the one-off Lesson20105_VarBool fix into a permanent test across the whole curriculum.
Status update: the engineering blocker (#299) is resolved and merged (spikersoft-backend PR #41). `LocalizeEmbeddedStarter` now lets Clang (C/C++) and x86 localize their plan-embedded starters, piloted on C lesson 80100 and x86 lesson 50100. Regex and SQL confirmed as no-ops (no translatable starter content exists today; tripwire test guards against silent regression if that changes).
Phase 2 content fan-out can now resume for **C, C++, x86** whenever we pick it back up. SQL/Regex need no further work on this front.
Unrelated side-finding while auditing test coverage for this epic's work: filed and fixed a general regression guard (`SpanishTranslations_NoUnresolvedSeedTokensLeak`, in PR #41) for translations referencing seed-token names that don't exist for that lesson — generalizes the one-off Lesson20105_VarBool fix into a permanent test across the whole curriculum.
Housekeeping: individually re-confirmed and closed the older translation-wave tickets this epic referenced as "not folded in until individually re-confirmed":
#196 (JS), #197 (C#), #198 (Python), #199 (C), #200 (C++), #202 (Regex), #203 (SQL) — all confirmed fixed by the #279 backend content PRs (#25–#32).
#267, #268, #269, #270, #272, #273, #274 (the newer per-playground wave with the same symptom) — same confirmation, closed.
One partial exception: #271 (C++) reported both an instructions-panel symptom (now fixed) and an English-only Concept Reference dictionary panel symptom. The latter is a separate, frontend-only static-data system with no i18n at all (affects C#, Python, C, and C++ playgrounds). Split that into a new ticket, #301, and left #271 open until it lands.
Housekeeping: individually re-confirmed and closed the older translation-wave tickets this epic referenced as "not folded in until individually re-confirmed":
- #196 (JS), #197 (C#), #198 (Python), #199 (C), #200 (C++), #202 (Regex), #203 (SQL) — all confirmed fixed by the #279 backend content PRs (#25–#32).
- #267, #268, #269, #270, #272, #273, #274 (the newer per-playground wave with the same symptom) — same confirmation, closed.
One partial exception: #271 (C++) reported both an instructions-panel symptom (now fixed) **and** an English-only Concept Reference dictionary panel symptom. The latter is a separate, frontend-only static-data system with no i18n at all (affects C#, Python, C, and C++ playgrounds). Split that into a new ticket, #301, and left #271 open until it lands.
x86 content fan-out is done — backend PR spikersoft-backend#310 (branch feat/296-x86-starter-es, not merged yet).
Added per-dialect codeTemplates Spanish overlays to all 33 comment-bearing x86 Challenge lessons (50101–50905) in es/x86.json — the pilot #299 had only localized 50100, leaving the rest serving the English >>> your code goes here <<< marker and the Chapter 6–9 body hints under a Spanish UI. Comments only; every code line is byte-identical to the English starter (grading unaffected), and each lesson's AllowedDialects is honored (Chapter 9 single-dialect lessons get one starter). Also localized lesson 50004's tutorial prose that quoted the marker, and added a permanent tripwire EveryX86ChallengeStarter_IsLocalizedToSpanish so a future un-localized lesson fails the build.
That leaves x86 alongside C#/Python/JS/C/C++ as fully localized (Regex/SQL are intentional no-ops), so all 8 playgrounds are covered. Leaving this open for you to close after #310 merges.
x86 content fan-out is done — backend PR spikersoft-backend#310 (branch `feat/296-x86-starter-es`, **not merged yet**).
Added per-dialect `codeTemplates` Spanish overlays to all **33** comment-bearing x86 Challenge lessons (50101–50905) in `es/x86.json` — the pilot #299 had only localized 50100, leaving the rest serving the English `>>> your code goes here <<<` marker and the Chapter 6–9 body hints under a Spanish UI. Comments only; every code line is byte-identical to the English starter (grading unaffected), and each lesson's `AllowedDialects` is honored (Chapter 9 single-dialect lessons get one starter). Also localized lesson 50004's tutorial prose that quoted the marker, and added a permanent tripwire `EveryX86ChallengeStarter_IsLocalizedToSpanish` so a future un-localized lesson fails the build.
Verified locally: `SpikerSoft.UnitTests.slnf` + `SpikerSoft.Wasm` build clean; `CurriculumLocaleTests` 43/43; tripwire confirmed to fail pre-change.
That leaves x86 alongside C#/Python/JS/C/C++ as fully localized (Regex/SQL are intentional no-ops), so all 8 playgrounds are covered. Leaving this open for you to close after #310 merges.
Board-sweep verified complete: the formatter mechanism (PR #36) fanned out across all 8 playgrounds — C# #37/#38, Python #39, JS #40, C #47, C++ #49, x86 #310 — all merged (es/x86.json verified in tree). The last comment's own condition was 'close after #310 merges'; it merged. Closing.
Board-sweep verified complete: the formatter mechanism (PR #36) fanned out across all 8 playgrounds — C# #37/#38, Python #39, JS #40, C #47, C++ #49, x86 #310 — all merged (es/x86.json verified in tree). The last comment's own condition was 'close after #310 merges'; it merged. Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary (confirmed root cause)
Lesson code-editor starter templates are never localized — the comments inside the editable code (e.g. C# lesson 301:
// return one label when flag is true, the other when false) always render in English even when UI + lesson text are Spanish. Verified in code:LessonStrategyBase.Localization.cs→FinalizeAttemptWithLocaleoverlays Instructions / Hints / TutorialPanels only, and passes the original Englishbuilt.CodeTemplatestraight through toFinalizeAttemptCore.CurriculumTranslationStore.LessonTranslationEntry) has nocodeTemplatefield — so a translated template can't even be expressed today.Lesson301_IfElse.cs(the exact comment in the report) and thees/csharp.jsonentry for 301 (has translated instructions/hints, no template).This is one structural root cause behind the entire per-language cluster.
Consolidates
(Older translation waves #267–274 and #196–203 are about instructions/lesson text — a different symptom, largely addressed by the #279 content work — and are NOT folded in here until individually re-confirmed.)
Plan
Phase 1 — Engineering (this epic's first PR)
codeTemplatefield toLessonTranslationEntry/LessonTranslationand the store loader.FinalizeAttemptWithLocale, when a translatedcodeTemplateexists, overlay it (withApplySeedTokensfor randomized lessons) beforeFinalizeAttemptCore.Phase 2 — Content fan-out (per track)
codeTemplateentries (comments only; keep identifiers/keywords as code) for every Challenge lesson, per track: C#, Python, JavaScript, C, C++, x86, Regex, SQL.Known follow-up (track separately)
LessonStrategyBase.Localization.csis server-only). Connected mode is fixed by Phase 1; offline localization of the template needs a separate SPA/WASM change.Acceptance criteria
?contentLocale=eswith passing tests.Severity
Medium (localization completeness; comprehension for Spanish-speaking learners).
Triage note — extra untranslated surfaces folded in from #288–#295
Reading the full reports, a few of the closed duplicates point at surfaces beyond the starter-template comments. Capturing them here so they aren't lost (each needs its own data/overlay work under Phase 2):
; Flat Assembler file), #295 SQL (-- Welcome to the SQL playground.). Python (#289)# replace this with your codeis the auto-generatedpass-placeholder annotation — needs localizing inAnnotatePlaceholdersForLanguage, not JSON.PR #36 covers (1) for C# as the pilot. Suggest tracking (2)–(5) as explicit Phase-2 sub-items so per-surface ownership is clear.
Phase 2 progress — content batch 1 (C# Tiers 1-3)
PR #36 (engine) merged to
master. First content batch is up in spikersoft-backend PR #37: SpanishcodeTemplatefor the beginner C# path — Tier 01 Foundations (100-107), Tier 02 Operators (200-206), Tier 03 Control Flow (300, 302-307); 301 shipped with Phase 1. 23 C# lessons now serve Spanish starter comments.Comments-only invariant is enforced by tests (line-count + non-comment-line equality vs English), so translations can't drift the actual code.
Remaining (per-track content):
pass-placeholder annotation inAnnotatePlaceholdersForLanguage)Phase 2, Batch 2 — C# Tiers 4-16 (PR spikersoft-backend#38, open)
Following PR #37 (Tiers 1-3), this batch finishes Spanish
codeTemplatecomment localization for the entire C# curriculum:{className},{propName}, etc.) preserved soApplySeedTokensstill binds randomized values.CurriculumLocaleTestspass, including theSpanishCodeTemplates_OnlyDifferInComments_FromEnglishguard now covering the full C# track.C# track status: complete (pending #38 merge). Remaining content work for other languages (Python, JavaScript, C, C++, SQL, x86, Regex) and the broader untranslated surfaces noted earlier in this epic (regex hints, concept panels, x86 terminal strings) are still open.
Phase 2 — Python track done. Opened spikersoft-backend PR #39 (
fix/issue-296-python-codetemplate-content→master).Localized starter
codeTemplatecomments for all 74 Python challenge lessons ines/python.json. Same discipline as the C# track: only comment lines translated, code lines byte-identical to the live English (enforced bySpanishCodeTemplates_OnlyDifferInComments_FromEnglish, 38/38 locale tests green). Comment-less code skeletons and tutorial lessons were skipped (nothing to translate). Lesson 20105 uses the{value}seed key instead of the build-time-only{literal}interpolation token so no raw token leaks under Spanish.Track status (content fan-out):
Remaining
es/*.jsontracks already have title/instructions/hints translated; onlycodeTemplatecomments are outstanding.Phase 2 — JavaScript track done. Opened spikersoft-backend PR #40 (
fix/issue-296-javascript-codetemplate-content→master).Localized starter
codeTemplatecomments for all 127 JavaScript challenge lessons ines/javascript.json. This track was unusually uniform — 125 of 127 templates share one generic boilerplate comment, with only the Hello World lesson (30100) bespoke. No seed-token interpolation in any JS template comment, so no leak risk there. Same discipline as C#/Python: only comments translated, code lines byte-identical to the live English (38/38 locale tests green).Track status (content fan-out):
Remaining tracks already have title/instructions/hints translated; only
codeTemplatecomments outstanding.Pausing the content fan-out here. While starting the C track, found that the Phase 1 overlay can't actually reach the starter source for C, C++, x86, SQL, and Regex — those five strategies ship their starter(s) inside a JSON blob (
TestCode) that the SPA's browser grader reads client-side, never throughBuiltAttempt.CodeTemplate. Translating theires/*.jsoncodeTemplatefields the way we did for C#/Python/JS would have had zero visible effect.Filed #299 with the root-cause detail and a proposed Phase 1.5 engineering fix (per-track translation model: single starter for Clang, per-dialect map for x86, per-theme map for SQL; Regex needs an audit first to see if it even has translatable comments).
Current state:
Resuming once #299's engineering lands.
Engineering fix for the C/C++/x86 blocker is up for review: spikersoft-backend PR #41 (spikerj/spikersoft-backend#41), resolving #299.
Also resolved as part of that work: audited Regex and SQL and confirmed neither has any starter content to localize today (no lesson uses a non-empty starter for either track), so they're not blocked — there's simply nothing to translate for them right now. Will drop them from the "blocked" list below once #299 merges.
Once #41 merges, content fan-out can resume for C, C++, and x86 (translating
codeTemplate/codeTemplatesper lesson ines/c.json,es/cpp.json,es/x86.json, the same way Python/JavaScript were done).Status update: the engineering blocker (#299) is resolved and merged (spikersoft-backend PR #41).
LocalizeEmbeddedStarternow lets Clang (C/C++) and x86 localize their plan-embedded starters, piloted on C lesson 80100 and x86 lesson 50100. Regex and SQL confirmed as no-ops (no translatable starter content exists today; tripwire test guards against silent regression if that changes).Phase 2 content fan-out can now resume for C, C++, x86 whenever we pick it back up. SQL/Regex need no further work on this front.
Unrelated side-finding while auditing test coverage for this epic's work: filed and fixed a general regression guard (
SpanishTranslations_NoUnresolvedSeedTokensLeak, in PR #41) for translations referencing seed-token names that don't exist for that lesson — generalizes the one-off Lesson20105_VarBool fix into a permanent test across the whole curriculum.Housekeeping: individually re-confirmed and closed the older translation-wave tickets this epic referenced as "not folded in until individually re-confirmed":
One partial exception: #271 (C++) reported both an instructions-panel symptom (now fixed) and an English-only Concept Reference dictionary panel symptom. The latter is a separate, frontend-only static-data system with no i18n at all (affects C#, Python, C, and C++ playgrounds). Split that into a new ticket, #301, and left #271 open until it lands.
x86 content fan-out is done — backend PR spikersoft-backend#310 (branch
feat/296-x86-starter-es, not merged yet).Added per-dialect
codeTemplatesSpanish overlays to all 33 comment-bearing x86 Challenge lessons (50101–50905) ines/x86.json— the pilot #299 had only localized 50100, leaving the rest serving the English>>> your code goes here <<<marker and the Chapter 6–9 body hints under a Spanish UI. Comments only; every code line is byte-identical to the English starter (grading unaffected), and each lesson'sAllowedDialectsis honored (Chapter 9 single-dialect lessons get one starter). Also localized lesson 50004's tutorial prose that quoted the marker, and added a permanent tripwireEveryX86ChallengeStarter_IsLocalizedToSpanishso a future un-localized lesson fails the build.Verified locally:
SpikerSoft.UnitTests.slnf+SpikerSoft.Wasmbuild clean;CurriculumLocaleTests43/43; tripwire confirmed to fail pre-change.That leaves x86 alongside C#/Python/JS/C/C++ as fully localized (Regex/SQL are intentional no-ops), so all 8 playgrounds are covered. Leaving this open for you to close after #310 merges.
Board-sweep verified complete: the formatter mechanism (PR #36) fanned out across all 8 playgrounds — C# #37/#38, Python #39, JS #40, C #47, C++ #49, x86 #310 — all merged (es/x86.json verified in tree). The last comment's own condition was 'close after #310 merges'; it merged. Closing.