Skip to content

refactor: introduce an LMS provider seam - #294

Open
DA-RAE wants to merge 1 commit into
heznpc:mainfrom
DA-RAE:refactor/lms-provider-seam
Open

refactor: introduce an LMS provider seam#294
DA-RAE wants to merge 1 commit into
heznpc:mainfrom
DA-RAE:refactor/lms-provider-seam

Conversation

@DA-RAE

@DA-RAE DA-RAE commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Introduces a narrow LMS provider seam so that adding another LMS no longer requires copying core translation behavior or scattering LMS-specific conditions across content modules.

  • Adds a small registry-backed LMS provider contract, with Skilljar as the first provider.
  • Keeps the existing Claude tutorial surface working through a focused compatibility provider.
  • Moves page-kind, content-root, metadata, lesson identity, translation target, quiz, and UI-anchor discovery behind a provider page context.
  • Preserves core-owned SPA navigation while re-probing provider context on every route change.
  • Keeps certification detection as a pre-initialization restricted-page probe, plus the existing core pattern safety floor.

Motivation

Skilljar-specific selectors and page assumptions were consumed directly by the translation pipeline and by several learning tools. Adding a second real LMS would therefore mean either duplicating core behavior or spreading LMS checks across modules. This change introduces a seam based only on variation points already demonstrated by currently supported surfaces, without speculating about future provider capabilities.

Implementation notes

Providers implement exactly three required methods: matches, probeRestricted, and getPageContext.

The runtime performs a two-phase probe -> describe flow. Restricted certification routes stop after the probe — before metadata discovery, translator/storage initialization, or UI injection. CERT_DISABLE_PATTERNS remains in core as a non-bypassable safety floor.

Core continues to own popstate, hashchange, and History API wrapping. A route change only re-resolves provider context; providers never install navigation listeners.

The Skilljar provider owns its LMS selectors and exposes semantic page context to the translation pipeline, quiz filtering, header controls, reading aid, and PDF export. Lesson keys omit query strings and fragments. No existing URL-keyed user data is migrated by this PR.

tests/lms-provider.test.js registers a fixture LMS to assert that a new provider can be added without touching core translation code, and that a restricted fixture halts at the probe phase.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🌍 Translation/i18n
  • 📝 Documentation
  • 🔧 Refactoring
  • 🎨 UI/Style

Testing

  • npm test passes
  • Tested on anthropic.skilljar.com
  • Extension loads without errors
  • No console errors in DevTools
  • Tested in target language (if i18n change) — n/a, no i18n change

Automated verification run on the rebased branch:

Check Result
npm test 724 passed / 38 suites
npx playwright test (exam-mode, spa-navigation, youtube-lifecycle, pdf-export, golden-translation) 12 passed
npx eslint src/ tests/ scripts/ pass
npm run typecheck pass
npm run format:check pass
npm run check:selectors pass (live catalog + course fetch)
npm run validate / npm run glossary pass
check-i18n-keys, check-locale-contamination, check-dict-coverage, check-dicts pass
check-bg-sync, check-permission-docs, build-plugin --check pass
npm run build:bundle / npm run build:firefox pass, remote-hosted-code check clean
git diff --check pass

I have not re-run manual in-browser QA against a live lesson since rebasing onto main, so those boxes are left unchecked deliberately. Suggested manual QA for review:

  • Open a normal Anthropic Skilljar lesson, switch language, and confirm translation plus header controls, reading aid, and PDF export.
  • Open a course quiz and confirm question text may translate while answer choices remain untouched.
  • Navigate between lessons via Skilljar SPA controls and confirm the new lesson translates without stale content.
  • Navigate to a recognized certification route and confirm no SkillBridge UI or translation initializes; navigate back and confirm normal surfaces rehydrate.
  • Open a Claude tutorial and confirm translation stays within the tutorial content roots.

QA Checklist (check items affected by your changes)

Expand checklist

Core Translation

  • Page translates after selecting language — covered by golden-translation.spec.js
  • Switch to English restores original — covered by golden-translation.spec.js
  • Protected terms stay in English — npm run glossary / npm run validate pass
  • Dictionary edits — n/a, no dictionary changes in this PR

Exam Mode

  • Answer choices NOT translated on quiz pages — covered by exam-mode.spec.js (4 tests)
  • AI Tutor integrity warning — unchanged by this PR

Cross-Browser (touching manifest)

  • Firefox: npm run build:firefox succeeds
  • Chrome / Edge: not manually re-verified after rebase

Risks

  • Page-kind and lesson-identity heuristics reflect current Skilljar / Claude tutorial markup only. A second LMS should add evidence-driven behavior rather than widening this contract speculatively.
  • Existing learning-state records remain URL-keyed. Consumers can adopt lessonIdentity later only with backward-compatible reads and an explicit storage-version strategy.
  • Provider context is re-resolved on SPA route changes, but navigation event ownership intentionally stays in core.

Related Issues

None yet. This is a standalone refactor with no behavior change intended.

@DA-RAE
DA-RAE requested a review from heznpc as a code owner August 19, 2026 06:27
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