content: bump content.lock — C1 + EVM elective + reflection prompts + flip wave - #892
Conversation
… flip wave Activates courses-academy @c5c625e0 (PRs #22/#23/#24/#25/#26/#27). Bundle 4 courses / 49 lessons -> 6 courses / 66 lessons: + C1 course-solana-for-web-devs (8 lessons, trackLevel 1, #25) + elective course-solana-for-evm-devs (9 lessons, trackId 0, #24) Flip wave (#27/#23): path-zero-to-deployed gains C1 in the FRONT slot, path-solana-core order 1 -> 8 (order-1 collision), achievement course-completer retargeted C2 -> C1 (closes the #673 placeholder), full-stack-solana description reworded. Reflection rewrites (#848 / courses-academy #26) touch 4 openEnded prompts across C4/C5. C4 code stand-ins fixed for inverted deposit account order (#22). Goldens regenerated from the bundle through the REAL projectors; e2e catalog fixture unchanged (C1/EVM have no deployment row, so the gate keeps them invisible).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @thomgabriel's task in 5m 1s —— View job Review: PR #892 — content.lock bump (C1 + EVM elective + reflections + flip wave)
BLOCKINGAdding C1 to
But the achievement engine reads path membership through a different, unfiltered path:
Net effect: This is distinct from — and not addressed by — the PR's own "Visibility" section, which only discusses catalog display and the (intentionally deferred) Suggested fix (not applied — flagging per review-only instructions): either (a) don't add C1 to Everything else checks out
Not run: This review is advisory — CI is the hard gate, and a human should confirm the path-completion interaction before merge given it touches live-user achievement state. |
… on #892) buildUserState() computed completedPathIds from getLearningPathsForAdmin()'s UNFILTERED path.courseIds while completedCourseIds is synced+active-only, so staging an unsynced course into an already-live path made that path's path-completed achievement permanently unsatisfiable — this wave adding C1 to path-zero-to-deployed would have retroactively broken achievement-full-stack- solana for learners who already finished C2-C5, and every future wave that adds a member to a live path re-armed the same trap. Filter path.courseIds through the same isSynced chokepoint the catalog and getAllLearningPaths use, before the .every(...) check. getLearningPathsForAdmin keeps returning raw membership (the admin panel needs it). A path whose synced membership is empty still does not count as completed — the length > 0 guard keeps .every([]) from being vacuously true. New regression suite path-completion-sync-gate.test.ts drives the REAL bundle membership and REAL queries through a controlled deployment set. Red-proofed at the previous head: cases 1 and 2 failed (expected false to be true / expected true to be false); case 3 (a synced-but-unfinished member still blocks) passed both before and after, as the control.
Gate bounce addressed — option (b), the durable fix (head
|
|
@claude review |
|
Claude finished @thomgabriel's task in 2m 14s —— View job Review: PR #892 follow-up — path-completion sync-gate fix (head
|
Activates everything staged in
solanabr/courses-academysince the last pin:9b1f03e6→c5c625e03b23f6ce527da884456f7b2d36c26bed.Counts
9b1f03e6)c5c625e0)explorer-reading,api-currency)6 courses = the 5-course ladder (C1→C2→C3→C4→C5) + 1 off-ladder elective.
Wave delta
Six upstream PRs land in this pin:
course-solana-for-web-devs(8 lessons,trackLevel 1, slots 0–7,next: 8). Completes the ladder at the bottom.course-solana-for-evm-devs(9 lessons,trackId 0, slots 0–8,next: 9). Off-ladder: member of no learning path, so itslearningPathprojectsnull.openEndedprompts across C4/C5 stop being URL-only:lesson-dsk-first-signed-deposit,lesson-dsk-publish-the-package,lesson-dsk-states-errors-and-readswidenmaxWords60 → 120 and append a comprehension question; C5'slesson-sap-submit-and-what-you-builtre-keys its blocksubmit→reflect, widens 200 → 250 and swaps the Earn-URL paste for a rail-comparison prompt.path-zero-to-deployedgains C1 in the front slot (order is now C1, C2, C3, C4, C5);achievement-course-completerretargetscourse-rust-for-program-devs→course-solana-for-web-devs, closing the Author C1 — solana-for-web-devs (8 lessons) — blocked on #599 (reference vault) #673 "pending C1" placeholder.path-solana-core(draft)order1 → 8 so it stops colliding with the live path;achievement-full-stack-solanadescription reworded to name the Zero to Deployed path.lesson-dsk-idl-to-typed-client,lesson-dsk-wrap-the-generated-clientand the code block oflesson-dsk-first-signed-deposit.Doc-level classification of the recompiled bundle: 2 courses added, 17 lessons added, 6 lessons edited, 0 removed, no id churn, no slot remapping on any existing course (both new courses get fresh
slots.jsonentries with emptyretired).Goldens methodology
Regenerated through the real projectors (
src/lib/content/project.ts), never hand-written, per the house pattern:courses.json,lessons.json— existing entries re-projected in place, existing order preserved, new docs appended.paths.json— rebuilt wholesale from bundle membership (projectLearningPath(bundlePath, resolvedMembers, deps)), so zero-to-deployed is now C1-first and solana-core carriesorder: 8.course-summaries.json—coursesByIds/recommended/lessonCountsrebuilt for all 6 courses (alphabetical by_id);learningPathresolved from real path membership, hencenullfor the EVM elective.quests-raw.json— derivedchallengeLessonIds/moduleLessonMaprecomputed viaprojectQuestData; raw quest docs untouched.course-by-slug.json— unchanged; its subject (course-building-first-program) is not in this wave.achievements-raw.json— hand-patched for exactly two fields (course-completer.award.course,full-stack-solana.description) in both theallanddeployedarrays; the rest stays the frozen prod-Sanity capture.Before rewriting anything, every pre-existing golden doc was re-projected against the new bundle to find unexplained drift. The only docs that diverged were the 6 intentionally-edited lessons above — no silent absorption. The wave delta is documented in the
project.golden.test.tsheader, as with every prior wave.E2E impact
e2e/harness/fixtures.mjsmodels the active catalog. C1 and the EVM elective have nopublic_onchain_deploymentsrow, so they land in the existing "no row → ABSENT" bucket and the fixture needs no new entries. Verified, not asserted: the full Playwright suite was run against a production build —catalog.spec.ts,learn-loop.spec.tsando4-journey.spec.tsall pass unchanged (unsubscribe.spec.tsstays skipped pending #769). The only edit to the file is a stale comment that still described the bundle as "the live 4-course ladder".Verification
pnpm compile-content→Emitted 8 modules, counts as tabled abovepnpm typecheck→ 6/6 tasks greenpnpm --filter web test→ 244 files / 2217 tests passedpnpm lint→ green (pre-existingimport/orderwarnings only)pnpm --filter web e2e→ 3 passed, 2 skippedprettier --checkon every touched file → cleanVisibility
C1 and the EVM elective stay INVISIBLE to learners on merge. The catalog gate (
lib/content/deployments.ts, oneisSyncedchokepoint) shows a course only when it has apublic_onchain_deploymentsrow that isstatus === "synced"andis_active !== false. Neither course has been created on-chain, so neither has a row, and the gate is fail-closed. This bump only stages them; they surface when the owner runs the on-chain course create. The flip-wave edits that touch already-live content (path ordering, thecourse-completerretarget, the reflection prompts) DO take effect on deploy.Do not merge — opened for review.
Surprises
lesson-dsk-first-signed-deposit.achievements-rawneeded a second patch. The brief scoped it to thecourse-completerretarget only, but feat: Complete LMS Frontend — 10 Pages, Wallet Auth, Gamification, i18n, Code Editor #23 also rewordedfull-stack-solana's description, whichprojectAchievementcompares — leaving it would have failed the golden. Patched and documented._keychanged (submit→reflectonlesson-sap-submit-and-what-you-built). Grepped the app for hardcoded block keys: none — blocks are addressed structurally, so this is inert. Worth knowing if any learner-progress record ever keys on block_key.explorer-readingandapi-currencyboth come from C1.🤖 Generated with Claude Code