Skip to content

Browser entry and choice items with named misconceptions - #23

Merged
HarperZ9 merged 1 commit into
mainfrom
feat/browser-entry-20261003
Oct 3, 2026
Merged

HarperZ9 merged 1 commit into
mainfrom
feat/browser-entry-20261003

Conversation

@HarperZ9

@HarperZ9 HarperZ9 commented Oct 3, 2026

Copy link
Copy Markdown
Owner

What this adds

  • @harperz9/learn/browser (src/browser.mjs): practice, mastery, spaced review (Leitner and FSRS), arithmetic diagnosis and choice diagnosis, with no Node built-ins. A static page imports it as an ES module with no bundler. Receipts, the session store, the CLI and the MCP server stay Node-only.
  • Choice items (learn-choice/1, src/tutor/choice.mjs, docs/CHOICE-ITEMS.md): one keyed answer, a named misconception per wrong choice. diagnoseChoice() returns the leaf and note for a wrong choice and never the keyed answer. publicItem() is what a page shows before the attempt.
  • recordAttempt accepts an optional misconception leaf, and misconceptions() counts it.

The session functions moved from tutor.mjs to session.mjs (the ledger import pulled in node:crypto); tutor.mjs re-exports them, so existing imports are unchanged.

Why

The portfolio site's explainers add recall checks after each step group. They need Learn's scheduling and a diagnosis that works for conceptual questions, running in the page with no network.

Checks

  • tests/learn-browser-entry.test.mjs walks the entry's import graph: only relative imports, no process, Buffer or require. Two controls show the walk fails on a node:crypto import and on tutor.mjs itself.
  • tests/learn-choice.test.mjs: validation errors, the key never appearing in a wrong-choice diagnosis, no-attempt handling, and the count in misconceptions().
  • doctor gains tutor.choice_diagnosis_never_reveals_key.
  • Full suite: 418 pass, 0 fail, 1 skipped (local, Node 25).

Limits

The diagnosis reports the misconception an item's author attached to a choice. It infers nothing and cannot check that the note is true. No version bump; the CHANGELOG entry is under Unreleased.

🤖 Generated with Claude Code

src/browser.mjs exports practice, scheduling and diagnosis with no Node
built-ins, so a static page can import them with no bundler. The session
functions move from tutor.mjs into session.mjs, which tutor.mjs re-exports
unchanged. A test walks the entry's import graph and fails on any node: or
bare import, with controls that prove the walk can fail.

src/tutor/choice.mjs adds learn-choice/1 items: one keyed answer, a named
misconception per wrong choice. diagnoseChoice() tells a wrong attempt which
misconception it matches and never returns the key; doctor checks this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@HarperZ9
HarperZ9 merged commit 310b362 into main Oct 3, 2026
9 checks passed
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