Repository navigation
fix(practice): converge the practice gate and repair the #41 findings - #43
Merged
Merged
Conversation
…akage Closes #41. - Practice work survives a reload: derivePendingSubmissions rebuilds practiceWork from the gradedBlocks already persisted per field, so a completed scene reopens in review mode showing the learner's own answers instead of a blank app. - A blank Introduction scene no longer publishes: author-document treats the untouched default document as empty. - getSceneContent on a PRACTICE scene refuses by name and points at getPractice, instead of returning a scene with no content. - The draft editor counts practice SP the way the player does, through a shared sumPracticeSolutionSp. - One gate for everything: checkPracticeScene(html, solution) is a pure check that publish, MCP validatePractice and the editor's readiness line all run. No stamp column, no content hash, no browser sweep — so an agent goes from createCourse to publishCourse without a UI visit, and publish refuses an unfinished app with the same sentence validatePractice gives. - publish failures carry details.params and are translated client-side; every code has en and de copy. Integration tests provision their own throwaway Postgres (pgvector, bound to loopback) and tear it down on every exit path, including Ctrl-C and failure; INT_DB still overrides for a local cluster you already have. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Already present when this branch's work started: deslop comment-scanner tweaks, editor CSS, two i18n strings, and a whitespace-only reformat of the vendored prism package.json. Split out so the fix commit stays readable — drop this one if the branch should carry only #41. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #41.
1. Practice work lost on reload — fixed, no new column
gradedBlocksalready persists alearnerAnswerper practice field, and agraded practice field's
blockIdis its solution field id — so the workobject can be rebuilt rather than stored twice.
derivePendingSubmissionsdoes that, and
sdkScriptnow startssubmitted = truein review mode, so aresumed scene reopens with the learner's own answers and an inert Submit.
An exploratory scene (
solution: null) grades no fields, so there is nothingto rebuild — it reopens blank but non-resubmittable, which is what the ticket
asked for as the floor.
2. Auto-created Introduction scene — fixed
isBlankHtmlStatenow recognises what the seeder actually writes, so theuntouched default classifies as
EMPTY_SCENE("add content") instead ofUNREADABLE_SCENE("open the scene and re-save it") — an instruction an agentcan act on.
3.
getSceneContenton a PRACTICE scene — fixedRefuses with
BAD_REQUESTnaminggetPractice, mirroring whatinsertContentalready does on the write side.
4. Draft SP reads 0 — fixed
Draft and published now sum the same way through a shared
sumPracticeSolutionSp.5. Tool descriptions and schema — fixed, except
correctAnswercreateScenesaysinsertContentfor DOCUMENT,writePracticefor PRACTICE.publishCourselists the refusals an agent actually hits, including theunfinished-practice one, in the words it will get back.
explanationtakes.default(null)— omit it and you get no explanation.validatePracticestill returnscorrectAnswer. It isreachable only with an authoring token, and such a caller can already read
the whole solution from
getPractice; hiding it here would remove the fieldfeedback without removing the exposure.
6. Polish — fixed
Publish failures now carry
details.code+details.paramsand aretranslated client-side (
translatePublishFailure,{{param}}interpolation);every code has en and de copy. PRACTICE scenes get their own icon and label in
the scene list. The stale "Geprüft" note is gone with the stamp it described —
readiness is recomputed live.
7. Zero-to-published over MCP — fixed by converging the gate
One pure function replaces the stamp, the content hash and the browser sweep:
It reads the app source and reports what is missing: no
__sciblySelfTestassignment, no
scibly.submit(work), noscibly.onGraded(), or a solutionfield the html never mentions. Publish, MCP
validatePracticeand theeditor's readiness line all call it, so publish refuses with the same
sentence
validatePracticereports, and a 12-scene practice course needs zeroeditor clicks.
practiceValidatedis dropped(
20260904140000_drop_practice_validated_stamp).Known ceiling, carried as a
ponytail:comment: these are string checks, not aparser — an app with all four markers that still throws at runtime gets
through. Upgrade path is a headless Chromium run behind the same function.
Tests
pnpm check(32 tasks),pnpm test:unit(all packages) andpnpm test:int(6 files, 29 tests) are green. New:
check-practice-scene.test.ts,publish-failure.test.ts, publish-validationSOL9b/SOL11b/SOL12b,review-pathRP4, and MCP integration test IT3 — publish refusing an app whoseself-test hook was renamed, asserting on the sentence the agent sees.
Integration tests now provision their own throwaway Postgres (pgvector, bound
to loopback) and remove it on every exit path including Ctrl-C and failure;
INT_DB=still points them at a local cluster you already have, with thelocalhost guard intact.
pnpm test:allincludes them.Second commit
chore: working-tree drift unrelated to #41is deslop/CSS/i18n churn that wasalready in the tree when this work started, plus a whitespace-only reformat of
the vendored prism
package.json. Split out so the fix commit reads clean —drop it if the branch should carry only #41.
🤖 Generated with Claude Code