Skip to content

Imported-standard boundary: ingest QTI and Common Cartridge, keep H5P/SCORM/cmi5 opaque

Status: accepted (Common Cartridge mechanism specified by ADR-0022; its “LTI links route to the LTI layer” line is superseded there — emergent is an LTI tool, not a consumer, so CC LTI links are quarantined until a consumer layer exists)

Before the QTI pivot, Emergent planned its own assessment model plus a family of opaque package imports — H5P, SCORM, cmi5, and qti3. We then made QTI 3.0.1 the canonical core (ADR-0001), but never removed the opaque qti3 path. The result is QTI modelled in two unconnected places (the authored Item Bank vs. an opaque qti3 course_material kind) and an import layer that contradicts itself: packages/domain treats a qti-package / common-cartridge import as a canonical QTI authoring document, while apps/api’s package importer and the schema treat the same formats as opaque runtime assets.

The import boundary is drawn by whether the format is our canonical model:

  • QTI (and the QTI resources inside a Common Cartridge) are Ingested into the Item Bank as assessment_item / assessment_item_version rows and delivered through the headless QTI runtime (ADR-0002) — gaining rendering, client scoring, item statistics, CAT, DIF, Renditions, and offline-complete delivery.
  • H5P, SCORM-1.2/2004, cmi5 remain External Packages: opaque bundles launched in an iframe and tracked via xAPI/cmi5/LRS. The platform never parses their interior.
  • Common Cartridge is a transport that is decomposed on import, never a leaf runtime kind: its QTI resources Ingest into the Item Bank; embedded packages become External Packages; LTI links route to the LTI layer.
  • Run imported QTI opaquely (the pre-pivot path): rejected. It discards the entire reason the headless core exists, and re-homes our own canonical model as a foreign runtime. Exact third-party render fidelity is not worth fragmenting delivery, scoring, and analytics across two stacks.
  • qti3 and common-cartridge are removed from the External Package kind/launch enums.
  • The package importer’s QTI branch is replaced by an Ingest pipeline that writes Item Versions (using @conform-ed/qti-xml + contracts); the SCORM/H5P/cmi5 branch is unchanged. The domain qti-package-import / common-cartridge-import authoring kinds become the Ingest contract.
  • QTI features the runtime cannot yet render are quarantined as an item state on Ingest, rather than spawning a parallel opaque runtime.