1EdTech QTI 3.0 customer specification

TimeBack QTI persistence surface

A standards-first website for 1EdTech reviewers, QTI implementers, and their coding agents. It explains what this surface promises, which database rows hold each promise, and which architecture decision owns every platform gap fill.

QTI persistence flow from package to attempt Package qti.content_package Resources qti.package_resource Artifacts qti.artifact Versions qti.artifact_version Sessions qti.delivery_session Attempts qti.attempt 1EdTech XML remains authoritative; SQL rows and JSON projections are traceable platform persistence views.
13 database tables all source-labeled
127 documented fields 42 pass-through / 85 gap fill
10 allowed-value sets with behavior and ITD trace
87 XSD-reachable processing elements 87 runtime-supported
311 in-profile XML examples full schema and round-trip evidence
2 canonical upstream URLs architecture plus data dictionary
Authentication

Authentication and request controls

Read this section before implementing any endpoint. It defines the token, tenant, idempotency, optimistic-concurrency, profile, service-role, and HTTPS rules shared across the surface.

ControlRequirementEndpointsTrace
Bearer JWT Every API operation requires Bearer authentication over HTTPS. The verifier checks issuer, expiry, signature, subject, and trusted key material before request handling. ingestContentPackage
getDeliveryJson
saveAuthoringJson
exportXml
startDeliverySession
submitAttempt
deleteCandidateRuntimeData
runConformance
Security Boundary, API Boundary
Tenant claim matching For /tenants/{tenantId}/... routes, the JWT tenant claim must equal the tenantId path value. Tenant identifiers are platform metadata, not QTI content. ingestContentPackage
getDeliveryJson
saveAuthoringJson
exportXml
startDeliverySession
submitAttempt
deleteCandidateRuntimeData
qti.tenant.tenant_id, Tenant Boundary, Security Boundary
Idempotency-Key Package ingest requires Idempotency-Key so retrying the same upload returns the same package outcome instead of creating duplicate package rows. ingestContentPackage qti.content_package.idempotency_key, Idempotency And Hashes
If-Match Saving authoring JSON requires If-Match. Missing preconditions fail with 428; stale or conflicting version state fails with 409. saveAuthoringJson qti.artifact.latest_version_id, qti.artifact_version.version_number, Artifact Versioning
X-QTI-Profile Package ingest accepts X-QTI-Profile as the implementation conformance profile label. When omitted, it defaults to qti-3.0 and is stored with the package import evidence. ingestContentPackage qti.content_package.qti_profile, Validation And Rejection Policy
Service-role learner deletion Candidate runtime-data deletion requires either a tenant-authorized service role or equivalent tenant-scoped administrative authorization. Bulk access to learner runtime state is not available to ordinary delivery clients. deleteCandidateRuntimeData qti.delivery_session.candidate_ref, qti.attempt.delivery_session_id, Candidate And Learner Data Privacy, Operational DDL Discipline
HTTPS only Plain HTTP requests fail before application handling. Tokens, package bytes, learner responses, and processing traces are only accepted over HTTPS. ingestContentPackage
getDeliveryJson
saveAuthoringJson
exportXml
startDeliverySession
submitAttempt
deleteCandidateRuntimeData
runConformance
Security Boundary
curl "$BASE/tenants/$TENANT/qti/artifact-versions/$VERSION/delivery-json" \
  -H "Authorization: Bearer $TOKEN"
Errors

HTTP statuses and error body

All endpoint cards link back to this table. Error responses use the Problem shape below unless the successful endpoint explicitly returns XML or an empty 204 body.

CodeNameTriggering conditions on this surface
200 OK getDeliveryJson returns a QtiDeliveryJsonEnvelope; exportXml returns canonical XML; submitAttempt returns AttemptResult.
201 Created saveAuthoringJson returns the new ArtifactVersion; startDeliverySession returns DeliverySession.
202 Accepted ingestContentPackage accepts package validation/import work; runConformance accepts conformance-run work.
204 No Content deleteCandidateRuntimeData deleted the candidate runtime rows in scope and returns no body.
400 Bad Request Malformed XML, bundled-XSD or Schematron validation failure, package path traversal, missing package references, privacy validation failure, invalid candidateRef format, authoring JSON that cannot round-trip, invalid response cardinality/base_type, unsupported runtime feature, or unregistered custom operator. See ingestContentPackage, saveAuthoringJson, startDeliverySession, submitAttempt, and deleteCandidateRuntimeData.
401 Unauthorized Missing, malformed, expired, untrusted, or unsigned Bearer JWT. Applies to every operation in ingestContentPackage through runConformance.
403 Forbidden Authenticated principal lacks access: tenant claim does not match tenantId, the route requires a service role, or the conformance runner is not authorized. See getDeliveryJson, saveAuthoringJson, deleteCandidateRuntimeData, and runConformance.
404 Not Found Tenant-scoped resource is absent or belongs to another tenant: artifact version, artifact, delivery session, or candidate runtime scope. See getDeliveryJson, saveAuthoringJson, exportXml, startDeliverySession, submitAttempt, and deleteCandidateRuntimeData.
409 Conflict Idempotency-Key reuse conflicts with the original ingest request, or If-Match/version state is stale during authoring save. See ingestContentPackage and saveAuthoringJson.
428 Precondition Required The authoring save omitted required If-Match precondition. See saveAuthoringJson.
500/502/503/504 Server or gateway error Unexpected server, gateway, dependency, or release-blocking conformance failure. For XML export, a canonical XML validation failure is release-blocking evidence rather than silent output. See exportXml and runConformance.

Problem response schema

FieldTypeRequiredDescriptionTrace
typestringRequiredStable problem category URI or identifier.API envelope; no persisted column.
titlestringRequiredShort human-readable summary of the problem.API envelope; no persisted column.
statusintegerRequiredHTTP status code repeated inside the error body.API envelope; no persisted column.
detailstringOptionalSpecific detail safe for the caller. Must not include direct learner PII, JWTs, request headers, IP addresses, user agents, or raw package bytes.Candidate And Learner Data Privacy, Security Boundary
invalidParamsarray<object>OptionalField-level validation details for malformed input, package closure failures, invalid QTI values, or privacy validation failures.Validation And Rejection Policy
Compliance map

What a reviewer can verify from this page

This is the quick route for a 1EdTech expert checking fidelity, traceability, runtime behavior, privacy boundaries, and release evidence.

Reviewer questionAnswerArchitecture traceData trace
Can I prove this is still QTI 3.0 rather than a renamed product model? Yes. XML is the authority, generated object graph is the typed hub, source_trace/spec_trace point back to the bundled 1EdTech source, and Alpha vocabulary is deliberately absent. Offline 1EdTech Source Bundle, Generated Object Model Hub, XML Authority And Canonical Hashes, Provenance Labels qti.artifact_version.source_xml
qti.artifact_version.spec_trace
qti.component.source_trace
Can I see which data is 1EdTech pass-through and which data is a platform gap fill? Yes. The data dictionary labels 42 fields as 1EdTech pass-through and 85 fields as platform gap fills, each with source basis and ITD links. Provenance Labels qti.package_resource.resource_type
qti.artifact_version.delivery_json
qti.attempt.processing_trace
Can a package be exported faithfully after ingest? Yes. Original bytes are kept in package_file, XML is preserved as source_xml and canonical_xml, component rows rehydrate the generated object graph, and xml_hash checks equivalence. XML Authority And Canonical Hashes, Lossless Relational Projection, Package Resource And File Ingest qti.package_file.content_bytes
qti.artifact_version.canonical_xml
qti.component.component_path
Can later edits change historical learner results? No. Delivery sessions snapshot an immutable artifact version and delivery JSON. Attempts persist response, template, outcome, and trace snapshots against that session. Delivery Session Snapshots, Attempt State And Processing Trace qti.delivery_session.delivery_json_snapshot
qti.attempt.response_state
qti.attempt.outcome_state
Can direct learner PII leak into QTI XML or logs? The contract forbids it. candidate_ref is pseudonymous; runtime state and processing traces must be redacted; platform-generated QTI XML cannot include direct learner PII, auth tokens, raw PNP records, or session-specific runtime state. Candidate And Learner Data Privacy, Security Boundary qti.delivery_session.candidate_ref
qti.delivery_session.session_state
qti.attempt.processing_trace
Can I reproduce the claimed conformance surface? Yes. The conformance tables persist profile, bundle hash, runner version, assertion key, artifact/spec references, status, and diagnostics. The current evidence covers full schema validation, round trips, and processing coverage. Conformance Evidence qti.conformance_run.profile
qti.conformance_run.bundle_hash
qti.conformance_assertion.assertion_key
qti.conformance_assertion.status
End-to-end behavior

Seven workflows the implementation must satisfy

These workflows are the customer-facing contract. The implementation deliverable should treat them as tests, not as descriptive copy.

01

Ingest a QTI package

Accept an IMS/QTI package, validate package closure and QTI XML against the bundled source bundle, then persist resources, files, artifacts, and immutable versions.

API
POST /tenants/{tenantId}/qti/packages
Data rows
qti.content_package, qti.package_resource, qti.package_file, qti.artifact, qti.artifact_version, qti.component, qti.variable_declaration, qti.processing_rule
Critical fields
qti.content_package.import_status, qti.content_package.package_hash, qti.package_resource.resource_type, qti.package_file.content_bytes, qti.artifact_version.source_xml, qti.artifact_version.canonical_xml, qti.artifact_version.xml_hash
Decision trace
Offline 1EdTech Source Bundle, XML Authority And Canonical Hashes, Package Resource And File Ingest, Idempotency And Hashes, Validation And Rejection Policy
curl -X POST "$BASE/tenants/$TENANT/qti/packages" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: pkg-upload-2026-05-20-001" \
  -H "X-QTI-Profile: qti-3.0" \
  -H "Content-Type: application/zip" \
  --data-binary @qti-package.zip
02

Inspect persisted QTI content

Use stable artifacts and immutable versions to inspect original XML, canonical XML, generated object graph, public JSON projections, variables, and processing rules without treating SQL rows as the 1EdTech source.

API
GET delivery JSON, GET XML export, or SQL/query APIs over artifact/version rows
Data rows
qti.artifact, qti.artifact_version, qti.component, qti.variable_declaration, qti.processing_rule
Critical fields
qti.artifact.artifact_kind, qti.artifact.qti_identifier, qti.artifact_version.object_graph, qti.artifact_version.authoring_json, qti.artifact_version.delivery_json, qti.component.ordinal, qti.variable_declaration.identifier, qti.processing_rule.rule_name
Decision trace
Generated Object Model Hub, Lossless Relational Projection, JSON Projection Boundaries, Artifact Versioning, Variable Declaration Projection, Processing Rule Projection
select artifact_kind, qti_identifier, latest_version_id
from qti.artifact
where tenant_id = $1 and qti_identifier = $2;
03

Deliver a frozen learner experience

Start a delivery session that snapshots one immutable artifact version and its delivery JSON so later content edits cannot change what the candidate saw.

API
POST /tenants/{tenantId}/qti/delivery-sessions
Data rows
qti.delivery_session, qti.artifact_version
Critical fields
qti.delivery_session.candidate_ref, qti.delivery_session.root_artifact_version_id, qti.delivery_session.status, qti.delivery_session.delivery_json_snapshot, qti.delivery_session.session_state
Decision trace
Delivery Session Snapshots, Candidate And Learner Data Privacy, Security Boundary
curl -X POST "$BASE/tenants/$TENANT/qti/delivery-sessions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"candidateRef":"9c41d14e-d011-4517-927e-b9bf0b7d5df4","rootArtifactVersionId":"4f4c18f4-c2ec-4278-97e2-2b07a3070d91"}'
04

Submit responses and explain scoring

Run template, response, and outcome processing against the session snapshot; persist response, template, outcome, and trace state for reproducible scoring review.

API
POST /tenants/{tenantId}/qti/delivery-sessions/{deliverySessionId}/attempts
Data rows
qti.attempt, qti.delivery_session, qti.processing_rule, qti.variable_declaration
Critical fields
qti.attempt.response_state, qti.attempt.template_state, qti.attempt.outcome_state, qti.attempt.processing_trace, qti.attempt.status, qti.attempt.submitted_at
Decision trace
Attempt State And Processing Trace, Runtime Execution Profile, Candidate And Learner Data Privacy
curl -X POST "$BASE/tenants/$TENANT/qti/delivery-sessions/$SESSION/attempts" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"artifactVersionId":"4f4c18f4-c2ec-4278-97e2-2b07a3070d91","responses":{"RESPONSE":"ChoiceA"}}'
05

Export QTI XML without platform taste

Export canonical XML from the generated object graph and validate it against the bundled schemas; QTI identifiers stay QTI identifiers and are not replaced by platform IDs.

API
GET /tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/xml
Data rows
qti.artifact, qti.artifact_version, qti.component
Critical fields
qti.artifact.qti_identifier, qti.artifact_version.source_xml, qti.artifact_version.canonical_xml, qti.artifact_version.xml_hash, qti.component.source_trace
Decision trace
XML Authority And Canonical Hashes, Lossless Relational Projection, Artifact Versioning, Validation And Rejection Policy
curl "$BASE/tenants/$TENANT/qti/artifact-versions/$VERSION/xml" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/xml"
06

Delete one candidate's runtime data

Delete delivery sessions and cascading attempts for a tenant-scoped pseudonymous candidate reference while leaving reusable QTI content, package files, artifacts, and versions intact.

API
DELETE /tenants/{tenantId}/qti/candidates/{candidateRef}/runtime-data
Data rows
qti.delivery_session, qti.attempt
Critical fields
qti.delivery_session.candidate_ref, qti.delivery_session.delivery_session_id, qti.attempt.delivery_session_id, qti.attempt.response_state, qti.attempt.processing_trace
Decision trace
Candidate And Learner Data Privacy, Tenant Boundary, API Boundary, Operational DDL Discipline
curl -X DELETE "$BASE/tenants/$TENANT/qti/candidates/9c41d14e-d011-4517-927e-b9bf0b7d5df4/runtime-data" \
  -H "Authorization: Bearer $TOKEN"
07

Persist conformance evidence

Run bundled examples, validation, round trips, processing assertions, and profile checks; persist the evidence so a reviewer can reproduce which profile and bundle were tested.

API
POST /qti/conformance-runs
Data rows
qti.conformance_run, qti.conformance_assertion
Critical fields
qti.conformance_run.profile, qti.conformance_run.bundle_hash, qti.conformance_run.status, qti.conformance_assertion.assertion_key, qti.conformance_assertion.spec_ref, qti.conformance_assertion.details
Decision trace
Conformance Evidence, Offline 1EdTech Source Bundle, Validation And Rejection Policy
curl -X POST "$BASE/qti/conformance-runs" \
  -H "Authorization: Bearer $TOKEN"
API reference

1EdTech QTI boundary contracts

All tenant-owned operations are tenant-scoped and authenticated. Each endpoint carries inline request and response schema tables so a client can be implemented from this page without opening the OpenAPI YAML. These contracts preserve QTI names and platform gap-fill names; Alpha-style simplifications belong to the future Alpha surface, not here.

POST

/tenants/{tenantId}/qti/packages

ingestContentPackage

Ingest an IMS/QTI content package or zip bundle.

Request

Binary application/zip body. Required Idempotency-Key header. Optional X-QTI-Profile header defaults to qti-3.0.

Success

202 application/json IngestAccepted with packageId, import status, and artifact versions when available.

Rejects

400 for malformed XML, bundled-XSD failure, package path traversal, missing package references, unsupported package closure, or privacy validation failure.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
tenantIdPathuuidRequiredTenant boundary for the operation. Cross-tenant reads, writes, exports, sessions, attempts, and deletions are rejected.qti.tenant.tenant_id
Idempotency-KeyHeaderstringRequiredClient retry key. Reusing the same key for the same tenant and same package returns the same import outcome.qti.content_package.idempotency_key
X-QTI-ProfileHeaderstringOptional; default qti-3.0Implementation conformance profile label stored with the import record.qti.content_package.qti_profile
bodyBodybinary application/zipRequiredIMS Content Package zip or loose QTI zip bundle. Original file bytes and normalized package hashes are persisted after validation.qti.package_file.content_bytes, qti.content_package.package_hash

Response envelope schema

FieldTypeRequiredDescriptionTrace
packageIduuidRequiredStable identifier for the accepted package ingest record.qti.content_package.package_id
statusenum(importing, imported, rejected)RequiredCurrent import lifecycle state for the accepted package.qti.content_package.import_status, import_status
artifactsarray<ArtifactVersion>OptionalArtifact versions created during ingest when projection is available in the response.qti.artifact_version
artifacts[].artifactIduuidRequired when artifacts[] is presentLogical artifact identity across versions.qti.artifact.artifact_id
artifacts[].artifactVersionIduuidRequired when artifacts[] is presentImmutable version identity for the generated artifact edition.qti.artifact_version.artifact_version_id
artifacts[].artifactKindstringRequired when artifacts[] is presentRepository category derived from QTI root element or manifest resource type.qti.artifact.artifact_kind, artifact_kind
artifacts[].rootElementstringRequired when artifacts[] is presentRoot XML element for this version.qti.artifact_version.root_element
artifacts[].schemaFilestringRequired when artifacts[] is presentBundled schema file used as validation authority.qti.artifact_version.schema_file
artifacts[].canonicalXmlHashstringRequired when artifacts[] is presentHash of canonical XML used for idempotency and preservation checks.qti.artifact_version.xml_hash
Related tables
qti.content_package, qti.package_resource, qti.package_file, qti.artifact, qti.artifact_version
Related fields
qti.content_package.idempotency_key, qti.content_package.package_hash, qti.content_package.import_status, qti.package_file.package_path, qti.artifact_version.source_xml, qti.artifact_version.canonical_xml
HTTP statuses
202, 400, 401, 403, 409, 500/502/503/504
GET

/tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/delivery-json

getDeliveryJson

Fetch declared-lossiness delivery JSON generated from the canonical object model.

Request

Tenant path scope and artifactVersionId path parameter.

Success

200 application/json QtiDeliveryJsonEnvelope with ETag. lossiness is declared and omittedFields names the allowed omissions.

Rejects

404 if the artifact version is absent or belongs to another tenant; 401/403 if the token tenant claim does not match.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
tenantIdPathuuidRequiredTenant boundary for the operation. Cross-tenant reads, writes, exports, sessions, attempts, and deletions are rejected.qti.tenant.tenant_id
artifactVersionIdPathuuidRequiredImmutable artifact version whose generated delivery JSON projection should be returned.qti.artifact_version.artifact_version_id

Response envelope schema

FieldTypeRequiredDescriptionTrace
ETagstring response headerRequiredValidator for the immutable projection returned by this version.qti.artifact_version.xml_hash, qti.artifact_version.artifact_version_id
artifactVersionIduuidOptionalImmutable artifact version identity, included when the projection generator emits it.qti.artifact_version.artifact_version_id
documentIdstringRequiredDocument identifier carried by the QTI projection; normally the QTI identifier when present.qti.artifact.qti_identifier
sourceBundleVersionstringRequiredIdentifier for the offline 1EdTech source bundle used to generate this projection.Offline 1EdTech Source Bundle
qtiQtiDeliveryNodeRequiredDelivery-safe generated QTI node tree. It preserves response, feedback, scoring, accessibility, and session identifiers.qti.artifact_version.delivery_json
qti.elementNameKnownElementNameRequiredQTI XML element name from the generated source bundle model.qti.component.element_name
qti.typeNameKnownTypeNameOptionalGenerated XSD type name when known for this node.qti.component.type_name
qti.attributesobject<string, string|number|boolean|null>RequiredAttribute projection for delivery clients.qti.component.attributes
qti.childrenarray<QtiDeliveryNode>RequiredChild QTI nodes in XML order.qti.component.ordinal, qti.component.component_path
qti.textstring|nullOptionalText value for text-bearing nodes when available in the delivery projection.qti.component.text_value
lossinessconst declaredRequiredSignals that only documented authoring-only or diagnostic fields may be omitted.qti.artifact_version.delivery_json, projection_lossiness
omittedFieldsarray<string>RequiredNames the fields intentionally left out of the delivery projection.qti.artifact_version.delivery_json, projection_lossiness
Related tables
qti.artifact_version
Related fields
qti.artifact_version.delivery_json, qti.artifact_version.object_graph, qti.artifact_version.artifact_version_id
HTTP statuses
200, 401, 403, 404, 500/502/503/504
PUT

/tenants/{tenantId}/qti/artifacts/{artifactId}/authoring-json

saveAuthoringJson

Save a lossless authoring JSON edit and create a new artifact version.

Request

QtiAuthoringJsonEnvelope body and required If-Match header for version safety.

Success

201 application/json ArtifactVersion for the new immutable version.

Rejects

409 for stale If-Match or version conflict; 400 when authoring JSON cannot round-trip to the generated object graph and canonical XML.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
tenantIdPathuuidRequiredTenant boundary for the operation. Cross-tenant reads, writes, exports, sessions, attempts, and deletions are rejected.qti.tenant.tenant_id
artifactIdPathuuidRequiredLogical artifact to edit. The save creates a new immutable artifact_version row.qti.artifact.artifact_id
If-MatchHeaderstringRequiredCurrent version validator. Missing If-Match is 428; stale values are 409.qti.artifact.latest_version_id, qti.artifact_version.version_number
artifactVersionIdBodyuuidOptionalVersion identity the authoring projection came from, when carried by the editor.qti.artifact_version.artifact_version_id
documentIdBodystringRequiredDocument identifier carried by the QTI authoring projection.qti.artifact.qti_identifier
sourceBundleVersionBodystringRequiredIdentifier for the offline 1EdTech source bundle used to generate this authoring projection.Offline 1EdTech Source Bundle
qtiBodyQtiAuthoringNodeRequiredLossless generated QTI object graph node tree. It must round-trip to canonical XML.qti.artifact_version.authoring_json, qti.artifact_version.object_graph
lossinessBodyconst noneRequiredAuthoring edits must preserve all spec-defined fields needed to reconstruct the object graph and XML.qti.artifact_version.authoring_json, projection_lossiness
editMetadataBodyobjectOptionalEditor metadata. It is platform metadata and must not replace QTI source trace.qti.artifact_version.spec_trace

Response envelope schema

FieldTypeRequiredDescriptionTrace
artifactIduuidRequiredLogical artifact identity across versions.qti.artifact.artifact_id
artifactVersionIduuidRequiredNew immutable version identity created by this save.qti.artifact_version.artifact_version_id
artifactKindstringRequiredRepository category derived from QTI root element or manifest resource type.qti.artifact.artifact_kind, artifact_kind
rootElementstringRequiredRoot XML element for the new version.qti.artifact_version.root_element
schemaFilestringRequiredBundled schema file used as validation authority.qti.artifact_version.schema_file
canonicalXmlHashstringRequiredHash of canonical XML for the new version.qti.artifact_version.xml_hash
Related tables
qti.artifact, qti.artifact_version, qti.component
Related fields
qti.artifact.latest_version_id, qti.artifact_version.version_number, qti.artifact_version.authoring_json, qti.artifact_version.xml_hash
HTTP statuses
201, 400, 401, 403, 404, 409, 428, 500/502/503/504
GET

/tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/xml

exportXml

Export canonical XML from a persisted artifact version.

Request

Tenant path scope and artifactVersionId path parameter.

Success

200 application/xml canonical QTI XML.

Rejects

404 for missing or cross-tenant artifact version; 500/release-blocking evidence if canonical XML cannot validate against the bundled source bundle.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
tenantIdPathuuidRequiredTenant boundary for the operation. Cross-tenant reads, writes, exports, sessions, attempts, and deletions are rejected.qti.tenant.tenant_id
artifactVersionIdPathuuidRequiredImmutable artifact version whose canonical XML should be exported.qti.artifact_version.artifact_version_id
AcceptHeaderapplication/xmlOptionalClients should request XML. The response body is canonical QTI XML, not JSON.qti.artifact_version.canonical_xml

Response envelope schema

FieldTypeRequiredDescriptionTrace
bodystring application/xmlRequiredCanonical XML generated from the persisted object graph and validated against the bundled source bundle.qti.artifact_version.canonical_xml, qti.artifact_version.object_graph
Content-Typeapplication/xml response headerRequiredSignals XML export; this endpoint does not return an API JSON envelope on success.XML Authority And Canonical Hashes
Related tables
qti.artifact_version, qti.component
Related fields
qti.artifact_version.canonical_xml, qti.artifact_version.xml_hash, qti.artifact_version.schema_file, qti.component.element_name
HTTP statuses
200, 401, 403, 404, 500/502/503/504
POST

/tenants/{tenantId}/qti/delivery-sessions

startDeliverySession

Start a delivery session using a snapshot of the current delivery JSON.

Request

JSON body with candidateRef and rootArtifactVersionId. candidateRef must be an opaque tenant-scoped pseudonymous UUID string.

Success

201 application/json DeliverySession with deliverySessionId, rootArtifactVersionId, status, and deliveryJsonSnapshot.

Rejects

400 if candidateRef contains direct PII or if the root artifact version cannot produce delivery JSON; 401/403 for tenant mismatch.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
tenantIdPathuuidRequiredTenant boundary for the operation. Cross-tenant reads, writes, exports, sessions, attempts, and deletions are rejected.qti.tenant.tenant_id
candidateRefBodystring pseudonymous UUIDRequiredOpaque tenant-scoped pseudonymous candidate reference. Direct learner PII is rejected.qti.delivery_session.candidate_ref
rootArtifactVersionIdBodyuuidRequiredImmutable item, section, or test version to snapshot for this learner session.qti.delivery_session.root_artifact_version_id, qti.artifact_version.artifact_version_id

Response envelope schema

FieldTypeRequiredDescriptionTrace
deliverySessionIduuidRequiredStable session identifier exposed by delivery APIs.qti.delivery_session.delivery_session_id
rootArtifactVersionIduuidRequiredImmutable artifact version pinned by this session.qti.delivery_session.root_artifact_version_id
statusstringRequiredSession lifecycle state after creation.qti.delivery_session.status, delivery_session_status
deliveryJsonSnapshotobjectRequiredSnapshot of delivery JSON at session start. Later content edits cannot change what this session saw.qti.delivery_session.delivery_json_snapshot, qti.artifact_version.delivery_json
Related tables
qti.delivery_session, qti.artifact_version
Related fields
qti.delivery_session.candidate_ref, qti.delivery_session.root_artifact_version_id, qti.delivery_session.status, qti.delivery_session.delivery_json_snapshot
HTTP statuses
201, 400, 401, 403, 404, 500/502/503/504
POST

/tenants/{tenantId}/qti/delivery-sessions/{deliverySessionId}/attempts

submitAttempt

Submit responses and execute QTI processing against the session snapshot.

Request

JSON body with artifactVersionId and responses object. Response keys must match QTI response variable identifiers and declaration shape.

Success

200 application/json AttemptResult with attemptId, responseState, outcomeState, and privacy-redacted processingTrace.

Rejects

400 for invalid response cardinality/base_type, unknown artifact version for the session, unsupported runtime feature, or unregistered custom operator; unsupported processing fails closed with a trace event.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
tenantIdPathuuidRequiredTenant boundary for the operation. Cross-tenant reads, writes, exports, sessions, attempts, and deletions are rejected.qti.tenant.tenant_id
deliverySessionIdPathuuidRequiredDelivery session receiving the attempt submission.qti.delivery_session.delivery_session_id, qti.attempt.delivery_session_id
artifactVersionIdBodyuuidRequiredImmutable artifact version attempted within the session.qti.attempt.artifact_version_id, qti.artifact_version.artifact_version_id
responsesBodyobject<string, QTI value>RequiredCandidate response values keyed by QTI response variable identifier. Cardinality and base type must match declarations.qti.attempt.response_state, qti.variable_declaration.identifier, qti.variable_declaration.cardinality, qti.variable_declaration.base_type

Response envelope schema

FieldTypeRequiredDescriptionTrace
attemptIduuidRequiredStable identifier for the persisted attempt record.qti.attempt.attempt_id
responseStateobjectRequiredCandidate response variables at the last processing point.qti.attempt.response_state
outcomeStateobjectRequiredOutcome variables after template, response, and outcome processing.qti.attempt.outcome_state
processingTracearray<object>RequiredPrivacy-redacted deterministic trace of processing operations and diagnostics.qti.attempt.processing_trace, Candidate And Learner Data Privacy
Related tables
qti.attempt, qti.delivery_session, qti.variable_declaration, qti.processing_rule
Related fields
qti.attempt.response_state, qti.attempt.template_state, qti.attempt.outcome_state, qti.attempt.processing_trace, qti.processing_rule.rule_name
HTTP statuses
200, 400, 401, 403, 404, 500/502/503/504
DELETE

/tenants/{tenantId}/qti/candidates/{candidateRef}/runtime-data

deleteCandidateRuntimeData

Delete one pseudonymous candidate's delivery sessions and cascading attempts.

Request

Tenant path scope and candidateRef path parameter. Service-role or tenant-authorized token required for bulk learner-runtime deletion.

Success

204 with no body after deleting learner-runtime rows. Reusable content package, artifact, version, resource, file, and conformance rows remain.

Rejects

400 if candidateRef is not the pseudonymous UUID format; 401/403 for tenant mismatch or insufficient role.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
tenantIdPathuuidRequiredTenant boundary for the operation. Cross-tenant reads, writes, exports, sessions, attempts, and deletions are rejected.qti.tenant.tenant_id
candidateRefPathstring pseudonymous UUIDRequiredOpaque tenant-scoped pseudonymous candidate reference whose runtime data should be deleted.qti.delivery_session.candidate_ref

Response envelope schema

FieldTypeRequiredDescriptionTrace
bodyemptyRequired emptyNo response body. Successful deletion is represented by HTTP 204.204
deleted scopeside effectRequiredDeletes qti.delivery_session rows for tenantId + candidateRef and cascades qti.attempt rows; content tables remain.qti.delivery_session.candidate_ref, qti.delivery_session.delivery_session_id, qti.attempt.delivery_session_id
Related tables
qti.delivery_session, qti.attempt
Related fields
qti.delivery_session.candidate_ref, qti.delivery_session.delivery_session_id, qti.attempt.delivery_session_id
HTTP statuses
204, 400, 401, 403, 404, 500/502/503/504
POST

/qti/conformance-runs

runConformance

Run the bundled QTI example corpus through validation, round-trip, and processing assertions.

Request

Administrative request using the configured source bundle and runner version.

Success

202 application/json with conformanceRunId.

Rejects

Error state when the runner, bundle, validation tool, or persistence adapter cannot produce a valid pass/fail result.

Request schema

FieldInTypeRequiredDescriptionTrace
AuthorizationHeaderBearer JWTRequiredSigned, trusted, unexpired token. Tenant-owned routes also require the token tenant claim to match tenantId.Security Boundary, Tenant Boundary
bodyBodyemptyRequired emptyThe server uses the configured offline source bundle, validation tools, persistence adapter, and runner version.qti.conformance_run.bundle_hash, qti.conformance_run.runner_version

Response envelope schema

FieldTypeRequiredDescriptionTrace
conformanceRunIduuidRequiredStable identifier for the accepted conformance run.qti.conformance_run.conformance_run_id
Related tables
qti.conformance_run, qti.conformance_assertion
Related fields
qti.conformance_run.profile, qti.conformance_run.bundle_hash, qti.conformance_run.runner_version, qti.conformance_assertion.status, qti.conformance_assertion.spec_ref
HTTP statuses
202, 401, 403, 500/502/503/504
Normative behavior

Behavior contracts

Each behavior below is backed by the approved architecture and by a data dictionary location. If implementation work cannot satisfy one of these rows, the loop should roll back to the earliest flawed upstream deliverable.

Source authority

The offline 1EdTech QTI 3.0 bundle is the standards input. Live web drift does not change accepted schemas, examples, response-processing templates, vocabularies, or generated trace until a new platform3 architecture/data-dictionary deliverable adopts it.

27 XSDs, 683 global elements, 28,292 embedded Schematron assertions, 6 bundled response-processing templates, and 327 XML examples.

Runtime execution profile

The runtime executes item-level template, response, and outcome processing deterministically against one submitted attempt. Unsupported rules or expressions fail the processing result with a trace entry; they are not silently ignored.

87 XSD-reachable processing elements, 87 inline elements supported, 6 bundled templates supported, 75 processing assertions passed.

Data model

Objects, lifecycle, and provenance

The customer website summarizes the model; the approved data dictionary remains the field-level source of truth. Every row below links back to that dictionary and to the owning ITDs.

Tenant and package

qti.tenant

Platform isolation root for schools, districts, publishers, or applications using the QTI surface.

Platform gap fill

A tenant owns QTI content, delivery sessions, attempts, and API access. QTI does not define tenancy, so this table is the platform boundary that keeps one customer's content and learner-runtime data separate from another's.

Lifecycle
Created before package ingest or delivery. Content packages, artifacts, sessions, and attempts point back to a tenant. Deleting a tenant is outside this package's normal workflow; learner-runtime deletion is done by candidate_ref instead.
Primary key
tenant_id
Architecture
ITD-008 Tenant Boundary, ITD-019 Security Boundary
Full dictionary
Open qti.tenant in the data dictionary
Relationships
  • Parent of qti.content_package, qti.artifact, and qti.delivery_session.
Fields
tenant_id tenant_key display_name created_at

qti.content_package

One imported IMS Content Package or loose XML bundle, scoped to a tenant.

Gap fill row with 1EdTech pass-through values

Records the package-level identity, import lifecycle, manifest identifier, hash, and metadata for an uploaded QTI package. This is where package ingest becomes durable before resources, files, artifacts, and versions are projected.

Lifecycle
Created by package ingest. The row starts as importing, becomes imported after validation/projection, rejected after validation failure, or superseded when later content replaces it operationally.
Primary key
package_id
Architecture
ITD-009 Package Resource And File Ingest, ITD-010 Idempotency And Hashes, ITD-020 Validation And Rejection Policy
Full dictionary
Open qti.content_package in the data dictionary
Relationships
  • Belongs to one qti.tenant.
  • Parent of qti.package_resource, qti.package_file, and imported qti.artifact rows.
Fields
package_id tenant_id source_uri idempotency_key package_hash manifest_identifier qti_profile import_status metadata imported_at

qti.package_resource

IMS manifest resource row with resource identifiers, type, href, dependencies, and metadata.

Gap fill row with 1EdTech pass-through values

Indexes manifest resources from an imported package without rewriting IMS/QTI names. The row lets delivery, authoring, export, and diagnostics find the primary XML or asset files associated with each manifest resource.

Lifecycle
Created during package ingest after manifest parsing and package-closure checks. Deleted when the owning content package is deleted.
Primary key
resource_id
Architecture
ITD-009 Package Resource And File Ingest, ITD-020 Validation And Rejection Policy
Full dictionary
Open qti.package_resource in the data dictionary
Relationships
  • Belongs to one qti.content_package.
  • May be referenced by qti.package_file and qti.artifact.
Fields
resource_id package_id resource_identifier resource_type href dependencies metadata

qti.package_file

Original file bytes from an imported IMS/QTI package.

Gap fill row with 1EdTech pass-through values

Preserves the exact package file payloads needed for export, audit, validation diagnostics, and media delivery. This includes imsmanifest XML, QTI XML, media, stylesheets, pronunciation lexicons, metadata XML, and other package assets.

Lifecycle
Created during package ingest for each normalized package path. Deleted when the owning content package is deleted. resource_id is set when a manifest resource first listed the file.
Primary key
package_file_id
Architecture
ITD-009 Package Resource And File Ingest, ITD-020 Validation And Rejection Policy
Full dictionary
Open qti.package_file in the data dictionary
Relationships
  • Belongs to one qti.content_package.
  • Optionally points to the qti.package_resource that first listed the file.
Fields
package_file_id package_id resource_id package_path media_type byte_length content_hash content_bytes metadata created_at

QTI artifact persistence

qti.artifact

Stable logical QTI document or package artifact across immutable versions.

Gap fill row with 1EdTech pass-through values

Represents one logical QTI thing: item, test, section, stimulus, outcome declaration, response processing, result, usage data, metadata, or manifest-only resource. QTI identifiers remain QTI-domain identifiers; artifact_id is the platform identity for version history and APIs.

Lifecycle
Created during ingest or authoring. New edits create qti.artifact_version rows instead of replacing the artifact. latest_version_id is a convenience pointer to the newest version.
Primary key
artifact_id
Architecture
ITD-011 Artifact Versioning, ITD-012 Artifact Kind Allowed Values, ITD-004 XML Authority And Canonical Hashes
Full dictionary
Open qti.artifact in the data dictionary
Relationships
  • Belongs to one qti.tenant.
  • May originate from qti.content_package and qti.package_resource.
  • Parent of qti.artifact_version.
Fields
artifact_id tenant_id package_id resource_id artifact_kind qti_identifier title language latest_version_id created_at

qti.artifact_version

Immutable XML, generated object graph, projections, and trace for one saved artifact edition.

Gap fill row with 1EdTech pass-through values

Binds original XML, canonical XML, generated object graph, public JSON projections, root/schema evidence, and spec trace to one immutable version. This table is the heart of faithful QTI round trips and stable historical delivery.

Lifecycle
Created on ingest or authoring save. Never updated in place except operational metadata that does not change content semantics. New edits append a later version_number.
Primary key
artifact_version_id
Architecture
ITD-004 XML Authority And Canonical Hashes, ITD-006 JSON Projection Boundaries, ITD-011 Artifact Versioning
Full dictionary
Open qti.artifact_version in the data dictionary
Relationships
  • Belongs to one qti.artifact.
  • Parent of qti.component, qti.variable_declaration, qti.processing_rule, qti.delivery_session, and qti.attempt references.
Fields
artifact_version_id artifact_id version_number source_xml canonical_xml xml_hash root_element root_type schema_file object_graph delivery_json authoring_json spec_trace supersedes_version_id created_at created_by

qti.component

Lossless relational projection of generated QTI object-graph nodes.

Gap fill row with 1EdTech pass-through values

Stores ordered object-graph nodes so the repository can query, diff, validate, and rehydrate QTI content without making relational rows the source of truth. Promoted query tables are not enough for round trip; component rows preserve the full structural bridge.

Lifecycle
Created whenever an artifact_version object graph is persisted. Deleted when the owning artifact_version is deleted.
Primary key
component_id
Architecture
ITD-005 Lossless Relational Projection, ITD-004 XML Authority And Canonical Hashes
Full dictionary
Open qti.component in the data dictionary
Relationships
  • Belongs to one qti.artifact_version.
  • Self-references parent_component_id.
  • Parent of qti.variable_declaration and qti.processing_rule rows.
Fields
component_id artifact_version_id parent_component_id ordinal element_name qualified_name namespace_uri type_name qti_identifier component_path attributes text_value tail_value source_trace

qti.variable_declaration

Typed query projection for QTI response, outcome, template, and context variables.

Gap fill row with 1EdTech pass-through values

Promotes QTI variable declarations into queryable rows so processing, delivery, validation, and reporting can find variables without scanning the full object graph. The object graph remains the reconstruction source.

Lifecycle
Created when an artifact_version object graph is projected. Deleted when the owning artifact_version or component is deleted.
Primary key
variable_declaration_id
Architecture
ITD-013 Variable Declaration Projection, ITD-021 Runtime Execution Profile
Full dictionary
Open qti.variable_declaration in the data dictionary
Relationships
  • Belongs to one qti.artifact_version.
  • References the qti.component that declared the variable.
Fields
variable_declaration_id artifact_version_id component_id variable_kind identifier cardinality base_type default_value correct_response mapping source_trace

qti.processing_rule

Executable QTI processing and expression tree projection.

Gap fill row with 1EdTech pass-through values

Promotes response, outcome, template, and expression nodes into ordered rows for execution, coverage, diagnostics, and trace generation. The rule_name and operands remain generated QTI values; the row scope and sequence are platform execution aids.

Lifecycle
Created when an artifact_version object graph is projected. Deleted when the owning artifact_version or component is deleted.
Primary key
processing_rule_id
Architecture
ITD-014 Processing Rule Projection, ITD-021 Runtime Execution Profile
Full dictionary
Open qti.processing_rule in the data dictionary
Relationships
  • Belongs to one qti.artifact_version.
  • References the qti.component backing the rule.
  • Self-references parent_processing_rule_id for nested rule/expression trees.
Fields
processing_rule_id artifact_version_id component_id parent_processing_rule_id rule_scope rule_name sequence_number operands source_trace

Learner runtime

qti.delivery_session

Candidate delivery snapshot against one immutable root artifact version.

Platform gap fill

Freezes exactly what one pseudonymous candidate was shown by storing root artifact version, delivery JSON snapshot, lifecycle state, and runtime session state. This protects historical learner experience from later content edits.

Lifecycle
Created by startDeliverySession. Moves through created, active, suspended, submitted, review, closed, or voided. Candidate-scoped deletion removes sessions and cascading attempts while leaving reusable content intact.
Primary key
delivery_session_id
Architecture
ITD-015 Delivery Session Snapshots, ITD-024 Candidate And Learner Data Privacy, ITD-019 Security Boundary
Full dictionary
Open qti.delivery_session in the data dictionary
Relationships
  • Belongs to one qti.tenant.
  • Pins one qti.artifact_version as root_artifact_version_id.
  • Parent of qti.attempt.
Fields
delivery_session_id tenant_id candidate_ref root_artifact_version_id status delivery_json_snapshot session_state created_at updated_at

qti.attempt

Candidate response, template, outcome, and processing trace snapshot inside a delivery session.

Gap fill row with 1EdTech pass-through values

Stores the learner's QTI variable state and the deterministic processing trace needed to explain scoring and feedback for one item/test artifact version within a session. It is the learner-runtime record that turns QTI content into reportable outcomes.

Lifecycle
Created when a candidate starts or submits an attempt. Moves through active, suspended, submitted, reviewed, or voided. Deleted through candidate-scoped runtime deletion by cascading from delivery_session.
Primary key
attempt_id
Architecture
ITD-016 Attempt State And Processing Trace, ITD-021 Runtime Execution Profile, ITD-024 Candidate And Learner Data Privacy
Full dictionary
Open qti.attempt in the data dictionary
Relationships
  • Belongs to one qti.delivery_session.
  • References the qti.artifact_version attempted.
Fields
attempt_id delivery_session_id artifact_version_id attempt_number status response_state template_state outcome_state processing_trace started_at suspended_at submitted_at

Release evidence

qti.conformance_run

Release evidence for a QTI conformance/profile run.

Platform gap fill

Persists repeatable proof that a runner exercised the source bundle, examples, XML/object/relational/JSON round trips, processing coverage, and profile expectations. The run row summarizes the evidence; assertion rows contain details.

Lifecycle
Created when the conformance runner starts. Moves from running to passed, failed, or error. Retained as release evidence.
Primary key
conformance_run_id
Architecture
ITD-017 Conformance Evidence
Full dictionary
Open qti.conformance_run in the data dictionary
Relationships
  • Parent of qti.conformance_assertion.
Fields
conformance_run_id profile bundle_hash runner_version started_at finished_at status summary

qti.conformance_assertion

Per-example and per-feature conformance evidence.

Gap fill row with 1EdTech pass-through values

Stores individual assertion results from conformance, round-trip, validation, processing, and coverage checks. This lets releases and future AI agents identify exactly which example, spec reference, or feature passed or failed.

Lifecycle
Created as child rows during a conformance run. Deleted when the parent run is deleted.
Primary key
conformance_assertion_id
Architecture
ITD-017 Conformance Evidence
Full dictionary
Open qti.conformance_assertion in the data dictionary
Relationships
  • Belongs to one qti.conformance_run.
Fields
conformance_assertion_id conformance_run_id assertion_key artifact_ref spec_ref status details
Field index

Every documented field links to its dictionary entry and ITDs

This compact index is intentionally exhaustive: 127 fields, each with meaning, invalid conditions, source label, and trace.

FieldMeaningTypeInvalid whenSourceArchitecture trace
qti.tenant.tenant_id Stable platform identifier for one tenant boundary. uuid
Required
Not parseable as UUID, reused by another tenant, or copied into QTI XML as assessment content. Platform gap fill
Platform isolation identifier.
ITD-008 Tenant Boundary
qti.tenant.tenant_key Human-stable lookup key for operations, logs, and local tooling. text
Required
Duplicated, empty in API input, used for direct learner identity, or treated as a QTI identifier. Platform gap fill
Platform operational key.
ITD-008 Tenant Boundary
qti.tenant.display_name Operational display label for the tenant. text
Required
Null, blank in API input, or used in place of tenant_id for joins. Platform gap fill
Platform console metadata.
ITD-008 Tenant Boundary
qti.tenant.created_at Timestamp when the tenant row was inserted. timestamptz
Required, default now()
Null, manually backdated without migration evidence, or compared as local time without timezone normalization. Platform gap fill
Platform audit metadata.
ITD-022 Operational DDL Discipline
qti.content_package.package_id Stable identifier assigned to one package ingest record. uuid
Required
Not a UUID or reused across package rows. Platform gap fill
Platform package identity.
ITD-009 Package Resource And File Ingest
qti.content_package.tenant_id Tenant that owns the package and all extracted resources. uuid
Required
References a missing tenant or disagrees with the tenant path in the API request. Platform gap fill
Tenant boundary.
ITD-008 Tenant Boundary, ITD-009 Package Resource And File Ingest
qti.content_package.source_uri Original filename, URI, or content-addressable reference supplied by the ingest caller. text
Nullable
Used as a primary identity, contains secrets, or points outside tenant authorization. Platform gap fill
Operational ingest evidence.
ITD-009 Package Resource And File Ingest
qti.content_package.idempotency_key Idempotency-Key from the package ingest API so retries return the same package instead of duplicating work. text
Nullable
Same tenant reuses the key for different package bytes, or a secret/token is stored here. Platform gap fill
HTTP/API idempotency behavior.
ITD-010 Idempotency And Hashes, ITD-018 API Boundary
qti.content_package.package_hash Cryptographic hash of the normalized package payload used to identify repeated imports. text
Required
Missing, not reproducible from the normalized package, or reused for different bytes in one tenant. Platform gap fill
Idempotent persistence and audit.
ITD-010 Idempotency And Hashes
qti.content_package.manifest_identifier IMS manifest identifier copied from imsmanifest when the package has one. text
Nullable
Invented when no manifest exists, changed to a platform name, or used as a database primary key. 1EdTech pass-through
IMS content package manifest identifier.
ITD-009 Package Resource And File Ingest, ITD-007 Provenance Labels
qti.content_package.qti_profile Conformance profile asserted for this import. text
Required, default 'qti-3.0'
Unsupported profile string, null, or used to imply the live network spec changed the accepted bundle. Platform gap fill
Platform conformance profile label tied to the offline QTI 3.0 bundle.
ITD-001 Offline 1EdTech Source Bundle, ITD-017 Conformance Evidence
qti.content_package.import_status Current lifecycle state of package ingest. text
Required, default 'imported'
Outside the enum set or inconsistent with resource/artifact projection state. Platform gap fill
Platform package import lifecycle.
ITD-009 Package Resource And File Ingest
qti.content_package.metadata Generated package-level import evidence such as manifest facts, QTI metadata summaries, counts, validation diagnostics, and vocabulary projections. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, direct learner PII, access tokens, or duplicated source XML bytes. Platform gap fill
Generated import evidence envelope.
ITD-009 Package Resource And File Ingest, ITD-020 Validation And Rejection Policy
qti.content_package.imported_at Timestamp when the package row was inserted. timestamptz
Required, default now()
Null or used as the source of content version ordering instead of artifact_version.version_number. Platform gap fill
Import audit metadata.
ITD-022 Operational DDL Discipline
qti.package_resource.resource_id Stable identifier for this manifest resource row. uuid
Required
Not a UUID or reused by another package_resource row. Platform gap fill
Platform row identity.
ITD-009 Package Resource And File Ingest
qti.package_resource.package_id Owning content package. uuid
Required
Missing package, cross-tenant package/resource mixture, or null. Platform gap fill
Package ownership boundary.
ITD-009 Package Resource And File Ingest
qti.package_resource.resource_identifier IMS manifest resource identifier copied from imsmanifest. text
Required
Duplicated within a package, rewritten to a platform UUID, or missing when the manifest resource has an identifier. 1EdTech pass-through
IMS manifest resource identifier.
ITD-009 Package Resource And File Ingest, ITD-007 Provenance Labels
qti.package_resource.resource_type IMS/QTI resource type from the package manifest. text
Required
Blank, invented by Alpha naming, or used to bypass validation. 1EdTech pass-through
IMS/QTI package resource type value.
ITD-009 Package Resource And File Ingest, ITD-007 Provenance Labels
qti.package_resource.href Package-relative path to the resource's primary file. text
Nullable
Absolute URL for a packaged file, path traversal, unnormalized slashes, or missing package_file for a required primary file. 1EdTech pass-through
IMS package resource href.
ITD-009 Package Resource And File Ingest, ITD-020 Validation And Rejection Policy
qti.package_resource.dependencies Manifest dependency references and variant resource links generated from the package manifest. jsonb
Required, default '[]'::jsonb
Null, non-array JSON, unresolved dependency, or cross-package dependency not represented as allowed external metadata. 1EdTech pass-through
IMS package resource dependency references.
ITD-009 Package Resource And File Ingest, ITD-020 Validation And Rejection Policy
qti.package_resource.metadata Manifest-derived metadata, file list, and resource facts generated at ingest. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, direct learner PII, auth tokens, or package bytes. 1EdTech pass-through
IMS manifest resource metadata projection when copied from manifest; generated file inventory remains gap-fill metadata.
ITD-009 Package Resource And File Ingest, ITD-007 Provenance Labels
qti.package_file.package_file_id Stable identifier for one original package file row. uuid
Required
Not a UUID or reused. Platform gap fill
Platform file row identity.
ITD-009 Package Resource And File Ingest
qti.package_file.package_id Owning content package. uuid
Required
References a missing package or mixes tenants. Platform gap fill
Package ownership boundary.
ITD-009 Package Resource And File Ingest
qti.package_file.resource_id Manifest resource that first listed this file, when applicable. uuid
Nullable
References a resource from a different package or tenant. Platform gap fill
Platform linkage from manifest resource to file preservation.
ITD-009 Package Resource And File Ingest
qti.package_file.package_path Normalized package-relative path for this file. text
Required
Contains ../ escape, backslash ambiguity, an absolute scheme, duplicate normalized path, or a path not present in the uploaded package. 1EdTech pass-through
IMS package-relative file path.
ITD-009 Package Resource And File Ingest, ITD-020 Validation And Rejection Policy
qti.package_file.media_type Detected or declared media type used for export, diagnostics, and content serving. text
Required, default 'application/octet-stream'
Null, unparseable as a media type, or trusted more than validation of the actual content. Platform gap fill
Generated file metadata for platform serving and diagnostics.
ITD-009 Package Resource And File Ingest
qti.package_file.byte_length Original byte length of content_bytes. integer
Required
Negative, null, or mismatched with content_bytes. Platform gap fill
Generated package file evidence.
ITD-009 Package Resource And File Ingest
qti.package_file.content_hash Cryptographic hash of the original file bytes. text
Required
Missing, digest does not match content_bytes, or algorithm is not recorded. Platform gap fill
File-level audit and export integrity evidence.
ITD-010 Idempotency And Hashes
qti.package_file.content_bytes Original bytes exactly as accepted from the package for this path. bytea
Required
Null, replaced by parsed text only, mutated after ingest, or contains a file that failed package-closure validation. 1EdTech pass-through
Original package file bytes.
ITD-009 Package Resource And File Ingest, ITD-004 XML Authority And Canonical Hashes
qti.package_file.metadata Generated evidence about the file, such as manifest listing flags, validation role, and extracted diagnostics. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, auth tokens, direct learner PII, or raw file bytes duplicated as JSON. Platform gap fill
Generated file-preservation evidence.
ITD-009 Package Resource And File Ingest, ITD-020 Validation And Rejection Policy
qti.package_file.created_at Timestamp when the file row was inserted. timestamptz
Required, default now()
Null or used as a proxy for QTI content versioning. Platform gap fill
Package-file audit metadata.
ITD-022 Operational DDL Discipline
qti.artifact.artifact_id Stable platform identity for one logical artifact across versions. uuid
Required
Not a UUID, reused, or derived from a mutable QTI identifier. Platform gap fill
Platform logical artifact identity.
ITD-011 Artifact Versioning
qti.artifact.tenant_id Tenant that owns this artifact. uuid
Required
Missing tenant or different from the owning package tenant. Platform gap fill
Tenant ownership boundary.
ITD-008 Tenant Boundary, ITD-011 Artifact Versioning
qti.artifact.package_id Origin package for imported artifacts. uuid
Nullable
References a package owned by another tenant. Platform gap fill
Package origin evidence.
ITD-009 Package Resource And File Ingest, ITD-011 Artifact Versioning
qti.artifact.resource_id Origin manifest resource for imported artifacts. uuid
Nullable
Resource comes from another package or tenant. Platform gap fill
Manifest origin evidence.
ITD-009 Package Resource And File Ingest, ITD-011 Artifact Versioning
qti.artifact.artifact_kind Repository category derived from QTI root element or manifest resource type. text
Required
Outside enum set, inconsistent with root_element on versions, or changed for Alpha vocabulary. Platform gap fill
Gap-fill classification derived from QTI roots.
ITD-012 Artifact Kind Allowed Values
qti.artifact.qti_identifier QTI identifier attribute copied from the root object when present. text
Nullable
Invented when absent, rewritten to a UUID, or assumed unique outside artifact scope. 1EdTech pass-through
QTI identifier attribute.
ITD-004 XML Authority And Canonical Hashes, ITD-007 Provenance Labels
qti.artifact.title QTI title or generated display label when present. text
Nullable
Used as identity, translated without retaining source XML, or contains direct learner PII. 1EdTech pass-through
QTI title or package display metadata when copied from source.
ITD-004 XML Authority And Canonical Hashes, ITD-007 Provenance Labels
qti.artifact.language xml:lang or package-default language associated with the artifact. text
Nullable
Not a language tag, invented without source/default evidence, or used to filter tenant access. 1EdTech pass-through
xml:lang or package default language.
ITD-004 XML Authority And Canonical Hashes
qti.artifact.latest_version_id Newest immutable artifact version for convenience reads. uuid
Nullable
Points to another artifact's version or treated as authoritative history instead of the artifact_version table. Platform gap fill
Platform version lookup convenience.
ITD-011 Artifact Versioning
qti.artifact.created_at Logical artifact creation timestamp. timestamptz
Required, default now()
Null or used as version_number. Platform gap fill
Artifact audit metadata.
ITD-022 Operational DDL Discipline
qti.artifact_version.artifact_version_id Stable identifier for one immutable artifact edition. uuid
Required
Not a UUID or reused. Platform gap fill
Platform version identity.
ITD-011 Artifact Versioning
qti.artifact_version.artifact_id Logical artifact this version belongs to. uuid
Required
Missing artifact or cross-tenant mismatch through artifact. Platform gap fill
Version belongs to logical artifact identity.
ITD-011 Artifact Versioning
qti.artifact_version.version_number Forward-only per-artifact version number. integer
Required
Zero or negative by convention, duplicated for an artifact, skipped without migration evidence, or reused after rollback. Platform gap fill
Immutable version sequencing.
ITD-011 Artifact Versioning
qti.artifact_version.source_xml Original XML accepted after bundled XSD/Schematron validation. xml
Required
Malformed XML, not valid against the bundled schema, contains direct learner runtime PII, or differs from the persisted object graph without trace. 1EdTech pass-through
Original QTI XML accepted from the 1EdTech source format.
ITD-004 XML Authority And Canonical Hashes, ITD-020 Validation And Rejection Policy
qti.artifact_version.canonical_xml Canonicalized XML used for equivalence checks and stable export. text
Required
Not reproducible from object_graph, hash mismatch, or changed after delivery sessions point to this version. 1EdTech pass-through
Canonical QTI XML derived from source XML under platform canonicalization rules.
ITD-004 XML Authority And Canonical Hashes
qti.artifact_version.xml_hash Hash of canonical_xml used for idempotency and semantic preservation checks. text
Required
Does not match canonical_xml, algorithm omitted, or duplicates a prior version for the same artifact. Platform gap fill
Platform equivalence and idempotency evidence over QTI XML.
ITD-004 XML Authority And Canonical Hashes, ITD-010 Idempotency And Hashes
qti.artifact_version.root_element Root XML element for this version. text
Required
Not present in the bundled root catalog or inconsistent with source_xml. 1EdTech pass-through
QTI root element from bundled schemas.
ITD-004 XML Authority And Canonical Hashes, ITD-002 Generated Object Model Hub
qti.artifact_version.root_type Generated XSD type name for the root element. text
Nullable
Invented type, wrong schema namespace, or mismatch with root_element. 1EdTech pass-through
Generated XSD root type from bundled QTI schemas.
ITD-002 Generated Object Model Hub, ITD-004 XML Authority And Canonical Hashes
qti.artifact_version.schema_file Bundled schema file used as validation authority. text
Required
Live network schema URL, missing local schema, or schema that does not define the root. 1EdTech pass-through
Bundled QTI XSD file.
ITD-001 Offline 1EdTech Source Bundle, ITD-020 Validation And Rejection Policy
qti.artifact_version.object_graph Canonical generated object-model graph serialized as JSONB for internal persistence. jsonb
Required
Null, non-object JSON, loses mixed-content tail text, loses namespace identity, or becomes a public delivery contract. Platform gap fill
Generated internal object graph for persistence; QTI defines XML, not this JSONB envelope.
ITD-002 Generated Object Model Hub, ITD-005 Lossless Relational Projection
qti.artifact_version.delivery_json Generated consumer-facing projection used by delivery applications and session snapshots. jsonb
Nullable
Drops response identifiers, scoring dependencies, feedback links, accessibility references, or includes source traces not intended for delivery. Platform gap fill
Generated delivery projection; QTI defines source XML, not this public JSON view.
ITD-006 JSON Projection Boundaries, ITD-015 Delivery Session Snapshots
qti.artifact_version.authoring_json Generated authoring projection for editors that must preserve all spec-defined fields. jsonb
Nullable
Lossy, missing extension payloads, missing source trace needed for edits, or used for delivery without declared lossiness. Platform gap fill
Generated authoring projection; QTI defines XML, not this editor JSON view.
ITD-006 JSON Projection Boundaries, ITD-011 Artifact Versioning
qti.artifact_version.spec_trace Generated traceability from classes, fields, and components to XSD/spec anchors. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, live-only references, or links that cannot be reproduced from the bundle. 1EdTech pass-through
Generated traceability to bundled XSD/spec sources.
ITD-001 Offline 1EdTech Source Bundle, ITD-007 Provenance Labels
qti.artifact_version.supersedes_version_id Previous version replaced by this version, when the save was an edit or replacement. uuid
Nullable
Points forward in time, points to another artifact without explicit migration evidence, or creates a cycle. Platform gap fill
Platform version history link.
ITD-011 Artifact Versioning
qti.artifact_version.created_at Timestamp when this immutable version was created. timestamptz
Required, default now()
Null or mutated to reorder version history. Platform gap fill
Version audit metadata.
ITD-022 Operational DDL Discipline
qti.artifact_version.created_by Principal or system actor that created the version. text
Nullable
Raw access token, raw JWT subject that identifies a learner, email address, or other direct learner PII. Platform gap fill
Platform audit metadata.
ITD-019 Security Boundary, ITD-024 Candidate And Learner Data Privacy
qti.component.component_id Stable identifier for one generated object node row. uuid
Required
Not a UUID or reused. Platform gap fill
Platform row identity.
ITD-005 Lossless Relational Projection
qti.component.artifact_version_id Artifact version containing this component. uuid
Required
Missing version or cross-artifact projection. Platform gap fill
Projection belongs to immutable version.
ITD-005 Lossless Relational Projection, ITD-011 Artifact Versioning
qti.component.parent_component_id Parent object node, preserving the XML/object hierarchy. uuid
Nullable
Parent is in a different artifact_version, creates a cycle, or is missing for non-root nodes. Platform gap fill
Relational hierarchy projection.
ITD-005 Lossless Relational Projection
qti.component.ordinal Sibling order under parent_component_id. integer
Required
Null, negative by repository convention, duplicated among siblings without deterministic tie-break, or changed after hashing. Platform gap fill
Relational ordering needed for round trip.
ITD-005 Lossless Relational Projection, ITD-004 XML Authority And Canonical Hashes
qti.component.element_name XML element name generated from the bundled XSD index. text
Required
Unknown to the generated model, mismatched with qualified_name, or rewritten to an Alpha name. 1EdTech pass-through
QTI/XML element name from bundled XSD index.
ITD-002 Generated Object Model Hub, ITD-005 Lossless Relational Projection
qti.component.qualified_name Clark-notation qualified XML name used to preserve namespace identity. text
Nullable
Namespace does not match namespace_uri, prefix-only value loses URI, or generated from live schema outside the bundle. 1EdTech pass-through
Qualified XML name preserving namespace identity.
ITD-004 XML Authority And Canonical Hashes, ITD-005 Lossless Relational Projection
qti.component.namespace_uri Namespace URI for this XML component, if any. text
Nullable
Prefix instead of URI, wrong QTI namespace, or discarded for namespaced elements. 1EdTech pass-through
Namespace URI from QTI/XML content.
ITD-004 XML Authority And Canonical Hashes
qti.component.type_name Generated XSD type name for this object node. text
Nullable
Invented type, type from the wrong namespace, or inconsistent with element_name. 1EdTech pass-through
Generated XSD type name.
ITD-002 Generated Object Model Hub, ITD-005 Lossless Relational Projection
qti.component.qti_identifier QTI identifier attribute on this component when present. text
Nullable
Invented, coerced to UUID, or assumed globally unique across artifacts. 1EdTech pass-through
QTI identifier attribute.
ITD-004 XML Authority And Canonical Hashes, ITD-007 Provenance Labels
qti.component.component_path Stable generated path from the root object to this component. text
Required
Not stable across rehydration, duplicated, or encodes tenant/private data. Platform gap fill
Platform traceability and diff path.
ITD-005 Lossless Relational Projection
qti.component.attributes Raw generated attribute projection for fields not promoted to typed query tables. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, drops data-* extension attributes, or stores API auth headers. 1EdTech pass-through
Raw QTI/XML attributes not promoted to query columns.
ITD-004 XML Authority And Canonical Hashes, ITD-005 Lossless Relational Projection
qti.component.text_value Text node value for text-bearing QTI and embedded content nodes. text
Nullable
Dropped for mixed content, normalized in a way that changes semantics, or used to store learner responses. 1EdTech pass-through
Text node value from QTI or permitted embedded content.
ITD-004 XML Authority And Canonical Hashes, ITD-005 Lossless Relational Projection
qti.component.tail_value Tail text after this element, required for mixed-content XML round trips. text
Nullable
Dropped because it is inconvenient, moved into text_value incorrectly, or included in delivery_json without declared lossiness. 1EdTech pass-through
Mixed-content XML tail text needed for round trips.
ITD-004 XML Authority And Canonical Hashes, ITD-005 Lossless Relational Projection
qti.component.source_trace Generated trace to XSD and spec source for this component. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, live-only link, or not aligned with element_name/type_name. 1EdTech pass-through
Generated traceability to bundled XSD/spec sources.
ITD-001 Offline 1EdTech Source Bundle, ITD-007 Provenance Labels
qti.variable_declaration.variable_declaration_id Stable row identifier for one promoted variable declaration. uuid
Required
Not a UUID or reused. Platform gap fill
Platform projection row identity.
ITD-013 Variable Declaration Projection
qti.variable_declaration.artifact_version_id Artifact version that declares the variable. uuid
Required
Missing version or mismatch with component_id artifact_version. Platform gap fill
Variable projection belongs to immutable content version.
ITD-013 Variable Declaration Projection, ITD-011 Artifact Versioning
qti.variable_declaration.component_id Component node that declared this variable. uuid
Required
Component is not in the same artifact_version or is not a variable declaration node. Platform gap fill
Projection link back to object graph component.
ITD-005 Lossless Relational Projection, ITD-013 Variable Declaration Projection
qti.variable_declaration.variable_kind QTI variable category. text
Required
Outside enum set or used to invent a platform-only variable category. 1EdTech pass-through
QTI variable declaration category.
ITD-013 Variable Declaration Projection, ITD-007 Provenance Labels
qti.variable_declaration.identifier QTI variable identifier. text
Required
Blank, duplicated within kind/version, rewritten to UUID, or mismatched with processing operands. 1EdTech pass-through
QTI variable identifier value.
ITD-013 Variable Declaration Projection, ITD-004 XML Authority And Canonical Hashes
qti.variable_declaration.cardinality QTI cardinality for the variable value container. text
Nullable
Outside QTI cardinality vocabulary, inconsistent with associated interaction, or inconsistent with JSON value shape. 1EdTech pass-through
QTI cardinality value.
ITD-013 Variable Declaration Projection, ITD-021 Runtime Execution Profile
qti.variable_declaration.base_type QTI base-type for atomic values when the declaration has one. text
Nullable
Outside QTI base-type vocabulary, present for record in a way QTI forbids, or inconsistent with correct_response/default_value. 1EdTech pass-through
QTI base-type value.
ITD-013 Variable Declaration Projection, ITD-021 Runtime Execution Profile
qti.variable_declaration.default_value Generated object value for qti-default-value. jsonb
Nullable
Shape does not match cardinality/base_type, contains unvalidated extension payload, or is used as candidate response state. 1EdTech pass-through
Generated value for qti-default-value.
ITD-013 Variable Declaration Projection, ITD-004 XML Authority And Canonical Hashes
qti.variable_declaration.correct_response Generated object value for qti-correct-response. jsonb
Nullable
Correct response values are coerced, ordered values are stored as unordered, or value type conflicts with base_type. 1EdTech pass-through
Generated value for qti-correct-response.
ITD-013 Variable Declaration Projection, ITD-021 Runtime Execution Profile
qti.variable_declaration.mapping Generated mapping, areaMapping, matchTable, or interpolationTable detail. jsonb
Nullable
Drops default mapping value, loses area coordinates, changes scoring numeric precision, or omits source trace. 1EdTech pass-through
Generated QTI mapping/detail payload.
ITD-013 Variable Declaration Projection, ITD-021 Runtime Execution Profile
qti.variable_declaration.source_trace Generated trace to XSD and spec section for the variable declaration. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, or not tied to the declaring component. 1EdTech pass-through
Generated trace to XSD and spec section.
ITD-001 Offline 1EdTech Source Bundle, ITD-007 Provenance Labels
qti.processing_rule.processing_rule_id Stable row identifier for one promoted processing rule or expression node. uuid
Required
Not a UUID or reused. Platform gap fill
Platform projection row identity.
ITD-014 Processing Rule Projection
qti.processing_rule.artifact_version_id Artifact version containing the processing rule. uuid
Required
Missing version or mismatch with component_id artifact_version. Platform gap fill
Processing projection belongs to immutable content version.
ITD-014 Processing Rule Projection, ITD-011 Artifact Versioning
qti.processing_rule.component_id Component node backing this processing rule. uuid
Required
Component is not in the same artifact_version or is not a processing/expression node. Platform gap fill
Projection link back to generated component.
ITD-005 Lossless Relational Projection, ITD-014 Processing Rule Projection
qti.processing_rule.parent_processing_rule_id Parent processing rule for nested expression and rule trees. uuid
Nullable
Parent is in another artifact_version, creates a cycle, or changes execution semantics. Platform gap fill
Relational processing-tree hierarchy.
ITD-014 Processing Rule Projection
qti.processing_rule.rule_scope Processing scope used for query and execution grouping. text
Required
Outside enum set or used to claim QTI defines this SQL row scope. Platform gap fill
Repository classification for persisted processing rows.
ITD-014 Processing Rule Projection
qti.processing_rule.rule_name QTI processing rule or expression element/operator name. text
Required
Not a QTI processing/expression element, renamed for Alpha, or mismatched with component.element_name. 1EdTech pass-through
QTI processing rule or expression element name.
ITD-014 Processing Rule Projection, ITD-021 Runtime Execution Profile
qti.processing_rule.sequence_number Order within the parent processing scope. integer
Required
Null, order differs from object graph, or ties cause nondeterministic execution. Platform gap fill
Execution ordering aid.
ITD-014 Processing Rule Projection, ITD-021 Runtime Execution Profile
qti.processing_rule.operands Generated operand references and literal values for execution. jsonb
Required, default '[]'::jsonb
Null, non-array JSON, points to undeclared variables, loses numeric precision, or contains unredacted learner identity. 1EdTech pass-through
Generated QTI operand references and literal values.
ITD-014 Processing Rule Projection, ITD-021 Runtime Execution Profile
qti.processing_rule.source_trace Generated trace to XSD and spec section for this processing rule. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, or not tied to the rule_name/component. 1EdTech pass-through
Generated trace to XSD and spec section.
ITD-001 Offline 1EdTech Source Bundle, ITD-007 Provenance Labels
qti.delivery_session.delivery_session_id Stable session identifier exposed by delivery APIs. uuid
Required
Not a UUID, reused, or guessable outside API authorization. Platform gap fill
Platform delivery session identity.
ITD-015 Delivery Session Snapshots
qti.delivery_session.tenant_id Tenant boundary for the delivery session. uuid
Required
Does not match authenticated tenant claim or root artifact tenant. Platform gap fill
Tenant-scoped learner runtime boundary.
ITD-008 Tenant Boundary, ITD-015 Delivery Session Snapshots
qti.delivery_session.candidate_ref Opaque tenant-scoped pseudonymous UUID string for the candidate. text
Required
Contains direct learner or parent PII, raw JWT subject, auth token, SIS ID, or is not tenant-scoped. Platform gap fill
Platform learner privacy boundary. QTI_CONTEXT candidateIdentifier uses this value only when runtime context needs it.
ITD-024 Candidate And Learner Data Privacy, ITD-019 Security Boundary
qti.delivery_session.root_artifact_version_id Immutable item, test, or section version delivered in this session. uuid
Required
Missing version, version not owned by tenant, or changed after session start. Platform gap fill
Session pins immutable content version.
ITD-015 Delivery Session Snapshots, ITD-011 Artifact Versioning
qti.delivery_session.status Session lifecycle state. text
Required, default 'created'
Outside enum set or inconsistent with attempts, submitted_at, or review workflow. Platform gap fill
Platform delivery lifecycle.
ITD-015 Delivery Session Snapshots
qti.delivery_session.delivery_json_snapshot Snapshot of delivery_json at session start. jsonb
Required
Null, mismatched to root_artifact_version_id at start, mutated after attempts, or contains authoring-only trace without declared lossiness. Platform gap fill
Generated delivery projection snapshot for historical stability.
ITD-006 JSON Projection Boundaries, ITD-015 Delivery Session Snapshots
qti.delivery_session.session_state Runtime state not modeled as QTI variables, such as navigation, item sequencing, resume information, or review flags. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, auth headers, raw PNP records, direct learner identity, or state that contradicts delivery_json_snapshot. Platform gap fill
Platform runtime state outside QTI variable declarations.
ITD-015 Delivery Session Snapshots, ITD-024 Candidate And Learner Data Privacy
qti.delivery_session.created_at Session creation timestamp. timestamptz
Required, default now()
Null or later than updated_at. Platform gap fill
Runtime audit metadata.
ITD-022 Operational DDL Discipline
qti.delivery_session.updated_at Last session state mutation timestamp. timestamptz
Required, default now()
Null, earlier than created_at, or stale after status/session_state update. Platform gap fill
Runtime audit metadata.
ITD-022 Operational DDL Discipline
qti.attempt.attempt_id Stable identifier for one attempt record. uuid
Required
Not a UUID or reused. Platform gap fill
Platform attempt identity.
ITD-016 Attempt State And Processing Trace
qti.attempt.delivery_session_id Owning delivery session. uuid
Required
Missing session or tenant mismatch through session. Platform gap fill
Attempt belongs to learner runtime session.
ITD-015 Delivery Session Snapshots, ITD-016 Attempt State And Processing Trace
qti.attempt.artifact_version_id Immutable item/test artifact version attempted. uuid
Required
Does not belong to the delivery session snapshot or changes after processing. Platform gap fill
Attempt pins content version for reproducible processing.
ITD-011 Artifact Versioning, ITD-016 Attempt State And Processing Trace
qti.attempt.attempt_number Attempt count within a session and artifact version. integer
Required
Zero or negative by convention, duplicated, or reused after an adaptive attempt changes state. Platform gap fill
Platform attempt sequencing.
ITD-016 Attempt State And Processing Trace
qti.attempt.status Attempt lifecycle state. text
Required, default 'active'
Outside enum set or inconsistent with suspended_at/submitted_at. Platform gap fill
Platform attempt lifecycle.
ITD-016 Attempt State And Processing Trace
qti.attempt.response_state Candidate response variables at the last processing point. jsonb
Required, default '{}'::jsonb
Null, values inconsistent with qti.variable_declaration, unnecessary learner PII copied from outside the response, or logged without redaction. 1EdTech pass-through
QTI response variable state bound to learner runtime.
ITD-016 Attempt State And Processing Trace, ITD-024 Candidate And Learner Data Privacy
qti.attempt.template_state Template variables used for item cloning and stability. jsonb
Required, default '{}'::jsonb
Null, regenerated on read instead of persisted, inconsistent with template processing trace, or logged with learner identity. 1EdTech pass-through
QTI template variable state bound to session stability.
ITD-016 Attempt State And Processing Trace, ITD-021 Runtime Execution Profile, ITD-024 Candidate And Learner Data Privacy
qti.attempt.outcome_state Outcome variables after template, response, and outcome processing. jsonb
Required, default '{}'::jsonb
Null, cannot be reproduced by processing rules under the runtime profile, or includes unsupported outcomes without diagnostics. 1EdTech pass-through
QTI outcome variable state.
ITD-016 Attempt State And Processing Trace, ITD-021 Runtime Execution Profile, ITD-024 Candidate And Learner Data Privacy
qti.attempt.processing_trace Deterministic trace of template, response, and outcome processing operations. jsonb
Required, default '[]'::jsonb
Null, non-array JSON, nondeterministic, lacks failed-closed diagnostics for unsupported operators, or contains auth/PII data. Platform gap fill
Implementation trace of QTI processing execution; QTI defines processing semantics, not this stored audit trail.
ITD-016 Attempt State And Processing Trace, ITD-021 Runtime Execution Profile, ITD-024 Candidate And Learner Data Privacy
qti.attempt.started_at Attempt start timestamp. timestamptz
Required, default now()
Null or after submitted_at. Platform gap fill
Runtime audit metadata.
ITD-022 Operational DDL Discipline
qti.attempt.suspended_at Attempt suspension timestamp, if the attempt was suspended. timestamptz
Nullable
Set while status never suspended without lifecycle evidence, before started_at, or after submitted_at. Platform gap fill
Runtime lifecycle audit metadata.
ITD-016 Attempt State And Processing Trace
qti.attempt.submitted_at Attempt submission timestamp, if the attempt was submitted. timestamptz
Nullable
Before started_at, set while status remains active without evidence, or absent for submitted/reviewed attempts. Platform gap fill
Runtime lifecycle audit metadata.
ITD-016 Attempt State And Processing Trace
qti.conformance_run.conformance_run_id Stable identifier for one conformance run. uuid
Required
Not a UUID or reused. Platform gap fill
Platform evidence row identity.
ITD-017 Conformance Evidence
qti.conformance_run.profile Targeted QTI 3.0 conformance profile or optional feature set. text
Required
Unsupported profile, Alpha-only label, or profile not represented by assertions. Platform gap fill
Platform conformance profile label tied to the QTI bundle.
ITD-017 Conformance Evidence, ITD-001 Offline 1EdTech Source Bundle
qti.conformance_run.bundle_hash Hash of the offline spec bundle used by the run. text
Required
Missing, live network URL, or not reproducible from the bundle used. Platform gap fill
Release evidence ties to immutable local source bundle.
ITD-001 Offline 1EdTech Source Bundle, ITD-017 Conformance Evidence
qti.conformance_run.runner_version Version or identity of the conformance runner. text
Required
Blank, vague, or points to unpinned code. Platform gap fill
Release evidence metadata.
ITD-017 Conformance Evidence
qti.conformance_run.started_at Run start timestamp. timestamptz
Required, default now()
Null or after finished_at. Platform gap fill
Conformance audit metadata.
ITD-022 Operational DDL Discipline
qti.conformance_run.finished_at Run finish timestamp, if complete. timestamptz
Nullable
Before started_at, absent for completed terminal status without explanation, or set while still running. Platform gap fill
Conformance lifecycle audit metadata.
ITD-017 Conformance Evidence
qti.conformance_run.status Run lifecycle status. text
Required, default 'running'
Outside enum set or inconsistent with child assertion statuses. Platform gap fill
Release evidence lifecycle.
ITD-017 Conformance Evidence
qti.conformance_run.summary Generated coverage and pass/fail summary. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, contradicts assertion rows, or includes raw package bytes/secrets. Platform gap fill
Generated release-gate summary.
ITD-017 Conformance Evidence
qti.conformance_assertion.conformance_assertion_id Stable identifier for one assertion result. uuid
Required
Not a UUID or reused. Platform gap fill
Platform assertion row identity.
ITD-017 Conformance Evidence
qti.conformance_assertion.conformance_run_id Owning conformance run. uuid
Required
Missing parent run or status contradicts parent run summary. Platform gap fill
Assertion belongs to release evidence run.
ITD-017 Conformance Evidence
qti.conformance_assertion.assertion_key Stable key generated by the conformance runner for this assertion. text
Required
Duplicated in a run, nondeterministic across reruns, or so vague it cannot locate the assertion. Platform gap fill
Generated assertion identity.
ITD-017 Conformance Evidence
qti.conformance_assertion.artifact_ref Example, fixture, or artifact path covered by this assertion. text
Nullable
Live-only URL, missing fixture, or reference to learner-runtime data. 1EdTech pass-through
QTI example or artifact reference covered by conformance evidence.
ITD-001 Offline 1EdTech Source Bundle, ITD-017 Conformance Evidence
qti.conformance_assertion.spec_ref Spec section, schema component, or generated trace reference covered by this assertion. text
Nullable
Points only to live network docs, wrong schema file, or cannot be followed by a future generator. 1EdTech pass-through
1EdTech spec, schema, or generated traceability reference.
ITD-001 Offline 1EdTech Source Bundle, ITD-007 Provenance Labels, ITD-017 Conformance Evidence
qti.conformance_assertion.status Assertion result status. text
Required
Outside enum set, contradicts details, or failed/error without diagnostics. Platform gap fill
Generated assertion result lifecycle.
ITD-017 Conformance Evidence
qti.conformance_assertion.details Assertion diagnostics, canonical hashes, processing outcomes, and failure details. jsonb
Required, default '{}'::jsonb
Null, non-object JSON, missing diagnostics for failure, or contains auth/PII data. Platform gap fill
Generated release-gate diagnostics; QTI defines conformance expectations, not this evidence payload.
ITD-017 Conformance Evidence, ITD-024 Candidate And Learner Data Privacy
Allowed values

Allowed values with behavioral meaning

Each value is constrained by the dictionary and linked to the decision that explains whether it is a 1EdTech pass-through or a platform gap fill.

Package import status

qti.content_package.import_status content_package_import_status_ck

Platform gap fill

Package lifecycle values are defined by the platform ingest workflow. QTI defines package content, not import job state. ITD-009 Package Resource And File Ingest, ITD-010 Idempotency And Hashes.

ValueBehavior
importingThe package row has been created and validation or resource extraction is still in progress. Do not deliver artifacts from this package yet.
importedValidation, resource extraction, artifact creation, and version projection succeeded. The package can be queried, delivered, and exported.
rejectedValidation, package-closure checks, XSD/Schematron validation, or privacy validation failed. Keep diagnostics in metadata; do not create deliverable sessions from this package.
supersededA later package or version replaces this import for operational use while preserving this row for audit and reproducibility.

IMS/QTI package resource type

qti.package_resource.resource_type IMS content-package resource type vocabulary

1EdTech pass-through

Resource type strings are copied from IMS/QTI content-package manifests and the bundled QTI ASI XML Binding package vocabulary. ITD-009 Package Resource And File Ingest, ITD-007 Provenance Labels.

ValueBehavior
imsqti_test_xmlv3p0A QTI assessment test XML resource. The primary href should point to a test XML document.
imsqti_section_xmlv3p0A QTI assessment section XML resource. Use for sections managed independently from a test.
imsqti_item_xmlv3p0A QTI assessment item XML resource. Use for a candidate-facing item with interactions and response processing.
imsqti_resprocessing_xmlv3p0A QTI response-processing XML resource when response processing is represented as a separate package resource.
imsqti_outcomes_xmlv3p0A QTI outcome-declaration XML resource, often used when outcomes are managed independently.
imsqti_stimulus_xmlv3p0A QTI assessment stimulus XML resource that items can depend on for shared passage or stimulus content.
imsqti_fragment_xmlv3p0A managed QTI fragment resource used by item, section, or test content.
imsqti_rptemplate_xmlv3p0A response-processing template XML resource, including standard or custom templates packaged with items.
associatedcontent/learning-application-resourceA learning-application asset referenced by QTI content.
webcontentGeneric web content asset, such as image, video, audio, HTML, or other supporting media.
imsbasiclti_xmlv1p3An LTI tool resource referenced by packaged content.
controlfileA manifest control file or package control artifact.
resourcemetadata/xmlMetadata XML associated with a package resource.
resourceextmetadata/xmlExternal metadata XML associated with a package resource.
qtiusagedata/xmlA QTI usage-data XML resource carrying item or distractor statistics.
plsPronunciation lexicon resource used by speech or accessibility presentation.
css2CSS 2 stylesheet resource.
css3CSS 3 stylesheet resource.
extensionAn extension resource. Preserve and export it, but do not treat it as a known QTI root without validation evidence.

Artifact kind

qti.artifact.artifact_kind artifact_kind_ck

Platform gap fill

Repository categories are derived from QTI root elements and package resources so APIs can route artifacts without renaming QTI concepts. ITD-011 Artifact Versioning, ITD-012 Artifact Kind Allowed Values.

ValueBehavior
itemLogical artifact whose root is a QTI assessment item.
testLogical artifact whose root is a QTI assessment test.
sectionLogical artifact whose root is a QTI assessment section.
stimulusLogical artifact whose root is a QTI assessment stimulus.
outcome-declarationLogical artifact whose root is a standalone QTI outcome declaration.
response-processingLogical artifact whose root is standalone QTI response processing or a response-processing template.
resultLogical artifact whose root is a QTI assessment result report.
usage-dataLogical artifact whose root is QTI usage data.
metadataLogical artifact for QTI or resource metadata XML.
manifest-resourceManifest-only resource that must remain addressable even when it is not a QTI root document.

Variable declaration kind

qti.variable_declaration.variable_kind variable_kind_ck

1EdTech pass-through

Values mirror QTI variable declaration categories: response, outcome, template, and context. ITD-013 Variable Declaration Projection, ITD-007 Provenance Labels.

ValueBehavior
responseCandidate response variable declared by QTI and usually bound to an interaction.
outcomeScoring, feedback, or reporting variable set by default values or processing rules.
templateTemplate variable used to instantiate or clone a parameterized item.
contextContextual variable available to template or response processing, including candidate, test, or system context when declared.

Processing rule scope

qti.processing_rule.rule_scope processing_rule_scope_ck

Platform gap fill

The row scope is a repository classification for query and execution order; QTI defines the processing elements and expressions themselves. ITD-014 Processing Rule Projection, ITD-021 Runtime Execution Profile.

ValueBehavior
responseRule belongs to response processing and computes outcome variables from candidate responses.
outcomeRule belongs to outcome processing at test or section level.
templateRule belongs to template processing and initializes template state before delivery.
expressionRow represents an expression subtree or operator nested inside response, outcome, or template processing.

Delivery session status

qti.delivery_session.status delivery_session_status_ck

Platform gap fill

Delivery lifecycle states are platform persistence behavior. QTI defines item/test content and processing, not this session state machine. ITD-015 Delivery Session Snapshots, ITD-024 Candidate And Learner Data Privacy.

ValueBehavior
createdSession exists and has a delivery JSON snapshot but has not yet become the active learner experience.
activeCandidate may interact with delivered content and create or update attempts.
suspendedCandidate work is paused and may be resumed with the same snapshot and session state.
submittedCandidate has submitted the session; scoring and attempt records are complete enough for review.
reviewSession is in review mode. Content and responses may be displayed, but interactions must not change response variables.
closedSession is final for normal operations. Future edits to content do not affect it.
voidedSession is retained as an operational record but should not count toward reporting or outcomes.

Attempt status

qti.attempt.status attempt_status_ck

Platform gap fill

Attempt lifecycle states are platform persistence behavior around QTI response processing. ITD-016 Attempt State And Processing Trace, ITD-024 Candidate And Learner Data Privacy.

ValueBehavior
activeCandidate can still modify responses for this attempt.
suspendedCandidate response state is saved for later continuation.
submittedCandidate submitted responses and processing has produced outcome state.
reviewedAttempt has been reviewed by an authorized person or workflow.
voidedAttempt is retained for audit but excluded from reporting and outcomes.

Conformance run status

qti.conformance_run.status conformance_run_status_ck

Platform gap fill

Release-evidence lifecycle values are platform gap fills. ITD-017 Conformance Evidence.

ValueBehavior
runningThe conformance runner has started and assertions are not yet complete.
passedAll required assertions for the targeted profile passed.
failedAt least one required assertion failed.
errorThe runner could not complete because of tool, environment, or infrastructure failure.

Conformance assertion status

qti.conformance_assertion.status conformance_assertion_status_ck

Platform gap fill

Per-assertion lifecycle values are generated evidence about implementation behavior, not QTI content. ITD-017 Conformance Evidence.

ValueBehavior
passedThis assertion met the expected result.
failedThis assertion ran and found behavior that violates the target profile or platform contract.
skippedThis assertion was intentionally not run, usually because it is out of profile or unavailable in the current runner.
errorThis assertion could not produce a valid pass/fail result because the runner or fixture failed.

JSON projection lossiness

API projection metadata OpenAPI projection contract

Platform gap fill

The platform names JSON projection lossiness because QTI defines XML, not public JSON projection envelopes. ITD-006 JSON Projection Boundaries, ITD-018 API Boundary.

ValueBehavior
noneThe projection must preserve all spec-defined fields needed to reconstruct the generated object graph and canonical XML.
declaredThe projection may omit only explicitly documented authoring-only or diagnostic detail, such as source trace or mixed-content tail detail.
Validation, runtime, privacy

Rules that protect QTI fidelity and learners

Runtime

  • Template, response, and outcome variables are initialized from generated QTI declarations.
  • All 87 XSD-reachable inline processing elements are covered by runtime assertions, and all 6 bundled templates are supported.
  • Unsupported future features fail closed with trace evidence rather than disappearing. qti.attempt.processing_trace.
  • Attempts remain stable because they reference immutable artifact versions and retain response, template, outcome, and trace snapshots.

Privacy

  • qti.delivery_session.candidate_ref must be an opaque tenant-scoped pseudonymous UUID string.
  • Direct names, emails, phone numbers, SIS IDs, raw JWT subjects, access tokens, raw PNP records, IP addresses, and user agents are forbidden in learner-runtime state and traces.
  • The deletion contract removes delivery sessions and cascading attempts for one candidate_ref while preserving reusable content.
  • When QTI_CONTEXT candidateIdentifier is needed at runtime, it receives candidate_ref, not direct learner identity.
Evidence

Conformance and release evidence

The website summarizes generated evidence and points to the persistence rows that make the evidence queryable after implementation.

EvidenceCurrent factsSourceTrace
Source bundle27 XSDs, 683 global elements, 842 complex types, 181 simple types, 2 VDEX vocabularies, 20 VDEX terms.external/qti/generated/spec/summary.mdOffline 1EdTech Source Bundle
Schema and round-trip corpus327 XML files classified; 311 schema checks and 311 round-trip schema checks passed for the in-profile corpus.external/qti/generated/conformance-full/conformance-report.mdConformance Evidence, Validation And Rejection Policy
Processing runtime87 XSD-reachable processing elements; 87 runtime-supported inline elements; 6 bundled templates supported.external/qti/generated/conformance/processing-coverage.mdRuntime Execution Profile, Conformance Evidence
Release evidence tablesConformance runs and assertions persist profile, bundle hash, runner version, status, assertion keys, artifact/spec references, and diagnostics.qti.conformance_run and qti.conformance_assertionConformance Evidence
Implementation input

What the next deliverable must implement

The implementation deliverable should be derived from this website, the approved architecture, and the approved data dictionary. It should not invent missing behavior during coding.

Package ingest

Accept ZIP/package input, validate closure and XML, persist package/resource/file/artifact/version/component rows, and reject invalid import_status values.

Projection and export

Generate lossless authoring JSON, declared-lossiness delivery JSON, canonical XML export, and reproducible XML hashes.

Tenant and auth

Require tenant-scoped reads/writes and Bearer JWT tenant-claim matching for tenant-owned routes.

Delivery and attempts

Snapshot delivery JSON, execute QTI processing against immutable versions, persist response/template/outcome/trace state.

Privacy deletion

Enforce pseudonymous candidate_ref, redact trace/runtime state, and implement candidate runtime-data deletion.

Conformance

Persist conformance run/assertion evidence and keep profile diagnostics separate from QTI schema restrictions.

Source trail

Inputs used to generate this website

This platform3 deliverable is derived from the approved upstream architecture and data dictionary. external/qti was used as reference material only.

Benchmarks considered

  • Stripe API reference for top-level authentication/errors references, resource-oriented endpoint clarity, and inline request/response specificity.
  • Algolia docs for navigation, search, and information scent.
  • loop/context/benchmarks/index.json now records Stripe as the customer_website benchmark; no local customer_website.html snapshot was present in this workspace.
external/qti files read
  • external/qti/ARCHITECTURE.md
  • external/qti/docs/plain-english-guide.md
  • external/qti/docs/1edtech-qti-package.md
  • external/qti/docs/qti-3-relational-json-architecture.md
  • external/qti/docs/conversion-contract.md
  • external/qti/docs/runtime-semantics.md
  • external/qti/docs/conformance-and-documentation.md
  • external/qti/docs/qti-3-documentation-source-audit.md
  • external/qti/docs/adr/0001-generated-object-model.md
  • external/qti/docs/adr/0002-postgresql-primary.md
  • external/qti/docs/adr/0003-json-projections.md
  • external/qti/docs/adr/0004-session-snapshotting.md
  • external/qti/docs/adr/0005-data-dictionary-provenance.md
  • external/qti/docs/adr/0006-tenant-boundary.md
  • external/qti/docs/adr/0007-package-resource-ingest.md
  • external/qti/docs/adr/0008-artifact-versioning-idempotency.md
  • external/qti/docs/adr/0009-attempt-processing-trace.md
  • external/qti/docs/adr/0010-conformance-evidence.md
  • external/qti/docs/adr/0011-api-boundary-auth-hosting.md
  • external/qti/contracts/qti-boundary.openapi.yaml
  • external/qti/generated/spec/summary.md
  • external/qti/generated/conformance-full/conformance-report.md
  • external/qti/generated/conformance/processing-coverage.md
  • external/qti/spec_bundle/MANIFEST.md
  • external/qti/spec_bundle/README.md
  • external/qti/site/index.html