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.
Decision
Section titled “Decision”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_versionrows 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.
Considered options
Section titled “Considered options”- 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.
Consequences
Section titled “Consequences”qti3andcommon-cartridgeare 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 domainqti-package-import/common-cartridge-importauthoring 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.