[Epic #296 follow-up] codeTemplate overlay never reaches C/C++/x86/SQL/Regex starters (plan-embedded, not BuiltAttempt.CodeTemplate) #299

Closed
opened 2026-06-30 19:31:03 +00:00 by spikerj · 2 comments
Owner

Summary

While fanning out Epic #296's content work past C#/Python/JavaScript, found that the Phase 1 overlay (LessonStrategyBase.Localization.csFinalizeAttemptWithLocale, 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:

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)

  • C# — merged (#36, #37, #38)
  • Python — merged (#39)
  • 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).

## 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).
Author
Owner

Opened spikersoft-backend PR #41: spikerj/spikersoft-backend#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).

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).
Author
Owner

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.
Sign in to join this conversation.