Skip to content

feat: infinite practice generator + Verify Solution (roadmap #5, #8)#80

Merged
ABCrimson merged 6 commits into
mainfrom
feat/wave1-practice-verify
Jul 11, 2026
Merged

feat: infinite practice generator + Verify Solution (roadmap #5, #8)#80
ABCrimson merged 6 commits into
mainfrom
feat/wave1-practice-verify

Conversation

@ABCrimson

Copy link
Copy Markdown
Owner

Summary

  • math-engine: seed-deterministic problem generation over 22/24 templates with CAS-graded canonical answers; checkEquivalence (symbolic simplify(student − canonical) == 0 with seeded numeric-probing fallback)
  • web: Infinite Drill mode on /practice (deep-linkable ?mode=drill&template=&seed=), Check my work panel in the solver; 32 i18n keys × 8 locales

Adversarial-review fixes included

  • equation-mode Check-my-work canonical is the solved root, not the LHS−RHS zero form (correct answers were previously graded "not equivalent")
  • "+ C" strip now gated on indefinite-integral problems only; floor/ceil/round excluded from numeric-agreement verdicts; duplicate-padded root lists rejected
  • drill "End & save" no longer stuck disabled (sessionId in state, not a ref); template switches flush progress to the topic actually practiced; probability template grades its own displayed 3-decimal answer; ungradeable templates removed from the drill picker

Verification

math-engine 2738 tests, web 284 tests — green; typecheck + biome clean. Wave-1 roadmap items #5 and #8.

🤖 Generated with Claude Code

ABCrimson and others added 5 commits July 10, 2026 19:35
…ded answers

- New string-seeded RNG (xmur3 + mulberry32); seeds minted via
  crypto.getRandomValues — no Math.random anywhere in generation
- templateEngine.generate(id, seed) is now pure and seed-required:
  the RNG is a local stream threaded through parameter generation
  (the mutable Math.random field and old LCG are gone)
- ProblemInstance carries its seed (URL round-tripping) and an optional
  machine-gradable answer computed at generate() time from a new
  per-template canonical() spec: exact roots via the closed-form
  solver, expressions for CAS-equivalence grading, numeric values with
  per-answer tolerance, and labeled assignments for systems
- canonical() added to 22 of 24 templates (prime-factorization stays
  textual; linear-inequality answers carry an operator the equation
  solver cannot support, so it deliberately has no graded answer)
- Fix latent system-linear-2x2 bug: the det != 0 constraint sat on c2,
  which the determinant does not involve — retries could never repair a
  singular draw; moved to b2 where at most one value in range is bad
- generateBatch(id, count, baseSeed?) derives reproducible per-item
  seeds as `${baseSeed}:${i}`
- './problems/templates' and './equivalence' subpath exports
- Tests: seeded determinism across all 24 templates, 100-seed
  constraint sweeps, and back-substitution of every graded root into
  the ORIGINAL equation (|LHS-RHS| < 1e-6)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…bing

checkEquivalence(student, canonical): parse both, prove
simplify(student - canonical) == 0 via symbolic/simplify + CAS; fall
back to deterministic seeded numeric probing (24 points in [-5,5] plus
positive-domain points for sqrt/log; singularities skipped; >=8 valid
samples required; mixed abs/rel tolerance 1e-9). Conservative by
construction: any mismatch rejects, insufficient samples reports
'inconclusive' — it never claims equivalence it cannot support.

checkGradedAnswer grades free-form input against GradedAnswer kinds:
multi-solution lists ('x = 2 or x = 3', '2; 3'), numeric values
(expression input like 1/2 or 16*pi accepted), labeled assignments
('x = 2, y = 3' any order, swapped values rejected), and canonical
expressions with '+ C' and assignment-prefix stripping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- DrillMode component: seed-deterministic problems from the template
  engine, graded via checkGradedAnswer (equivalent forms accepted),
  commonMistakes explanations on wrong answers, progressive hints,
  per-problem timer (useEffectEvent — no legacy ref hacks), running
  tally chips, Copy-link sharing, template picker grouped by category
- Practice page: ?mode=drill&template=…&seed=… deep links via
  useSearchParams (Suspense-wrapped) with native
  window.history.replaceState/pushState shallow URL updates; a missing
  seed is minted (crypto.getRandomValues) straight into the URL so
  every drill link reproduces its exact problem; Infinite Drill entry
  card in the config UI
- Session persistence: startPracticeSession on first checked answer,
  completePracticeSession on End drill with new optional correctCount +
  topicSlug fields feeding TopicProgress (generated problems write NO
  per-attempt rows — Attempt.problemId is a required FK to Problem);
  graceful sign-in messaging when unauthenticated
- CheckWorkPanel ('Check my work'): verifies any equivalent form against
  a canonical expression, reporting verified-symbolically/numerically,
  parse-error and inconclusive states; embedded in InteractiveSolver
  (gated on isValidExpression) and SolverPanel (new finalRaw on both
  compute paths; equations use the zero-form LHS-RHS so factorings
  verify)
- submitAnswer grading upgraded in place (contract unchanged): exact
  match first, then conservative CAS equivalence in try/catch
- i18n: 21 practice.drill.* + 11 checkWork.* keys fully translated in
  en/ru/es/uk/de/fr/ja/zh (identical structure, ICU plurals per locale)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DrillMode: deterministic statement for fixed template+seed, equivalent
expression form '(c-b)/a' graded correct, sign-mistake answer graded
incorrect with the commonMistakes explanation surfaced, Generate-another
mints a fresh 8-char crypto seed, progressive hint reveal with count.
CheckWorkPanel: equivalent (symbolic and numeric captions), wrong form,
parse-error, and verdict-reset-on-edit states.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Check-my-work equation canonical is now the solved root, not the
  LHS-RHS zero form (correct answers were graded "not equivalent");
  panel offered only for single-real-root equations
- "+ C" strip is opt-in (indefinite-integral problems only) instead of
  running on every problem type in grading and check-work paths
- numeric probing refuses to claim equivalence when floor/ceil/round is
  present — sample agreement on step functions proves nothing
- duplicate-padded root lists no longer pass distinct-root problems
- drill "End & save" reads sessionId from state, not a ref (button was
  stuck disabled); saved status tracked per segment
- switching drill templates flushes the tally to the topic actually
  practiced instead of crediting everything to the final selection
- probability-basic tolerance 1e-3 so its own displayed 3-decimal
  answer grades correct (matches geometry templates)
- ungradeable templates (no canonical) excluded from the drill picker

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nextcalc-pro Ready Ready Preview, Comment Jul 11, 2026 5:57pm

…e-verify

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ABCrimson
ABCrimson merged commit 8975e18 into main Jul 11, 2026
7 checks passed
@ABCrimson
ABCrimson deleted the feat/wave1-practice-verify branch July 11, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant