Enhancement for /tree-of-knowledge/domain(tools:python-playground) — the Python playground (PythonRunner) should track lesson completion per lesson, not only a generic "run lesson" signal.
Problem
Current behavior appears to record a generic run rather than which lessons were completed in this playground.
Goals
Per-lesson completion state for the Pyodide/Python runner path.
Consistent patterns with C# and JavaScript playground sibling tickets.
Clear progress for learners alongside ToK navigation.
Acceptance (draft)
Lesson-keyed completion persisted for Python playground.
UI exposes completed / not completed per lesson where the playground lists lessons.
Shared contract with #43 (C#) and #45 (JS) — single progress service or conventions doc.
Telemetry updated so runs are attributable to lesson id.
## Summary
**Enhancement** for **`/tree-of-knowledge/domain`(tools:python-playground)** — the **Python playground** (`PythonRunner`) should **track lesson completion per lesson**, not only a **generic "run lesson"** signal.
## Problem
Current behavior appears to record a **generic run** rather than **which lessons** were completed in this playground.
## Goals
- **Per-lesson** completion state for the Pyodide/Python runner path.
- **Consistent patterns** with C# and JavaScript playground sibling tickets.
- Clear **progress** for learners alongside ToK navigation.
## Acceptance (draft)
- [ ] **Lesson-keyed completion** persisted for Python playground.
- [ ] UI exposes **completed / not completed** per lesson where the playground lists lessons.
- [ ] Shared contract with **[#43](https://git.spikersoft.com/spikerj/spikersoft-issues/issues/43)** (C#) and **[#45](https://git.spikersoft.com/spikerj/spikersoft-issues/issues/45)** (JS) — single progress service or conventions doc.
- [ ] Telemetry updated so runs are attributable to **lesson id**.
## Area
`PythonRunner` · app-language-runner · `/tree-of-knowledge/domain` tools outlet (`python-playground`).
## Sibling tickets (same enhancement pattern)
- **[#43 — C# playground](https://git.spikersoft.com/spikerj/spikersoft-issues/issues/43)**
- **[#45 — JavaScript playground](https://git.spikersoft.com/spikerj/spikersoft-issues/issues/45)**
Closing as already implemented by the same shared infrastructure that resolved#43.
The Python playground (PythonRunner at libraries/features/dev-tools-python-runner/src/lib/python-runner.ts) is a thin shell over the shared LanguageRunner, configured with LANGUAGE_RUNTIME_ADAPTER = PythonRuntimeAdapter and the same PROGRESS_SYNC_PORT_PROVIDER. It picks up the full per-lesson completion stack by construction:
Durable backend record — one UserLessonProgress Mongo doc per (UserId, LessonNumber) with attempts, test results, timing.
Offline queue — ProgressSyncService IndexedDB queue with language: "python", server re-verifies on reconnect.
One caveat carried over from #43: the server-side ExecuteLessonCodeCommand is annotated [TrackableActivity("tools.csharp-playground", "run-lesson")], so generic analytics rows for Python submissions land under csharp-playground instead of python-playground. Durable completion is correct — only the activity attribution is wrong. Filing a separate cross-cutting ticket for that.
Closing as **already implemented** by the same shared infrastructure that resolved #43.
The Python playground (`PythonRunner` at `libraries/features/dev-tools-python-runner/src/lib/python-runner.ts`) is a thin shell over the shared `LanguageRunner`, configured with `LANGUAGE_RUNTIME_ADAPTER = PythonRuntimeAdapter` and the same `PROGRESS_SYNC_PORT_PROVIDER`. It picks up the full per-lesson completion stack by construction:
- **Durable backend record** — one `UserLessonProgress` Mongo doc per `(UserId, LessonNumber)` with attempts, test results, timing.
- **Offline queue** — `ProgressSyncService` IndexedDB queue with `language: "python"`, server re-verifies on reconnect.
- **UI** — `LessonSidebar` consumes `completedLessonNumbers` and renders checkmarks / locks / progress counts.
- **Shared contract** — same `ProgressSyncPort` / `QueuedProgressInput` / `/Lessons/progress` endpoints used by C# (#43) and JavaScript (#45).
Full architectural breakdown is in #43's [closing comment](https://git.spikersoft.com/spikerj/spikersoft-issues/issues/43#issuecomment-179).
One caveat carried over from #43: the server-side `ExecuteLessonCodeCommand` is annotated `[TrackableActivity("tools.csharp-playground", "run-lesson")]`, so generic *analytics* rows for Python submissions land under `csharp-playground` instead of `python-playground`. Durable completion is correct — only the activity attribution is wrong. Filing a separate cross-cutting ticket for that.
Closing #44.
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
Enhancement for
/tree-of-knowledge/domain(tools:python-playground) — the Python playground (PythonRunner) should track lesson completion per lesson, not only a generic "run lesson" signal.Problem
Current behavior appears to record a generic run rather than which lessons were completed in this playground.
Goals
Acceptance (draft)
Area
PythonRunner· app-language-runner ·/tree-of-knowledge/domaintools outlet (python-playground).Sibling tickets (same enhancement pattern)
Closing as already implemented by the same shared infrastructure that resolved #43.
The Python playground (
PythonRunneratlibraries/features/dev-tools-python-runner/src/lib/python-runner.ts) is a thin shell over the sharedLanguageRunner, configured withLANGUAGE_RUNTIME_ADAPTER = PythonRuntimeAdapterand the samePROGRESS_SYNC_PORT_PROVIDER. It picks up the full per-lesson completion stack by construction:UserLessonProgressMongo doc per(UserId, LessonNumber)with attempts, test results, timing.ProgressSyncServiceIndexedDB queue withlanguage: "python", server re-verifies on reconnect.LessonSidebarconsumescompletedLessonNumbersand renders checkmarks / locks / progress counts.ProgressSyncPort/QueuedProgressInput//Lessons/progressendpoints used by C# (#43) and JavaScript (#45).Full architectural breakdown is in #43's closing comment.
One caveat carried over from #43: the server-side
ExecuteLessonCodeCommandis annotated[TrackableActivity("tools.csharp-playground", "run-lesson")], so generic analytics rows for Python submissions land undercsharp-playgroundinstead ofpython-playground. Durable completion is correct — only the activity attribution is wrong. Filing a separate cross-cutting ticket for that.Closing #44.