Skip to content

Surface Layout and Subject Packs

Define how the platform configures what kinds of learning exist and how a learning activity is presented, while keeping the core model generic across all subjects (language, maths, geography, programming, …) with language learning as the initial specialization.

This document resolves the “learning profiles” question: how configurable the learner/teacher interface around an activity should be, and where that configuration lives relative to the existing standards-aligned models.

  • This is not a new authoring tool, no-code builder, or drag-and-drop editor. None of those are in scope for the alpha.
  • This does not introduce per-subject grading/validation infrastructure (e.g. executing and grading a programming assignment). That is explicitly out for 1+ year.
  • This does not add UI configuration to the standards models (QTI / competency framework / xAPI). See Layering discipline.

Two orthogonal concepts. They must not be conflated, and neither reuses the word “profile” (already taken by personProfile, xAPI activity-profile / agent-profile, and QTI authoringProfile).

  • Subject packwhat frameworks, activity types, and presentation components exist for a subject. The “language pack” = CEFR/ELLP competency frameworks + language-oriented QTI item types (dictation, cloze, pronunciation) + presentation components (word card, IPA, flashcard) + relevant xAPI verbs. Most of a subject pack’s data foundation already exists (see Implementation anchors); the new part is the presentation component set.
  • Surface layouthow a learning activity and the controls/widgets around it (buttons, panels, hints, audio, progress) are arranged on screen, and who is allowed to author that arrangement. This is a new, thin presentation-config layer, deliberately separate from the standards models.

A subject pack (what) and a surface layout (how) vary independently: a hard-coded language pack can have a configurable surface, or vice versa. Treating them as one concept (“a profile”) couples decisions that should move at different speeds and pollutes the standards layers with presentation concerns.

Surface layout: provider-authored now, engine designed to widen later

Section titled “Surface layout: provider-authored now, engine designed to widen later”

Configurability spectrum:

Level Who authors Status
A Hard-coded in React rejected — every variation is a deploy
B Provider (us), declarative presets chosen for alpha
C Institution-assignable + guardrailed overrides future
D Teacher / institution builder future
E Learner self-composition likely never (see a11y guardrail)

Governing principle: separate the rendering engine from the authoring authority. Who may author a surface layout is just a row owner + a permission — never a different engine. Widening B → C → D later is cheap (add ownership + permissions); narrowing is expensive. So start conservative.

No authoring UI of any kind. The alpha is three pieces:

  1. A versioned surface-layout schema (the declarative document format).
  2. A generic renderer that lays out an activity plus its surrounding widgets/buttons from a layout document.
  3. Trivial ingestion — a developer hand-authors the document (JSON/XML) and loads it via the simplest available path: paste into a textbox, a manually-inserted DB row, or an artifact on S3-compatible storage.

Admin editors, institution overrides, and builders are all deferred. There are many higher priorities; the alpha exists to prove the schema + renderer.

A hard rule. Each standard owns its concern; surface layout owns only presentation:

Concern Owner
Item / interaction QTI
Attainment / level competency framework
Activity tracking xAPI (LRS)
External tools LTI
Surface arrangement (buttons, panels, widgets) new surface-layout presentation layer

Never store UI/layout configuration inside the QTI, competency-framework, or xAPI models.

Accessibility and i18n are the guardrail, not an afterthought

Section titled “Accessibility and i18n are the guardrail, not an afterthought”

A curated widget set rendered by a single tested renderer is what preserves the accessibility and localization guarantees the project mandates. Freeform teacher/learner mashup (levels D/E) makes those guarantees effectively impossible. This is a primary reason the open-ended levels stay deferred — a correctness constraint, not merely a scope call.

  • Surface-layout documents are versioned; a renderer targets a known schema version.
  • Surface layout configuration lives only in the presentation layer; the standards models remain free of UI concerns.
  • The renderer composes from a curated widget set — arbitrary/unknown widgets are not rendered. This bounds the a11y/i18n surface.
  • Authoring authority is expressed as ownership + permission on a layout, so the engine is unchanged as authority widens from provider (B) to institution/teacher (C/D).
  • Subject-agnostic core first; a subject pack is an additive specialization, never a fork of the core.

The standards spine that subject packs and surface layouts build on already exists:

  • Tenancy / B2B2C boundary: organization (packages/db/src/schema/identity-context.ts).
  • Attainment engine (CEFR/ELLP as instances): packages/db/src/schema/competency-framework.ts — see Competency Framework Model.
  • Items / interactions (MCQ, cloze, dictation): packages/db/src/schema/qti-* and packages/domain/src/qti.ts.
  • Activity tracking: packages/db/src/schema/lrs.ts (xAPI) — see Standards and xAPI/cmi5 event model.
  • Learning structure (container / offering / unit / membership): packages/db/src/schema/learning-structure.ts.
  • Presentation components (the new subject-pack surface): packages/ui (shared Mantine v9 theme + domain components such as level badge, word card, progress, lesson MCQ renderer).

When the surface-layout schema and renderer are built, they belong in shared frontend packages (packages/ui for the renderer/widgets, packages/domain for the schema/validation contract), consumed by the apps — never redefined per app.

All four open decisions closed 2026-07-07 in ADR-0050, together with the structural design for Surface Experiences (bespoke, additive interfaces over an offering — the “mini-app” shape this layer was always building toward). In brief:

  • Schema format: JSON, validated solely by zod v4 in packages/domain; a JSON Schema artifact is derived for editor autocomplete, never hand-maintained.
  • Storage / ingestion: synced DB tables (surface_layout + experience tables), admin read-write via the sync mutation rail with fail-closed server validation; admin-console paste + live preview; drizzle-seed fixtures for dev.
  • Widget catalog v1: 15 curated types (9 activity-chrome, 5 navigation, viewport), governed by a per-delivery-mode fail-closed policy.
  • i18n: documents are text-free; widget copy routes through @emergent/i18n (LL.surface.*, English entries now) so later locales are translation-file work only.

Build sequencing lives in surface-experience-v1-build-plan.md; glossary terms in CONTEXT.md → “Surface layout and subject packs”.