Authoring guide

Build course apps that can survive campus review.

Lantern authoring is for learning engineers, instructional technologists, faculty developers, and campus developers who can build useful course tools but do not want every tool to become a new LMS integration.

Mental model

A Lantern app is a small package, not a standalone platform.

Authors build the learner experience. Lantern owns launch, identity, storage, grading, review records, and the LMS connection. That split is what makes the authoring path acceptable for institutional review.

The package is intentionally plain: HTML, CSS, JavaScript, content, preview fixtures, and a manifest. A reviewer should be able to open it, understand what it asks learners to do, and see exactly which runtime capabilities it requests.

Baseline package

app/
  manifest.json
  dist/
    index.html
    app.js
    app.css
  content/
    activity.json
  preview/
    fixtures.json
    tests.json

Browser autograder adds

grading/
  specs/
    checks.spec.js
evidence/
  example-output.json

Choose a starter

Start with the smallest shape that fits the course need.

Simple activity

Use this for flashcards, practice tools, short simulations, checks for understanding, and course-specific interactions that do not need reviewed browser grading specs.

deno task app:new /tmp/my-lantern-app \
  --starter=simple-activity \
  --app-id=my-app \
  --title="My App"

Browser autograder

Use this when the app needs reviewed HTML, CSS, or JavaScript checks, structured evidence, Jasmine-style specs, or a grading routine that should stay inside the Lantern review boundary.

deno task app:new /tmp/my-autograder \
  --starter=browser-autograder \
  --app-id=my-autograder \
  --title="My Autograder"

List the shipped starters with deno task app:new --list-starters.

Local loop

Use one path from scaffold to review.

  1. Scaffold one package. Start from a curated starter. Do not copy internal admin routes or build a second runtime.
  2. Edit the visible learning files. Most work happens in content/activity.json, dist/index.html, dist/app.js, dist/app.css, and the preview files.
  3. Run validation and preview checks. The local preview runtime injects window.GatewayApp, serves reviewed content, records attempt events, and accepts evidence artifacts.
  4. Open a browser only when it helps. Preview assertions are faster for repeated checks. The live preview is for human inspection.
deno task app:dev /tmp/my-lantern-app
deno task app:validate /tmp/my-lantern-app
deno task app:test-preview /tmp/my-lantern-app
deno task app:preview /tmp/my-lantern-app

app:dev is the everyday authoring loop. It keeps one preview URL open, reruns validation and preview assertions after saves, and leaves the diagnostic in view when a save breaks the package.

Runtime contract

Apps call the gateway. They do not call the LMS.

A package talks to Lantern through window.GatewayApp. The manifest must request the matching capability for every method the app uses. If the app does not need a capability, leave it out.

getLaunchContext() Read the scoped course, assignment, activity, role, and attempt context.
getActivityContent() Load reviewed content from content/activity.json.
readLocalState() and writeLocalState(value) Resume and save the current learner's progress through Lantern-owned storage.
emitAttemptEvent(event) Record answer, progress, and completion events for reports.
submitEvidenceArtifact(input) Return structured evidence through the governed evidence path.
submitScoreProposal(input) and finalizeAttempt(input) Send scoring and completion signals without writing grades directly to the LMS.

Keep out of package code

  • Backend code, Worker code, Durable Objects, D1, R2, KV, or service bindings.
  • Direct LMS, SCORM, xAPI, cmi5, LRS, or grade-passback calls.
  • Arbitrary outbound HTTP, external scripts, remote stylesheets, or CDN assets.
  • Standalone fallback runtime paths that bypass Lantern.

AI-assisted authoring

Generated apps follow the same path as human-authored apps.

App Writer works because the target is narrow. A model authors inside a prepared package workspace, uses the same SDK surface, and has to pass the same validation and preview checks before a version can enter review.

Ask for one starter

The model should choose simple-activity or browser-autograder. It should not invent a new runtime shape because the prompt sounds unusual.

Keep lesson data in content

Put course-specific text, questions, answers, rubrics, and examples in reviewed content or grader files. Keep the browser code small.

Repair failures honestly

If validation or preview fails, fix the app. Do not remove tests or relax the manifest to make the failure disappear.

Review and import

The package directory is the artifact you review.

When the app is ready, import the same validated package directory into Lantern. Lantern stores an immutable snapshot, signs the runtime contract for that version, and adds it to admin inventory for approval and LMS setup.

deno task local:init
deno task local:bootstrap
deno task local:start

Then open /admin/packages/import on the local URL printed by Wrangler and choose the package directory you just validated.

Reviewers should be able to answer

  • What does the app ask the learner to do?
  • What capabilities does this version request?
  • What state, events, score proposals, or evidence does it send?
  • Do preview assertions prove the important behavior?
  • Does anything require a separate IT or security review?