While fanning out Epic #296's content work past C#/Python/JavaScript, found that the Phase 1 overlay (LessonStrategyBase.Localization.cs → FinalizeAttemptWithLocale, which patches built.CodeTemplate from tr.CodeTemplate) cannot reach the starter source for 5 of the 8 playgrounds: C, C++, x86, SQL, and Regex.
Root cause
ClangLessonStrategyBase (C/C++), X86LessonStrategyBase, and RegexLessonStrategyBase all hard-code:
returnnewBuiltAttempt(...CodeTemplate:string.Empty,// always emptyTestCode:json,// the real starter lives in here instead...);
The actual editor starter ships inside a JSON blob (ClangLessonPlan.Starter, per-dialect x86 starters, regex's plan) serialized into LessonAttemptState.TestCode. The SPA's browser graders (Clang/x86/Regex run entirely client-side, no server execution) read the starter out of that JSON after hydrating — never from BuiltAttempt.CodeTemplate. So translating codeTemplate in es/c.json / es/cpp.json / es/x86.json / es/regex.json would have zero visible effect for Challenge lessons.
SqlLessonStrategyBase is a partial variant: it projects the default theme'sStarterQuery into BuiltAttempt.CodeTemplate (so the overlay would apply there), but the durable per-theme starter map lives inside the same TestCode JSON and is what the SPA actually renders after it hydrates the active theme — so a translated es/sql.jsoncodeTemplate would only affect a one-frame flash before theme hydration, not the served starter.
Proposed fix (Phase 1.5 engineering, before any Phase 2 content for these 5 tracks)
Each plan type needs its own localized-starter overlay, applied before JSON-serializing the plan in BuildAttempt, or as a post-process step that deserializes/patches/re-serializes TestCode:
Clang (C/C++): translate ClangLessonPlan.Starter (single starter per lesson).
x86: translate each per-dialect starter (GNU/FASM/NASM) — likely 3x the content surface of the other tracks.
SQL: translate SqlThemeBinding.StarterQuery for all 3 themes (Travel/VideoGames/Animals) per lesson — also a 3x surface.
Regex: check whether regex lessons even have a starter-with-comments worth localizing (regex patterns are typically comment-free); may turn out to be a no-op track.
This likely means extending CurriculumTranslationStore's translation model with per-family shapes (e.g. CodeTemplate for Clang, CodeTemplates: { travel, videoGames, animals } for SQL, CodeTemplates: { gnu, fasm, nasm } for x86) rather than reusing the single flat CodeTemplate string that works for C#/Python/JS.
Acceptance criteria
Decide per-track translation model shape (single string vs. per-theme/per-dialect map).
Overlay applied before/during plan JSON serialization so the SPA's hydrated starter is actually localized, not just the pre-hydration flash.
Confirm whether Regex needs this at all (audit existing regex starters for translatable comments first).
Pilot end-to-end on one Clang (C) lesson + unit coverage, mirroring the #296 Phase 1 pilot pattern.
Once landed, Phase 2 content fan-out can resume for C, C++, x86, SQL (and Regex if applicable).
Status of Epic #296 content fan-out (for reference)
Medium — same comprehension impact as the parent epic, but discovered before any wasted content-authoring effort (content for these 5 tracks would have silently had no effect on what students actually see).
## Summary
While fanning out Epic #296's content work past C#/Python/JavaScript, found that the Phase 1 overlay (`LessonStrategyBase.Localization.cs` → `FinalizeAttemptWithLocale`, which patches `built.CodeTemplate` from `tr.CodeTemplate`) **cannot reach the starter source for 5 of the 8 playgrounds**: C, C++, x86, SQL, and Regex.
### Root cause
`ClangLessonStrategyBase` (C/C++), `X86LessonStrategyBase`, and `RegexLessonStrategyBase` all hard-code:
```csharp
return new BuiltAttempt(
...
CodeTemplate: string.Empty, // always empty
TestCode: json, // the real starter lives in here instead
...);
```
The actual editor starter ships inside a JSON blob (`ClangLessonPlan.Starter`, per-dialect x86 starters, regex's plan) serialized into `LessonAttemptState.TestCode`. The SPA's browser graders (Clang/x86/Regex run **entirely client-side**, no server execution) read the starter out of that JSON after hydrating — never from `BuiltAttempt.CodeTemplate`. So translating `codeTemplate` in `es/c.json` / `es/cpp.json` / `es/x86.json` / `es/regex.json` would have **zero visible effect** for Challenge lessons.
`SqlLessonStrategyBase` is a partial variant: it projects the **default theme's** `StarterQuery` into `BuiltAttempt.CodeTemplate` (so the overlay *would* apply there), but the durable per-theme starter map lives inside the same `TestCode` JSON and is what the SPA actually renders after it hydrates the active theme — so a translated `es/sql.json` `codeTemplate` would only affect a one-frame flash before theme hydration, not the served starter.
Confirmed via static read of:
- `SpikerSoft.Business/Domain/Lessons/Curriculum/Clang/ClangLessonStrategyBase.cs` (`BuildAttempt`, lines ~32-59)
- `SpikerSoft.Business/Domain/Lessons/Curriculum/X86/X86LessonStrategyBase.cs` (`BuildAttempt`, lines ~53-70+)
- `SpikerSoft.Business/Domain/Lessons/Curriculum/Sql/SqlLessonStrategyBase.cs` (`BuildAttempt`, lines ~42-87)
- `SpikerSoft.Business/Domain/Lessons/Curriculum/Regex/RegexLessonStrategyBase.cs` (`BuildAttempt`, lines ~31-60+)
## Proposed fix (Phase 1.5 engineering, before any Phase 2 content for these 5 tracks)
Each plan type needs its own localized-starter overlay, applied **before** JSON-serializing the plan in `BuildAttempt`, or as a post-process step that deserializes/patches/re-serializes `TestCode`:
- **Clang (C/C++)**: translate `ClangLessonPlan.Starter` (single starter per lesson).
- **x86**: translate each per-dialect starter (GNU/FASM/NASM) — likely 3x the content surface of the other tracks.
- **SQL**: translate `SqlThemeBinding.StarterQuery` for all 3 themes (Travel/VideoGames/Animals) per lesson — also a 3x surface.
- **Regex**: check whether regex lessons even have a starter-with-comments worth localizing (regex patterns are typically comment-free); may turn out to be a no-op track.
This likely means extending `CurriculumTranslationStore`'s translation model with per-family shapes (e.g. `CodeTemplate` for Clang, `CodeTemplates: { travel, videoGames, animals }` for SQL, `CodeTemplates: { gnu, fasm, nasm }` for x86) rather than reusing the single flat `CodeTemplate` string that works for C#/Python/JS.
## Acceptance criteria
- [ ] Decide per-track translation model shape (single string vs. per-theme/per-dialect map).
- [ ] Overlay applied before/during plan JSON serialization so the SPA's hydrated starter is actually localized, not just the pre-hydration flash.
- [ ] Confirm whether Regex needs this at all (audit existing regex starters for translatable comments first).
- [ ] Pilot end-to-end on one Clang (C) lesson + unit coverage, mirroring the #296 Phase 1 pilot pattern.
- [ ] Once landed, Phase 2 content fan-out can resume for C, C++, x86, SQL (and Regex if applicable).
## Status of Epic #296 content fan-out (for reference)
- [x] C# — merged (#36, #37, #38)
- [x] Python — merged (#39)
- [x] JavaScript — merged (#40)
- [ ] C, C++, x86, SQL, Regex — **blocked on this ticket**
## Severity
Medium — same comprehension impact as the parent epic, but discovered before any wasted content-authoring effort (content for these 5 tracks would have silently had no effect on what students actually see).
Added a LocalizeEmbeddedStarter hook on LessonStrategyBase, called from the locale-aware finalize path, so lesson families can patch their own JSON-embedded starter(s) in TestCode the same way the #296 overlay patches CodeTemplate directly.
Clang (C/C++) overrides it and reuses the existing single codeTemplate field — one starter per lesson. Covers both C and C++ since they share ClangLessonStrategyBase.
x86 overrides it using a new codeTemplates dictionary field keyed by dialect ("GNU"/"FASM"/"NASM") — it ships up to three starters per lesson.
Regex and SQL audited and confirmed no-ops: neither has any starter content to localize today (no chapter overrides BuildStarterPattern; no chapter passes a non-null starterQuery). Added a tripwire test so this surfaces immediately if that ever changes. No engineering needed for these two.
Piloted end-to-end on one lesson per engineered track (C 80100, x86 50100) with translated es content + regression tests, mirroring the #296 Phase 1 pilot pattern.
Caught and fixed a subtlety along the way: reusing the codeTemplate field for Clang would have leaked a non-empty attempt.CodeTemplate into Spanish only (English is empty by design for this family) — gated the original overlay on the English template being non-empty to keep the wire payload locale-consistent.
Will close this out once the PR is merged, and update Epic #296 to unblock the C/C++/x86 content fan-out (and to drop SQL/Regex from that blocked list since they're confirmed no-ops).
Opened spikersoft-backend PR #41: https://git.spikersoft.com/spikerj/spikersoft-backend/pulls/41
Summary of the engineering work:
- Added a `LocalizeEmbeddedStarter` hook on `LessonStrategyBase`, called from the locale-aware finalize path, so lesson families can patch their own JSON-embedded starter(s) in `TestCode` the same way the #296 overlay patches `CodeTemplate` directly.
- **Clang (C/C++)** overrides it and reuses the existing single `codeTemplate` field — one starter per lesson. Covers both C and C++ since they share `ClangLessonStrategyBase`.
- **x86** overrides it using a new `codeTemplates` dictionary field keyed by dialect (`"GNU"`/`"FASM"`/`"NASM"`) — it ships up to three starters per lesson.
- **Regex and SQL audited and confirmed no-ops**: neither has any starter content to localize today (no chapter overrides `BuildStarterPattern`; no chapter passes a non-null `starterQuery`). Added a tripwire test so this surfaces immediately if that ever changes. No engineering needed for these two.
- Piloted end-to-end on one lesson per engineered track (C 80100, x86 50100) with translated `es` content + regression tests, mirroring the #296 Phase 1 pilot pattern.
- Caught and fixed a subtlety along the way: reusing the `codeTemplate` field for Clang would have leaked a non-empty `attempt.CodeTemplate` into Spanish only (English is empty by design for this family) — gated the original overlay on the English template being non-empty to keep the wire payload locale-consistent.
Will close this out once the PR is merged, and update Epic #296 to unblock the C/C++/x86 content fan-out (and to drop SQL/Regex from that blocked list since they're confirmed no-ops).
Resolved in spikersoft-backend PR #41 (merged to master). Added a LocalizeEmbeddedStarter hook so Clang (C/C++) and x86 lesson strategies can localize their JSON-embedded starter code (previously invisible to the #296 overlay, which only patched BuiltAttempt.CodeTemplate). Piloted on C lesson 80100 and x86 lesson 50100. Regex and SQL audited and confirmed to have no starter content to localize today (tripwire test added for if that changes). Closing.
Resolved in spikersoft-backend PR #41 (merged to `master`). Added a `LocalizeEmbeddedStarter` hook so Clang (C/C++) and x86 lesson strategies can localize their JSON-embedded starter code (previously invisible to the #296 overlay, which only patched `BuiltAttempt.CodeTemplate`). Piloted on C lesson 80100 and x86 lesson 50100. Regex and SQL audited and confirmed to have no starter content to localize today (tripwire test added for if that changes). 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
While fanning out Epic #296's content work past C#/Python/JavaScript, found that the Phase 1 overlay (
LessonStrategyBase.Localization.cs→FinalizeAttemptWithLocale, which patchesbuilt.CodeTemplatefromtr.CodeTemplate) cannot reach the starter source for 5 of the 8 playgrounds: C, C++, x86, SQL, and Regex.Root cause
ClangLessonStrategyBase(C/C++),X86LessonStrategyBase, andRegexLessonStrategyBaseall hard-code:The actual editor starter ships inside a JSON blob (
ClangLessonPlan.Starter, per-dialect x86 starters, regex's plan) serialized intoLessonAttemptState.TestCode. The SPA's browser graders (Clang/x86/Regex run entirely client-side, no server execution) read the starter out of that JSON after hydrating — never fromBuiltAttempt.CodeTemplate. So translatingcodeTemplateines/c.json/es/cpp.json/es/x86.json/es/regex.jsonwould have zero visible effect for Challenge lessons.SqlLessonStrategyBaseis a partial variant: it projects the default theme'sStarterQueryintoBuiltAttempt.CodeTemplate(so the overlay would apply there), but the durable per-theme starter map lives inside the sameTestCodeJSON and is what the SPA actually renders after it hydrates the active theme — so a translatedes/sql.jsoncodeTemplatewould only affect a one-frame flash before theme hydration, not the served starter.Confirmed via static read of:
SpikerSoft.Business/Domain/Lessons/Curriculum/Clang/ClangLessonStrategyBase.cs(BuildAttempt, lines ~32-59)SpikerSoft.Business/Domain/Lessons/Curriculum/X86/X86LessonStrategyBase.cs(BuildAttempt, lines ~53-70+)SpikerSoft.Business/Domain/Lessons/Curriculum/Sql/SqlLessonStrategyBase.cs(BuildAttempt, lines ~42-87)SpikerSoft.Business/Domain/Lessons/Curriculum/Regex/RegexLessonStrategyBase.cs(BuildAttempt, lines ~31-60+)Proposed fix (Phase 1.5 engineering, before any Phase 2 content for these 5 tracks)
Each plan type needs its own localized-starter overlay, applied before JSON-serializing the plan in
BuildAttempt, or as a post-process step that deserializes/patches/re-serializesTestCode:ClangLessonPlan.Starter(single starter per lesson).SqlThemeBinding.StarterQueryfor all 3 themes (Travel/VideoGames/Animals) per lesson — also a 3x surface.This likely means extending
CurriculumTranslationStore's translation model with per-family shapes (e.g.CodeTemplatefor Clang,CodeTemplates: { travel, videoGames, animals }for SQL,CodeTemplates: { gnu, fasm, nasm }for x86) rather than reusing the single flatCodeTemplatestring that works for C#/Python/JS.Acceptance criteria
Status of Epic #296 content fan-out (for reference)
Severity
Medium — same comprehension impact as the parent epic, but discovered before any wasted content-authoring effort (content for these 5 tracks would have silently had no effect on what students actually see).
Opened spikersoft-backend PR #41: spikerj/spikersoft-backend#41
Summary of the engineering work:
LocalizeEmbeddedStarterhook onLessonStrategyBase, called from the locale-aware finalize path, so lesson families can patch their own JSON-embedded starter(s) inTestCodethe same way the #296 overlay patchesCodeTemplatedirectly.codeTemplatefield — one starter per lesson. Covers both C and C++ since they shareClangLessonStrategyBase.codeTemplatesdictionary field keyed by dialect ("GNU"/"FASM"/"NASM") — it ships up to three starters per lesson.BuildStarterPattern; no chapter passes a non-nullstarterQuery). Added a tripwire test so this surfaces immediately if that ever changes. No engineering needed for these two.escontent + regression tests, mirroring the #296 Phase 1 pilot pattern.codeTemplatefield for Clang would have leaked a non-emptyattempt.CodeTemplateinto Spanish only (English is empty by design for this family) — gated the original overlay on the English template being non-empty to keep the wire payload locale-consistent.Will close this out once the PR is merged, and update Epic #296 to unblock the C/C++/x86 content fan-out (and to drop SQL/Regex from that blocked list since they're confirmed no-ops).
Resolved in spikersoft-backend PR #41 (merged to
master). Added aLocalizeEmbeddedStarterhook so Clang (C/C++) and x86 lesson strategies can localize their JSON-embedded starter code (previously invisible to the #296 overlay, which only patchedBuiltAttempt.CodeTemplate). Piloted on C lesson 80100 and x86 lesson 50100. Regex and SQL audited and confirmed to have no starter content to localize today (tripwire test added for if that changes). Closing.