One Course Contract, Four Ways to Learn

OpenMAIC's staged generator can produce several kinds of classroom page, but those pages cannot remain isolated outputs. This chapter examines the contract that lets a course move from generation to rendering, editing, storage, and playback while keeping the meanings of a slide, quiz, interactive widget, and project distinct. The practical result is a way to reason about course validity and future change: a common structure connects the parts, while typed boundaries prevent one kind of page from being mistaken for another.

A course contract with a type at every junction

The central unit is a Stage: the course or classroom as a whole. A stage contains Scene objects, which are ordered page-like units. Each scene has an explicit type and a matching content payload. A slide scene carries slide content; a quiz scene carries quiz content; an interactive scene carries interactive content; and a PBL scene carries a project structure. The declared type and the payload are bound together instead of being two independent strings that can drift apart.

That binding makes an otherwise ordinary JSON document more meaningful. In an opaque blob, a field might say that a page is a quiz while another field contains a slide-shaped object. The failure may not appear until a renderer, editor, or playback path branches on the first field and reads the second. OpenMAIC's contract treats the agreement as a structural invariant. Consumers can ask what kind of scene they received and then rely on the corresponding content shape, rather than repeating defensive guesses throughout the application.

The contract is also generic enough to grow. The DSL owns the universal lesson skeleton and the standard content kinds, while an application can widen the content union for its own scene data. That is an important balance. A platform-wide contract cannot know every future widget payload or project runtime detail, but it can define the stable seam—scene identity, order, type binding, actions, and document envelopes—through which those extensions travel.

classDiagram class Stage class Scene class SlideContent class QuizContent class InteractiveContent class PBLContent class Action class Validator class Normalizer class Migration class Renderer class Playback Stage "1" --> "*" Scene : contains Scene --> SlideContent : type slide Scene --> QuizContent : type quiz Scene --> InteractiveContent : type interactive Scene --> PBLContent : type pbl Scene --> Action : carries Validator ..> Scene : validates Normalizer ..> Scene : repairs shape Migration ..> Scene : evolves document Renderer ..> Scene : renders Playback ..> Action : executes

The DSL package is intentionally pure: it owns types, schemas, guards, validators, normalizers, and migration helpers without depending on React, a presentation library, or a charting engine. That lack of runtime baggage is architectural, not cosmetic. The renderer, importer, editor, storage layer, and generation package can all agree on the course shape without dragging one another into a circular dependency. A document can be produced in one environment and consumed in another as long as both sides understand the contract.

The contract has several kinds of enforcement. JSON Schema provides a language-neutral description for consumers that are not TypeScript applications. In-process validators offer a dependency-free structural gate for generators, importers, and runtime code. They check object shape, required fields, known discriminants, and the relationship between a scene's type and its content. A validation result can collect multiple errors rather than stopping at the first missing field, which makes a malformed generated document easier to diagnose.

A normalizer has a different responsibility. It repairs producer-independent omissions and derives values that follow from a valid element's shape. For example, it can supply required element defaults or derive geometry for certain slide elements. It does not silently turn a field with the wrong type into something plausible. A present-but-malformed value fails loudly; a producer can then drop or repair the affected element at a higher level. This division prevents “normalization” from becoming a vague excuse to accept anything the model emits.

The distinction becomes useful at the boundary between model output and stored content. A generator may reasonably treat a missing optional field as an omission and let the normalizer supply a default. It should not treat a string where a coordinate array is required as close enough, because downstream geometry code may interpret it differently. In OpenMAIC's generation path, malformed elements can be stripped of null-like omissions, normalized, and dropped when they still cannot be repaired. The DSL remains strict; the producer decides how much local damage it can safely absorb before handing the scene to other consumers.

Migration is different again. A validator asks whether a value fits the current contract. A normalizer brings a producer's value to a valid structural baseline. A migration changes the serialized shape from one documented version to the next. OpenMAIC keeps document and runtime version lines separate: DSL_VERSION describes the persisted course contract, while RUNTIME_DSL_VERSION describes learner/session data. Their distinct envelopes prevent a document migration from being accidentally applied to a runtime session.

The migration runner is designed for continuity rather than silent downgrading. It walks a contiguous ladder of pure transformations, returns current or newer documents without pretending to rewrite them backward, and fails loudly when there is no path or the version envelope is ambiguous. That behavior matters for a course that may outlive a single release. A new application should not quietly reinterpret an old document as current, and it should not mutate a future document into an older shape just to make the read appear successful.

None of these mechanisms evaluates the truth of a lesson. A structurally valid slide can contain a false explanation. A valid interactive document can teach the wrong relationship. A migration can preserve bytes without preserving pedagogical intent. The contract makes the data legible and portable; it does not replace review of what the data says.

Different experiences, shared verbs

A shared contract would be unhelpful if it erased the differences among the page types. OpenMAIC's four scene kinds represent different ways of organizing learner attention and activity, even though the platform stores them under one course structure.

A slide is primarily a visual composition. It gives the classroom a canvas with text, images, shapes, charts, formulas, or other elements that can be highlighted during narration. Its strength is controlled presentation: the author or generator can arrange information spatially, and playback can direct attention to a particular element. A slide does not, by itself, prove that the learner understood the material. It is a surface on which explanation and focus can be choreographed.

A quiz changes the relationship between the classroom and the learner. Instead of only receiving an explanation, the learner answers a question. The persisted content can distinguish single choice, multiple choice, and short-answer forms, along with options, answer information, analysis, and grading guidance where available. The contract supports the data needed for a quiz experience; it does not promise that the question is well designed or that an answer key is correct. That boundary is important because an automatically graded mistake can be more misleading than an absent quiz.

Interactive content moves more of the experience into a self-contained web surface. The contract can carry complete HTML or a URL fallback, together with a widget type and optional configuration. The documented widget families cover simulations, diagrams, code, games, 3D visualizations, and a gated procedural-skill path. These categories are not just visual themes. A simulation exposes variables or changing states; a diagram organizes relations; a code page invites the learner to write or run something; a game frames practice as a challenge; a 3D visualization makes spatial structure explorable.

The platform still needs a common way to talk to those different widgets. When an interactive page is generated, OpenMAIC can inspect the actual HTML and derive an inventory of identifiers, stable data attributes, and meaningful classes. Later actions can highlight, annotate, reveal, or change state using the page's observed surface. This does not make arbitrary HTML safe or scientifically correct. It does make the link between an action and its target more concrete than asking a model to guess a selector from a description.

PBL content represents a project rather than a single explanatory surface. Its persisted project shape can include roles, milestones, microtasks, scenario characters, learner-facing documents, discussion threads, submissions, evaluations, and engagement events. The project therefore has a lifecycle: participants have responsibilities, work is divided into milestones, and progress can be represented separately from the initial design. Treating PBL as a long quiz or a slide deck would hide the state that makes a project a project.

The common Action union connects these experiences without making them identical. Speech actions carry narration. Spotlight and laser actions direct visual attention on slide elements and can fire without blocking the next operation. Whiteboard actions open a board, draw text or shapes, show formulas or tables, edit code, and close the board. Discussion actions create a point at which a classroom agent can participate. Widget actions highlight a target, set state, add an annotation, or reveal content inside an interactive page.

This vocabulary belongs beside the lesson data because playback is part of the meaning of an OpenMAIC scene. A slide with an element and a slide with an element plus a narration-and-spotlight sequence are not the same classroom experience. The content describes what can be seen or manipulated; the actions describe how the learner is guided through it. Keeping both in the contract allows online generation and offline playback to consume the same verbs, while each renderer decides how to realize them.

The action categories also make timing explicit. Some actions are fire-and-forget visual effects. Others are synchronous and must finish before the next action begins. Speech may wait for audio, a whiteboard draw may wait for its render, and a widget state change may need to reach the interactive surface before the lesson continues. If every action were treated as an undifferentiated event, the playback engine would have to infer timing from arbitrary payloads. The contract makes the sequencing rule visible.

Imagine two pages that both contain a definition. On a slide, the intended sequence might be to speak the definition, spotlight a phrase, and then draw a supporting formula on the whiteboard. On an interactive page, the intended sequence might be to highlight a control, set an initial simulation state, and reveal an explanation after the learner changes a variable. The pages need different targets and different consumers, but the classroom runtime can still treat both as ordered actions with explicit completion behavior. That is the value of a shared verb set: it standardizes the control relationship without standardizing the learning surface.

That visibility helps explain why the contract is more than a type catalogue. It assigns responsibility. The scene owns its content kind and its ordered actions. The DSL owns structural validity and version movement. The renderer owns presentation. The playback engine owns timing and interruption. The application owns provider-specific behavior and richer widget payloads. When those boundaries hold, a generated page can move through the system without every component knowing how every other component works.

Portability without flattening meaning

Portability has two dimensions here. The first is technical: a course should survive movement between the generator, editor, renderer, storage backend, and export path. The second is semantic: moving a course should not silently turn an interactive exercise into a slide or a PBL project into an inert description. The discriminated scene contract protects the second dimension while the schemas, validators, and migrations support the first.

This is also where the limitations become visible. A dependency-free DSL does not remove the dependencies of the complete application. An interactive page may rely on browser behavior or external resources. A renderer may need optional peers for charts or code. A PBL runtime may interpret fields that the universal contract deliberately leaves app-owned. A strict consumer using an older schema may reject additive fields even when the core code treats them as compatible. The contract creates a disciplined boundary, not a world in which every consumer is automatically synchronized.

The same boundary helps an extension avoid a common mistake: adding a new experience by smuggling its entire runtime into a generic field. An application can specialize widget configuration or widen the scene union, but it still benefits from keeping identity, type discrimination, actions, validation, and migration explicit. If a new content kind needs a new action, that action must have a defined timing and consumer. If it needs learner state, that state should not be confused with the authoring document. A common contract makes new features answer these questions early, before they become hidden assumptions in an exporter or playback path.

The most defensible claim is therefore modest but useful: OpenMAIC gives different learning experiences a common, versioned, executable home. It does not make them pedagogically equivalent, and it does not guarantee that model-generated content deserves trust. The next question is what happens when the shared actions leave the document and enter a live classroom—when speech, whiteboard work, widget guidance, and discussion must be routed, timed, paused, and resumed around a learner's intervention.

References