Skip to content

feat(scoring): heuristic difficulty tuner [STORY-018]#18

Merged
khoks merged 1 commit intomainfrom
story/018-heuristic-difficulty
Apr 26, 2026
Merged

feat(scoring): heuristic difficulty tuner [STORY-018]#18
khoks merged 1 commit intomainfrom
story/018-heuristic-difficulty

Conversation

@khoks
Copy link
Copy Markdown
Owner

@khoks khoks commented Apr 26, 2026

Summary

  • Per-episode adaptive engine: difficultySignal() (clamped overtime/hints/failures + correctness bonus → s ∈ [-1, +1]), nextDifficulty() (steps the catalog tier when |s| crosses the threshold), episodeSuccessScore() (penalty-floored success in [0, 1]), updateSkillScore() (EWMA on skill + asymptotic confidence growth) — all in packages/scoring/src/difficulty.ts.
  • All coefficients are configurable via DifficultyHeuristicConfigSchema (Zod) with sensible defaults exposed as DEFAULT_DIFFICULTY_HEURISTIC. No magic numbers in code paths.
  • Sibling to the existing policies/difficulty-policy.ts (EloEwmaPolicy picks tiers from a multi-episode catalog EWMA); the new helpers are the per-episode complement.
  • 20 unit tests covering 6+ representative scenarios — perfect / hint-heavy / repeated failures / overtime / under-time / no-progress + cap-at-easy / cap-at-expert + operator-injected stricter threshold.
  • Lives in packages/scoring, not the spec'd packages/profile (no profile package exists; scoring is its sibling and already houses the catalog-tier policy).

Story

Closes STORY-018.

Test plan

  • pnpm --filter @learnpro/scoring test → 40 tests pass (20 new + 20 existing)
  • pnpm format clean
  • pnpm lint clean
  • pnpm typecheck clean
  • Full repo pnpm test → 12 tasks, all green

🤖 Generated with Claude Code

Per-episode signal (`difficultySignal`) → next-difficulty step
(`nextDifficulty`) + per-concept skill score updater
(`updateSkillScore`) with EWMA + asymptotic confidence growth.
All coefficients live in a Zod-schema'd config with sensible
defaults — operators can pass partials per call. Sibling to
`policies/difficulty-policy.ts` (which picks tiers from the
multi-episode catalog EWMA); these new helpers handle the
finer-grained per-episode decision.

20 unit tests cover perfect/hint-heavy/repeated-failure/overtime/
under-time/no-progress + capped-at-extremes + operator-stricter-
threshold scenarios. Boundary cases use inclusive `>=`/`<=`
thresholds so the default `correctness_bonus = step_up_threshold`
boundary actually steps up.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@khoks khoks merged commit 56aa822 into main Apr 26, 2026
1 check passed
@khoks khoks deleted the story/018-heuristic-difficulty branch April 26, 2026 22:29
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