A deterministic mental-math and estimation trainer for quant interview prep — arithmetic, percentages, probability & expected value, and market-making estimation.
The engineering, not the pitch, is the point of this project:
- Deterministic scoring. Every problem is generated and graded with exact
rational arithmetic (a
bigint-backedFractiontype incore/) — no floating-point drift, no fuzzy matching, and no AI grading anywhere in the loop. A correctness verdict is a pure function of(problem, input). - Elo-adaptive difficulty. Each topic tracks a skill rating updated with a standard Elo expected-score formula (K = 32) after every answer. The next problem's difficulty tier is chosen to target a ~70% expected success rate.
- Property-tested invariants.
fast-checkproves exactness, monotonic difficulty, determinism from a seed, Elo boundedness/direction, and that scoring never throws — see Test coverage below anddocs/architecture.md. - Seeded & reproducible. A
mulberry32PRNG seeded from your session seed means the same seed and settings always regenerate the exact same problem sequence.
Scope note (v1): no accounts, no backend, no AI — session history lives in
localStorageonly. This is a deliberate v1 decision, not an oversight; seedocs/architecture.mdfor what a v2 backend migration would look like.
edge-trainer/
├── core/ # pure TypeScript — zero React/Next/UI imports, enforced by lint
│ ├── fraction.ts # exact rational arithmetic (bigint-backed)
│ ├── prng.ts # mulberry32 seedable PRNG
│ ├── generator.ts # problem generation, 4 categories, difficulty tiers 1-10
│ ├── scoring.ts # deterministic correctness checking + tolerance rules
│ ├── adaptive.ts # Elo rating engine + next-difficulty selection
│ ├── stats.ts # session statistics (accuracy, percentiles, rating trend)
│ ├── types.ts # shared types
│ └── __tests__/ # unit + fast-check property tests
├── app/ # Next.js 14 App Router pages
├── components/ui/ # small hand-rolled shadcn-style primitives (no extra UI framework)
├── lib/ # browser-facing glue: localStorage schema, session runner
├── e2e/ # Playwright end-to-end specs
├── docs/ # architecture docs
└── .github/workflows/ci.yml
core/ never imports from react, next, or components//app//lib/ —
enforced by an ESLint no-restricted-imports rule, checked in CI. See
docs/architecture.md for the full data-flow diagram
and the exact Elo/scoring formulas.
Requires Node 20+ and pnpm (pinned via packageManager in
package.json; corepack enable will pick it up automatically).
pnpm install
pnpm dev # http://localhost:3000Other scripts:
pnpm typecheck # tsc --noEmit
pnpm lint # next lint
pnpm test # vitest — core/ unit + property tests
pnpm test:coverage
pnpm e2e # Playwright end-to-end tests (spins up `pnpm dev` itself)
pnpm build # production buildcore/ is the part of this project where correctness actually matters — the
UI is thin glue over it — so coverage is measured and reported for core/
specifically rather than the whole repo:
119 tests passing across 10 files (unit + fast-check property tests)
File | % Stmts | % Branch | % Funcs | % Lines
--------------|---------|----------|---------|--------
All files | 97.79 | 94.85 | 98.7 | 98.2
fraction.ts | 94.73 | 87.87 | 95 | 94.23
generator.ts | 99.31 | 100 | 100 | 99.2
adaptive.ts | 100 | 100 | 100 | 100
stats.ts | 100 | 100 | 100 | 100
types.ts | 100 | 100 | 100 | 100
prng.ts | 100 | 83.33 | 100 | 100
scoring.ts | 91.66 | 90.9 | 100 | 96.66
Run pnpm test:coverage to regenerate (HTML report at coverage/index.html).
The required invariants — exactness, monotonic difficulty, determinism,
Elo boundedness/direction, and "scoring never throws" — are listed with their
test files in docs/architecture.md.
Three Playwright E2E specs (e2e/) cover a fixed-count session end-to-end, a
speed round, and a dashboard read of real localStorage state after a
session — see pnpm e2e.
Deploy target is Vercel — this is a standard Next.js
14 App Router project with no server-side environment variables required
(everything is client-side/localStorage), so vercel / the Vercel Git
integration works with zero configuration.
.github/workflows/ci.yml defines a GitHub Actions pipeline that runs on
every push/PR: install, typecheck, lint, core/ unit + property tests with
coverage, then Playwright E2E. All of these pass locally (see
Test coverage above); the pipeline itself is configured but
not currently displayed via badge.
- No AI/LLM features of any kind — see
docs/architecture.md. - No accounts, auth, or backend database.
- No social features, leaderboards, or cross-user comparison.
- No mistake-review page yet (noted as future work).




