AlphaTest · mastery_engine · integrator_api

Every mastery field, with its owner attached

A cold integrator’s field-level contract for a stateless adaptive run: Content identity and the immutable QTI pool root are bound; start and simulation remain absent until QTI can resolve every pool member version with CASE/KC attribution. Once that owner seam opens, deliver the native Platform3 QTI item session, advance with an encrypted continuation, and read explicit KC gaps plus a mastery-scale result—without creating a second learner record.

Start here

Who

AcmeTest maintainer

Use Platform3 Content, QTI, CASE, and Results identifiers directly. The adaptive composition is resumed with an opaque continuation token—not an AlphaTest run ID.

What persists

Configuration + retry control

AlphaTest’s engine store contains immutable selection policy and scale calibration records plus a 24-hour, payload-free idempotency control record. QTI, CASE, Content, Results, and Caliper retain every learner fact.

Reading this page

Required means required

Required fields must be present. “Conditional” names the exact condition. Omitted optional values are absent, not null, unless the row explicitly permits null.

Evolution

Unknown enums are possible

Clients must tolerate unknown response fields and enum values. A semantic break requires /v2. See ITD-020.

Do not send responses or tenant routing. Start/inspect/advance accept no item response, answer, score, item list, candidate ID, or tenant selector. Tenant comes only from the verified JWT; the QTI player submits responses to QTI and this engine rereads scored outcomes. Unknown or forbidden fields are rejected.
Release status — Bank receipt blocks architecture; the real journey blocks implementation. Content’s blueprint and zero-member adaptive-bank identity reads and QTI’s immutable root read are bound. The mandatory owner seam is bank.read_adaptive_pool_manifest: Bank’s terminal operation manifest must provide the complete package-bound native member-version plus CASE/KC projection, and Mastery independently reconciles it to QTI. Platform3 calls use a server-held provisioned service profile whose configured tenant must equal the verified client claim. Production learner completion additionally awaits results.write_kc_components. No caller item array, Content member row, generic artifact scan, forwarded client JWT, copied pool, or local KC store may substitute. See binding status, manifest r7, and ITD-028031.

Provenance legend

ENGINE AlphaTest immutable policy/calibration state or payload-free retry control PASS-THROUGH opaque identifier or fact owned upstream COMPOSED calculated in-memory from pinned configuration + upstream facts FORBIDDEN must not enter the engine store

Wire conventions

NameType / locationPresenceValidation and meaningDecision
Authorizationheader · stringEvery endpointBearer <JWT>. Signature, iss, aud, exp, sub, role, tenantId, and endpoint scope are verified. Tenant is never accepted elsewhere.ITD-008
Idempotency-Keyheader · stringEvery POST; required and non-null1–255 characters. Its operation scope is verified tenant + HTTP method + canonical path + server HMAC of this key. Inside that scope, reuse with the same canonical request hash resumes and recomposes semantically; reuse with a different canonical request hash returns 409 idempotency-key-reused before upstream work. The same key on another endpoint or for another verified tenant is a separate scoped operation.ITD-007
If-Matchheader · strong entity-tagAdvance onlyMust exactly equal the latest adaptive-run ETag. Weak tags and * do not identify the pinned response stream and are rejected.ITD-006
ETagresponse header · strong entity-tagStart, inspect, and advance successOpaque validator over token pins plus canonical token-named QTI attempts. Never parse it.ITD-006
Deprecationresponse header · Structured Field DateConditional: every response from a deprecated resourceRFC 9745 date in @<Unix-seconds> form announcing when that resource is or becomes deprecated. Its presence does not change response semantics. Treat it as a migration signal, continue handling the documented response, and consult the version-pinned docs; clients must not require this optional hint for correctness.ITD-020
Sunsetresponse header · HTTP-dateConditional: deprecated resource scheduled for removalRFC 8594 HTTP-date announcing when the resource is expected to stop responding. When both headers occur, Sunset must not precede Deprecation. Migrate before this instant; removal or a semantic change is exposed on /v2, never silently applied to /v1.ITD-020
identifierJSON stringPer fieldOpaque, case-sensitive, non-empty upstream or immutable-version identifier. Preserve exactly; percent-encode when used as one path segment. The owning upstream defines its maximum length.ITD-002, 020
probabilityJSON numberPer fieldFinite decimal in the closed interval [0,1]. Calculation uses the calibration’s pinned precision; JSON never contains NaN or Infinity.ITD-013
timestampJSON stringPer fieldRFC 3339 UTC instant. Calibration validity uses an inclusive validFrom and exclusive validUntil.ITD-017

Endpoint contract map

Method + pathScopeRequestAvailability / success contractNamed failures
POST /v1/adaptive-runsmastery:runStartAdaptiveRunRequest; Idempotency-KeyMANDATORY SHIP · 201 AdaptiveRun + strong ETag, profile, receipt ID, and first real QTI item session; reads the terminal Bank operation manifest and independently reconciles its pool to QTI400, 401, 403, hidden 404, 409 idempotency-key-reused/adaptive-pool-version-drift/stream-conflict, 422, 424 upstream-unavailable, 502 qti-adaptive-pool-invalid
POST /v1/adaptive-runs:inspectmastery:readContinuationRequest; Idempotency-Key200 AdaptiveRun + current strong ETag; rereads Content identity, QTI root/member projection/runtime, and CASE400, 401, 403, hidden 404, 409 idempotency-key-reused/adaptive-pool-version-drift/stream-conflict, 422, 424, 502 qti-adaptive-pool-invalid
POST /v1/adaptive-runs:advancemastery:runContinuationRequest; Idempotency-Key + If-Match200 AdaptiveRun + new strong ETag; consumes scored QTI attempt and may offer one next session400, 401, 403, hidden 404, 409 idempotency-key-reused/adaptive-pool-version-drift/stream-conflict, 412 stream-conflict, 422, 424, 428, 502 qti-adaptive-pool-invalid
GET /v1/selection-policies/{policyId}mastery:readExact path IDRELEASABLE CONFIG · 200 SelectionPolicy400, 401, 403, hidden 404
GET /v1/scale-calibrations/{calibrationId}mastery:readExact path IDRELEASABLE CONFIG · 200 ScaleCalibration400, 401, 403, hidden 404, 422 calibration-invalid
POST /v1/score-recovery-simulationsmastery:simulateSimulationRequest; Idempotency-KeyMANDATORY SHIP · 200 synchronous ScoreRecoverySimulation with a complete owner-conformance trace and acknowledged Caliper evidence400, 401, 403, hidden 404, 409 idempotency-key-reused/adaptive-pool-version-drift, 413 simulation-limit-exceeded, 422, 424 upstream-unavailable, 502 qti-adaptive-pool-invalid
Two release profiles: both select a server-held provisioned Platform3 service profile whose configured tenant equals the verified client claim. owner_conformance uses synthetic facts only and requires the complete Bank→QTI→CASE/anchor→Caliper trace. production_learner additionally requires Results acknowledgement of the record and one component per CASE GUID. A learner stays finalizing until Results and Caliper acknowledge; conformance completion explicitly has no learner Results write. Inspect the remaining owner contracts.
Endpoint omission is deliberate. There are no list, filter, sort, cursor, modifiedSince, webhook, or DELETE endpoints. Discover sessions in QTI/administration and results in Results. See ITD-004, ITD-005, and ITD-010.

Minimal TypeScript advance

const inspected = await fetch(`${baseUrl}/v1/adaptive-runs:inspect`, {
  method: "POST",
  headers: {Authorization: `Bearer ${jwt}`, "Content-Type": "application/json",
            "Idempotency-Key": crypto.randomUUID()},
  body: JSON.stringify({continuationToken})
});
if (!inspected.ok) throw await inspected.json() as ProblemDetails;
const current = await inspected.json() as AdaptiveRun;
const etag = inspected.headers.get("etag")!;

// Deliver current.offeredItem.deliverySessionId in the existing QTI player.
// After QTI has scored that attempt:
const advanced = await fetch(`${baseUrl}/v1/adaptive-runs:advance`, {
  method: "POST",
  headers: {Authorization: `Bearer ${jwt}`, "Content-Type": "application/json",
            "Idempotency-Key": crypto.randomUUID(), "If-Match": etag},
  body: JSON.stringify({continuationToken: current.continuationToken})
});
if (!advanced.ok) throw await advanced.json() as ProblemDetails;
const next = await advanced.json() as AdaptiveRun;

Request and response objects

StartAdaptiveRunRequest #

Body of POST /v1/adaptive-runs. Exactly seven top-level fields in production learner mode; resultsStudentId is omitted for owner conformance. bankOperationId names the terminal Bank operation whose immutable evidence manifest owns the native pool projection; callers never send a pool or member list.

FieldTypePresenceMeaning / validationOwner + provenance
selectionPolicyIdidentifierRequiredExact immutable policy version; mutable aliases such as “latest” are invalid.ENGINE ITD-016
scaleCalibrationIdidentifierRequiredExact immutable calibration version valid for the pool’s subject, grade coverage, and CASE framework.ENGINE ITD-017
testSpecIdidentifierRequiredPlatform3 Content test_spec ID. The engine calls the bound tenant-scoped blueprint read, requires assessment_role=spec, and hashes the complete normalized projection.CONTENT ITD-028, 024
testBankIdidentifierRequiredPlatform3 Content adaptive test_bank ID. Its bound identity read must match testSpecId, report membership_rule=qti_adaptive_selection, and return exactly zero Content members.CONTENT ITD-028
bankOperationIdidentifierRequiredExact terminal same-tenant Bank generation operation. The engine reads GET /v1/bank-operations/{operationId}/manifest, requires its package root and non-empty ordered native member/CASE/KC projection, and reconciles it exactly to the immutable QTI root. A non-terminal, mismatched, incomplete, or ambiguous manifest fails closed.BANK + QTI ITD-028
runModeenumRequiredowner_conformance or production_learner. Conformance is synthetic-only and creates no Results learner fact. Both modes use the server-selected provisioned Platform3 service profile; caller credentials are never forwarded.ENGINE ITD-030
resultsStudentIdidentifierRequired only when runMode=production_learner; otherwise forbiddenSame-tenant Platform3 Results student reference used only for final durable write-back. It is encrypted inside the continuation and never stored by AlphaTest.RESULTS ITD-001, 019
{
  "selectionPolicyId": "policy-g5-math-v3",
  "scaleCalibrationId": "cal-math-vertical-2026-01",
  "testSpecId": "spec-tx-g5-math",
  "testBankId": "bank-tx-g5-adaptive",
  "bankOperationId": "bankop-01J...",
  "runMode": "production_learner",
  "resultsStudentId": "student-01HR..."
}

ContinuationRequest #

The entire JSON body for POST /v1/adaptive-runs:inspect and POST /v1/adaptive-runs:advance. Unknown fields are rejected.

FieldTypePresenceMeaning / validationOwner + provenance
continuationTokencompact JWE stringRequired, non-nullOpaque, non-empty A256GCM authenticated-encrypted token returned by the preceding start/advance. Never parse, log, place in a URL, or persist in analytics. It expires 24 hours after issue, renews on a valid advance, and cannot outlive seven days from start. A token with unknown/retired kid, invalid authentication tag, expiry, or wrong tenant is rejected. The architecture pins no client-enforced byte limit.ENGINE ITD-002

ExecutionPins #

Read-only native identities and canonical hashes authenticated inside the continuation. Content owns blueprint/bank identity with zero adaptive members; Bank’s terminal evidence manifest projects generation provenance and the package-bound members; QTI owns the immutable package graph. All fields are present on every produced run.

FieldTypePresenceMeaning / validationOwner + provenance
testSpecIdidentifierAlwaysExact Content blueprint ID supplied at start.CONTENT ITD-028
testSpecHash64-char lowercase hexAlwaysSHA-256 of the complete normalized projection from bound content.read_test_spec. Later drift is 409 stream-conflict.COMPOSED ITD-016, 028
testBankIdidentifierAlwaysExact Content adaptive bank ID supplied at start.CONTENT ITD-028
testBankIdentityHash64-char lowercase hexAlwaysSHA-256 of the bound Content bank identity projection: bank/spec IDs, role, qti_adaptive_selection, zero-member invariant, and update version. It is not a membership hash.COMPOSED ITD-016, 028
bankOperationIdidentifierAlwaysExact terminal same-tenant Bank operation supplied at start; binds the immutable evidence manifest used for this run.BANK ITD-028
qtiPoolPackageIdidentifierAlwaysImmutable QTI package ID from the terminal Bank manifest root.BANK + QTI ITD-028
qtiPoolArtifactIdidentifierAlwaysNative QTI assessment-test artifact pin from the Bank manifest, independently cross-checked against QTI.BANK + QTI ITD-028
qtiPoolArtifactVersionIdidentifierAlwaysImmutable root version from the Bank manifest used for the independent QTI delivery-JSON read and member reconciliation.BANK + QTI ITD-028
qtiPoolPackageHash64-char lowercase hexAlwaysBank-manifest package hash; two reads of the terminal manifest must agree before selection.BANK ITD-028
qtiPoolEtagstrong entity-tagAlwaysETag returned for the exact immutable QTI root; any mismatch fails closed.QTI ITD-028
resolvedPoolHash64-char lowercase hexAlwaysSHA-256 over the Bank manifest root, QTI root version/ETag, and ordered reconciled tuples of member version, QTI identifier, canonical CASE GUIDs, and canonical KC GUIDs. A reread change is 409 adaptive-pool-version-drift.COMPOSED ITD-016, 028

AdaptiveRun #

Composed response. It is never persisted as an AlphaTest learner record. Arrays are bounded by the pinned Content spec/bank and policy; no pagination applies.

FieldTypePresenceMeaning / allowed valuesOwner + provenance
continuationTokencompact JWE stringAlwaysOpaque continuation for the next inspect/advance. A successful advance returns a renewed token; do not reuse its predecessor for a new semantic operation.ENGINE ITD-002
continuationExpiresAttimestampAlwaysExpiry of this returned token; at most 24 hours from issue and never beyond the run’s seven-day absolute lifetime.ENGINE ITD-002
statusenumAlwaysin_progress, finalizing, or completed. Unknown future values must be tolerated. Production completion requires QTI, Results components, and Caliper acknowledgement; conformance completion requires QTI and Caliper but forbids a learner Results write.COMPOSED ITD-019, 031
runModeenumAlwaysowner_conformance or production_learner; echoes the non-interchangeable execution profile. Upstream authentication is always selected server-side from the verified tenant.ENGINE ITD-030
selectionPolicyIdidentifierAlwaysExact immutable policy pin.ENGINE ITD-016
scaleCalibrationIdidentifierAlwaysExact immutable calibration pin.ENGINE ITD-016
executionPinsExecutionPinsAlwaysExact Content identity plus Bank-manifest and independently reconciled QTI pool/member pins authenticated inside the continuation and revalidated before every offer.COMPOSED ITD-016, 028
offeredItemOfferedItem or nullAlwaysExactly one currently offered item while one is outstanding; null during finalization/completion or before a valid offer.QTI ITD-015
kcClassificationsarray<KcClassification>AlwaysOne entry per in-scope KC, sorted by caseCompetencyGuid for deterministic representation; may be empty before evidence.COMPOSED ITD-014
scaleReportabilityenumAlwayspending, reportable, or anchor_unavailable. pending means the run has not reached a publishable scale result. anchor_unavailable explicitly marks every returned KC posterior/classification as provisional and non-reportable; clients may use it for recovery UI but must not publish it as a mastery result. Unknown future values must be treated as non-reportable.COMPOSED ITD-017
scaleScaleResult or nullAlwaysNon-null if and only if scaleReportability=reportable. It is null for pending and anchor_unavailable. Anchor failure never produces an unanchored fallback score; kcClassifications remain structurally unchanged but are provisional when reportability is anchor_unavailable.COMPOSED ITD-017
stopReasonenum or nullAlwaysNull while selection continues; otherwise classifications_complete, precision_target_met, max_items, or time_budget. Unknown future values must be tolerated.COMPOSED ITD-015
remainingUncertaintynumber ≥ 0AlwaysCalibration-defined aggregate posterior uncertainty, at pinned numeric precision. Meaning is identified by the calibration model family.COMPOSED ITD-013
resultRecordRefidentifierCompleted production_learner only; forbidden in conformanceAcknowledged Platform3 Results result_record reference, with every per-KC component acknowledged. Absent—not null—otherwise.RESULTS ITD-019
caliperEventRefidentifierCompleted onlyAcknowledged upstream Caliper completion-event reference. Absent before acknowledgement.CALIPER ITD-019
receiptIdidentifierEvery successful 200/201Opaque reference to the redacted replayable trace. The receipt records service-profile selection, approved hosts, Bank/QTI reconciliation, operation IDs, statuses, request IDs, native versions, fixture versions, response hashes, and tenant-isolation probe outcomes; it never contains credentials, learner IDs, responses, or scores.EVIDENCE ITD-031
HTTP/1.1 200 OK
ETag: "mrun-4f0c..."
Content-Type: application/json

{
  "continuationToken": "eyJraWQiOiJtZS0yMDI2LTA3IiwiZW5jIjoiQTI1NkdDTSJ9...",
  "continuationExpiresAt": "2026-07-16T15:30:00Z",
  "status": "in_progress",
  "runMode": "production_learner",
  "selectionPolicyId": "policy-g5-math-v3",
  "scaleCalibrationId": "cal-math-vertical-2026-01",
  "executionPins": {"testSpecId":"spec-tx-g5-math","testSpecHash":"a3...64 hex","testBankId":"bank-tx-g5-adaptive","testBankIdentityHash":"b4...64 hex","bankOperationId":"bankop-01J...","qtiPoolPackageId":"pkg-01J...","qtiPoolArtifactId":"qti-pool-g5-math","qtiPoolArtifactVersionId":"45bf...","qtiPoolPackageHash":"c5...64 hex","qtiPoolEtag":"\"pool-45bf\"","resolvedPoolHash":"d6...64 hex"},
  "offeredItem": {"deliverySessionId":"qti-session-7f23","artifactVersionId":"qti-artifact-v42","sequence":3},
  "kcClassifications": [{"caseCompetencyGuid":"case-guid-1","caseFrameworkGuid":"framework-guid","caseMappingVersion":"2026-06","classification":"not_yet","posteriorProbability":0.62,"evidenceItemRefs":["qti-artifact-v11"]}],
  "scaleReportability":"pending", "scale":null, "stopReason":null,
  "remainingUncertainty":0.38,
  "receiptId":"receipt-01K..."
}
Anchor-failure response rule. A valid pinned calibration whose anchor cannot be reverified after KC evidence exists may return 200 with scaleReportability=anchor_unavailable, scale=null, and provisional kcClassifications. A bad, expired, unlicensed, or checksum-invalid calibration is instead 422 calibration-invalid. If an unavailable dependency prevents the operation from safely computing even provisional KCs, the endpoint returns 424 upstream-unavailable and no AdaptiveRun body. ITD-017, ITD-018.

OfferedItem #

FieldTypePresenceMeaning / validationOwner + provenance
deliverySessionIdidentifierAlwaysNative same-tenant Platform3 QTI delivery-session ID for the selected immutable item. Pass it directly to the QTI player.QTI ITD-018
artifactVersionIdidentifierAlwaysImmutable QTI member version selected from the Bank-manifest projection after exact QTI-root reconciliation; must equal the QTI session’s rootArtifactVersionId.BANK + QTI ITD-028
sequenceinteger ≥ 1AlwaysOffer sequence in this adaptive composition. Canonical replay orders by this value, then QTI attemptNumber, then attemptId.COMPOSED ITD-016

No item body, answer key, candidate response, pseudonymous candidate ref, or locally generated delivery URL is returned. The existing QTI player delivers and scores this native session.

KcClassification #

FieldTypePresenceMeaning / allowed valuesOwner + provenance
caseCompetencyGuididentifierAlwaysLive CASE GUID for the knowledge component. AlphaTest does not invent a label or replacement ID.CASE ITD-014
caseFrameworkGuididentifierAlwaysOwning CASE framework GUID used to validate calibration compatibility.CASE ITD-014
caseMappingVersionidentifierAlwaysImmutable CASE/KC mapping version pinned for replay.CASE ITD-016
classificationenumAlwaysmastered, gap, or not_yet. not_yet means insufficient evidence, not failure.COMPOSED ITD-014
posteriorProbabilityprobabilityAlwaysPosterior probability of mastery under the pinned calibration—not a percentile or rank.COMPOSED ITD-013
evidenceItemRefsarray<identifier>AlwaysUnique QTI item IDs with scored outcomes contributing to this KC, sorted by canonical QTI sequence. Empty before evidence.QTI ITD-014

ScaleResult #

FieldTypePresenceMeaning / validationOwner + provenance
scaleScorefinite numberAlwaysMastery-scale score produced by the calibration’s monotonic vertical transform. It is RIT-like for crosswalk comparability, not an official NWEA RIT score.COMPOSED ITD-017
standardErrornumber ≥ 0AlwaysStandard error in the same scale units as scaleScore.COMPOSED ITD-017
scaleIdidentifierAlwaysStable identifier for the vertical mastery scale shared by compatible calibration versions. Compare scores only when this identifier and the documented validity/limitations permit it.ENGINE ITD-017
scaleCalibrationIdidentifierAlwaysExact immutable calibration that defines the score.ENGINE ITD-016, 017
anchorobjectAlways present, non-nullProvenance descriptor containing non-null source, version, 64-character lowercase SHA-256 checksum, and non-empty licenseScope. It contains metadata only, never licensed anchor payloads or rank data.ANCHOR ITD-017
validFromtimestampAlwaysInclusive beginning of the calibration validity interval used for this score.ENGINE ITD-017
validUntiltimestampAlwaysExclusive end of the calibration validity interval; strictly later than validFrom.ENGINE ITD-017
limitationsarray<string>AlwaysNon-empty plain-language limits of the crosswalk and permitted interpretation. Never contains percentile/rank claims.ENGINE ITD-017

SelectionPolicy #

Immutable engine-owned configuration. The GET representation contains no learner/session fields.

FieldTypePresenceMeaning / allowed valuesOwner + provenance
ididentifierAlwaysImmutable version identifier; never a mutable alias.ENGINE ITD-016
visibilityenumAlwaystenant or system. Tenant policy is visible only to its verified tenant; system policy is published for authorized platform tenants.ENGINE ITD-008
algorithmconstantAlwaysconstrained_information_gain for v1. Unknown future values must be tolerated on reads.ENGINE ITD-015
kcCutScoreprobabilityAlwaysMastery cut applied to each KC posterior.ENGINE ITD-014
confidenceThresholdprobabilityAlwaysMinimum posterior confidence required for mastered or gap; otherwise classification is not_yet.ENGINE ITD-014
precisionTargetnumber > 0AlwaysMaximum allowed aggregate posterior uncertainty for precision-based stopping, after coverage floors.ENGINE ITD-015
maxItemsinteger ≥ 1AlwaysHard maximum offered items.ENGINE ITD-015
timeBudgetSecondsinteger ≥ 1 or nullAlwaysHard elapsed-time budget; null disables only this stopping rule.ENGINE ITD-015
coverageFloorsarray<CoverageFloor>AlwaysEach entry has caseCompetencyGuid and integer minimumEvidenceItems ≥ 0. Unique by GUID; sorted by GUID.ENGINE + CASE ITD-015
eligibilityRulesobjectAlwaysPinned constraints for blueprint/CASE coverage, accessibility, exposure, prior use, and pool membership. Keys are versioned with the policy and interpreted by its runtime version.ENGINE ITD-015
checksumstringAlwaysLowercase hexadecimal SHA-256 of the canonical policy document (64 characters); supports replay comparison.ENGINE ITD-016

ScaleCalibration #

Immutable engine-owned configuration plus licensed-anchor provenance. Entitlement-filtered GET never exposes restricted anchor payloads.

FieldTypePresenceMeaning / validationOwner + provenance
ididentifierAlwaysImmutable calibration version identifier.ENGINE ITD-016
scaleIdidentifierAlwaysStable vertical-scale identifier. Multiple immutable calibration versions may share it only when their published validity and limitations preserve score comparability.ENGINE ITD-017
visibilityenumAlwaystenant or system; same authorization semantics as SelectionPolicy.ENGINE ITD-008
modelFamilystringAlwaysVersioned Bayesian estimator family. Client displays but does not interpret it.ENGINE ITD-013
modelVersionidentifierAlwaysImmutable model semantics/version.ENGINE ITD-013, 016
numericPrecisioninteger 1–15AlwaysDecimal significant-digit precision used by canonical numeric calculation and serialization.ENGINE ITD-016
runtimeVersionidentifierAlwaysExact deterministic calculation runtime.ENGINE ITD-016
caseFrameworkGuididentifierAlwaysCompatible CASE framework.CASE ITD-014
caseMappingVersionidentifierAlwaysPinned KC relationship/mapping version.CASE ITD-016
subjectstringAlwaysCanonical subject covered by the calibration; exact taxonomy comes from its anchor provenance.ANCHOR ITD-017
gradeCoveragearray<string>AlwaysNon-empty ordered grade labels supported by the anchor, including PK/college labels only when licensed and calibrated.ANCHOR ITD-017
validFromtimestampAlwaysBeginning of validity interval.ENGINE ITD-017
validUntiltimestampAlwaysExclusive end; must be later than validFrom.ENGINE ITD-017
anchorobjectAlways present, non-nullAlways contains non-null source, version, 64-character lowercase SHA-256 checksum, and licenseScope. licenseScope describes the provenance/entitlement scope and is never absent or null, including for callers not entitled to restricted anchor material. Restricted parameters and payloads themselves are omitted for unentitled callers; no omitted field is represented as null.ANCHOR ITD-017
recoveryTolerancenumber ≥ 0AlwaysMaximum absolute mastery-scale error accepted by the known-mastery simulation for this calibration.ENGINE ITD-021
limitationsarray<string>AlwaysNon-empty interpretation/crosswalk limitations. No percentile or rank claim.ENGINE ITD-017
checksumstringAlways64-char lowercase SHA-256 of the canonical, entitlement-independent calibration descriptor.ENGINE ITD-016
Deliberate abstraction: priors, item/KC parameters, and scale-transform coefficients are pinned in the stored calibration and used by the engine, but their vendor/licensed payload schema is not public here. The GET exposes provenance, compatibility, tolerance, and limitations—not an unlicensed model export. ITD-013, ITD-017.

SimulationRequest #

FieldTypePresenceMeaning / validationOwner + provenance
selectionPolicyIdidentifierRequiredExact immutable policy version.ENGINE ITD-016
scaleCalibrationIdidentifierRequiredExact immutable calibration version.ENGINE ITD-016, 017
testSpecIdidentifierRequiredPlatform3 Content blueprint used for every synthetic profile.CONTENT ITD-028
testBankIdidentifierRequiredPlatform3 Content adaptive-bank identity; must be associated with testSpecId, use qti_adaptive_selection, and contain exactly zero Content members.CONTENT ITD-028
bankOperationIdidentifierRequiredExact terminal same-tenant Bank operation whose manifest supplies the immutable package root and ordered native member/CASE/KC projection; the engine independently reconciles it to QTI before simulation.BANK + QTI ITD-028
profilesarray<SyntheticProfile>Required; 1–100Each profile has exactly a unique syntheticProfileId beginning synthetic: and a knownMastery object with 1–500 CASE-GUID keys mapped to probabilities. Real OneRoster, Results, or QTI candidate IDs are rejected.SYNTHETIC ITD-021

ScoreRecoverySimulation #

FieldTypePresenceMeaning / allowed valuesOwner + provenance
profilesTotalinteger ≥ 1AlwaysNumber of synthetic profiles accepted.COMPOSED ITD-021
recoveryErrorsarray<object>AlwaysExactly one per input profile, same order. Each has syntheticProfileId, finite knownScale, finite recoveredScale, and non-negative absoluteError. No learner identity.COMPOSED ITD-021
tolerancenumber ≥ 0AlwaysExact recoveryTolerance from the pinned calibration.ENGINE ITD-021
maxAbsoluteErrornumber ≥ 0AlwaysMaximum absoluteError across the returned matrix.COMPOSED ITD-021
withinTolerancebooleanAlwaysTrue iff every recovery error is ≤ tolerance.COMPOSED ITD-021
executionPinsExecutionPinsAlwaysContent identity plus Bank-manifest and reconciled QTI immutable root/member/KC hashes used for this deterministic matrix.COMPOSED ITD-016, 028
receiptIdidentifierAlwaysOpaque reference to the complete redacted and replayable owner_conformance trace.EVIDENCE ITD-031
eventIriabsolute IRI stringAlwaysRead-back-acknowledged Caliper conformance event; synthetic and non-learner.CALIPER ITD-021
envelopeHash64-char lowercase hexAlwaysSHA-256 of the acknowledged Caliper envelope; the immutable evidence receipt.CALIPER ITD-021

ProblemDetails #

Content-Type: application/problem+json, following RFC 9457. Raw upstream response bodies are never copied.

FieldTypePresenceMeaning / validationProvenance
typeabsolute URI stringAlwaysStable documentation URI identifying the problem class.ITD-009
titlestringAlwaysShort, stable human summary; do not branch program logic on it.RFC 9457
statusinteger 400–599AlwaysMatches HTTP status.RFC 9457
detailstringAlwaysOccurrence-specific, redacted explanation.RFC 9457
instanceURI-reference stringAlwaysOpaque occurrence reference; contains no learner identifier.RFC 9457 + ITD-012
codekebab-case stringAlwaysStable machine code from the error catalog.ITD-009
requestIdidentifierAlwaysRedacted correlation reference subject to operational-log expiry.ITD-012
retryablebooleanAlwaysWhether the operation can succeed after the catalog’s stated recovery action, without changing business inputs. Key handling is code-specific: reuse the same key only for a transport/dependency retry of the same request; after a 412 stream-conflict, refetch and reconcile, then send the new If-Match with a fresh key because that is a new semantic advance.ITD-022
invalidParamsarray<object>Validation onlyEach entry: JSON Pointer name, stable reason, and message. Never echoes submitted values.ITD-009
currentEtagstrong entity-tag412 onlyLatest validator to use after refetch/reconciliation.ITD-006
upstreamobjectDependency error onlyservice enum (platform3_auth, bank, content, qti, case, results, caliper, anchor) plus redacted operation and optional upstream requestId when a call was actually made. A pre-call profile mismatch has no upstream request ID. No host credential, token, payload, or learner data is exposed.ITD-018, 030
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json

{"type":"https://alphatest.example/problems/stream-conflict","title":"Adaptive stream changed","status":412,"detail":"Inspect the run before advancing again.","instance":"urn:request:01J...","code":"stream-conflict","requestId":"01J...","retryable":true,"currentEtag":"\"mrun-5a21...\""}

Engine-store dictionary

Security model: authenticated API in front of server-only storage. Browser clients receive no database key. Every read is authorized from the verified JWT, tenant policies are scoped by that claim, system records are explicitly published, and no table below has a candidate/session/response/result column.

These are the only logical AlphaTest mastery-engine tables: two immutable append-only configuration registries and one short-lived, payload-free idempotency control table. Configuration creation/publishing is an internal calibrated release process—not a public v1 endpoint. Physical migration names may add a schema prefix but may not alter these field contracts.

selection_policies #

Owner: mastery_engine. Primary key policy_id. No updates/deletes through the integrator API.

ColumnSQL typeNullabilityConstraint / meaningAPI mapping
policy_idtextNOT NULLPK; non-empty immutable version ID.SelectionPolicy.id
tenant_idtextNULLNull iff visibility='system'; otherwise verified tenant owner. Never accepted from request body.Authorization only; not exposed
visibilitytextNOT NULLCHECK in (tenant, system).visibility
algorithmtextNOT NULLv1 CHECK constrained_information_gain.algorithm
kc_cut_scorenumericNOT NULLCHECK 0…1.kcCutScore
confidence_thresholdnumericNOT NULLCHECK 0…1.confidenceThreshold
precision_targetnumericNOT NULLCHECK > 0.precisionTarget
max_itemsintegerNOT NULLCHECK ≥ 1.maxItems
time_budget_secondsintegerNULLCHECK ≥ 1 when present.timeBudgetSeconds
coverage_floorsjsonbNOT NULLCanonical array matching CoverageFloor; default []; unique/sorted GUIDs validated before insert.coverageFloors
eligibility_rulesjsonbNOT NULLCanonical versioned rule document; object, not null.eligibilityRules
checksum_sha256char(64)NOT NULLUNIQUE; CHECK lowercase hex.checksum
published_attimestamptzNOT NULLRelease audit metadata; not learner activity.Not exposed in v1

Indexes: PK (policy_id); UNIQUE (checksum_sha256); partial lookup (tenant_id, policy_id) WHERE visibility = 'tenant'. FKs: none—CASE/Content/QTI references are deliberately not copied into policy rows. Mutation: INSERT-only; DB trigger rejects UPDATE. A corrected policy receives a new ID.

scale_calibrations #

Owner: mastery_engine. Primary key calibration_id. Restricted parameter documents remain server-only and entitlement-controlled.

ColumnSQL typeNullabilityConstraint / meaningAPI mapping
calibration_idtextNOT NULLPK; non-empty immutable version ID.ScaleCalibration.id
scale_idtextNOT NULLNon-empty stable vertical-scale identifier; changing scale semantics requires a new value.ScaleCalibration.scaleId and ScaleResult.scaleId
tenant_idtextNULLNull iff system visibility; verified tenant otherwise.Authorization only
visibilitytextNOT NULLCHECK in (tenant, system).visibility
model_familytextNOT NULLNon-empty Bayesian estimator family.modelFamily
model_versiontextNOT NULLImmutable model semantics.modelVersion
model_parametersjsonbNOT NULLServer-only priors + item/KC parameters + monotonic scale transform. Canonical, validated against model version; never returned wholesale.Not exposed
numeric_precisionsmallintNOT NULLCHECK 1…15.numericPrecision
runtime_versiontextNOT NULLExact deterministic runtime version.runtimeVersion
case_framework_guidtextNOT NULLOpaque CASE GUID; validated live when used.caseFrameworkGuid
case_mapping_versiontextNOT NULLImmutable mapping pin.caseMappingVersion
subjecttextNOT NULLNon-empty anchor taxonomy value.subject
grade_coveragejsonbNOT NULLCanonical non-empty unique string array.gradeCoverage
valid_fromtimestamptzNOT NULLInclusive validity start.validFrom
valid_untiltimestamptzNOT NULLExclusive validity end; CHECK later than start.validUntil
anchor_sourcetextNOT NULLLicensed source descriptor.anchor.source
anchor_versiontextNOT NULLExact immutable licensed anchor version.anchor.version
anchor_checksum_sha256char(64)NOT NULLLowercase hex; verified before score publication.anchor.checksum
license_scopetextNOT NULL · non-emptyProvenance/entitlement scope; never treated as endorsement. This metadata is not the restricted anchor parameter or payload.Always exposed as non-null anchor.licenseScope; restricted anchor material is omitted when the caller lacks entitlement
recovery_tolerancenumericNOT NULLCHECK ≥ 0.recoveryTolerance
limitationsjsonbNOT NULLCanonical non-empty string array.limitations
checksum_sha256char(64)NOT NULLUNIQUE; canonical descriptor hash, lowercase hex.checksum
published_attimestamptzNOT NULLRelease audit metadata.Not exposed in v1

Indexes: PK (calibration_id); UNIQUE (checksum_sha256); (scale_id, subject, valid_from, valid_until); partial (tenant_id, calibration_id) WHERE visibility = 'tenant'. FKs: none—CASE and anchor sources remain external and are validated on the wire. Mutation: INSERT-only; DB trigger rejects UPDATE. Invalid-row test: an empty scale ID, overlapping validity that claims incompatible scale semantics under one ID, invalid interval, bad checksum, empty provenance, or tenant/system visibility mismatch violates this contract.

idempotency_controls #

Engine-owned, server-only retry coordination from ITD-007. This is operational control metadata, not an adaptive run, response cache, or learner record. A row expires 24 hours after creation and must contain no request body, response body, answer, score, candidate, QTI session, Results record, or Caliper event identifier.

ColumnSQL typeNullabilityConstraint / meaningAPI mapping
tenant_idtextNOT NULLVerified JWT tenant claim; non-empty. Part of the primary key and every server query. Never accepted from a header, path, or body.Not exposed
methodtextNOT NULLCanonical uppercase HTTP method; CHECK method = 'POST' in v1.Request method
canonical_pathtextNOT NULLOne exact public POST path from the endpoint table; excludes origin, query, fragment, and tenant data.Request path
key_hmacchar(64)NOT NULLLowercase-hex HMAC-SHA-256 of the 1–255 character Idempotency-Key under a server secret. The raw key is never persisted.Not exposed
canonical_request_hashchar(64)NOT NULLLowercase SHA-256 of the endpoint’s canonical request representation. Equality permits resume/recomposition; mismatch produces 409 idempotency-key-reused before upstream work.Not exposed
operation_iduuidNOT NULLDeterministic internal operation identity derived from scoped key plus request hash. It is not a run, learner, candidate, session, or result identifier.Not exposed
lifecycle_statetextNOT NULLEnum started, completed, or failed. Unknown values are invalid; state may move only started→completed or started→failed.Drives semantic retry only
terminal_statussmallintNULLAbsent while started; required for completed/failed; CHECK 100–599. Records only HTTP status, never response data.Controls semantic retry; not exposed
created_attimestamptzNOT NULLServer timestamp when conflict protection begins.Not exposed
updated_attimestamptzNOT NULLServer timestamp; CHECK not earlier than created_at.Not exposed
expires_attimestamptzNOT NULLExactly created_at + interval '24 hours'; expired rows are unusable and purged.Not exposed

Indexes: PRIMARY KEY (tenant_id, method, canonical_path, key_hmac); UNIQUE (operation_id); purge index (expires_at). FKs: none. Mutation: one atomic insert-or-read before side effects; only the legal lifecycle transition, terminal_status, and updated_at may change. Access: server service role only; anon/public/browser roles have no SELECT/INSERT/UPDATE/DELETE. Invalid-row test: any raw key, payload/response column, learner/upstream identifier, bad hash, illegal state/status pairing, cross-tenant query, or row older than 24 hours violates this contract.

Migration and ownership rules

RuleContractProvenance
Idempotent DDLCREATE TABLE IF NOT EXISTS; additive columns use ADD COLUMN IF NOT EXISTS. Constraints/indexes are named and existence-checked.Shared datastore discipline
Single ownerOnly mastery_engine migrates these three tables. Other modules consume public APIs, never create lookalike tables.ITD-001, 007
Mutation splitPublished policy/calibration rows reject UPDATE; correction inserts a new immutable ID/checksum. Idempotency controls permit only the documented lifecycle transition and are hard-purged after 24 hours. No public DELETE endpoint exists.ITD-007, 016, 020
API-fronted accessServer credentials only; anonymous DB access is not a product path. Reads enforce tenant/system visibility after JWT verification.ITD-008

Mechanically forbidden learner fields

Never in any engine table or logsSystem of recordHow the API uses it
candidate / OneRoster sourcedIdOneRosterNo caller candidate ID is accepted. The engine derives per-offer pseudonymous QTI candidate refs in memory; they remain encrypted in the continuation and are never returned or stored locally.
QTI session, item response, answer value, item outcomeQTIRead-through in memory; only opaque session/item refs appear on wire
mastery posterior, KC classification, scale scoreResults for durable factsCalculated in memory; acknowledged result reference returned
result_record / test_result_component payloadResultsIdempotent upstream write; no local copy
Caliper event payloadCaliperIdempotent upstream write; redacted receipt ref only
bearer token, request body, upstream response bodyNot retainedRedacted from operational logs

Error catalog

HTTPcodeWhenretryableIntegrator action
400invalid-requestMalformed JSON/path ID, unknown field, wrong type/range, learner-data field, or unsupported query parameter.falseCorrect fields using invalidParams.
401authentication-requiredMissing, malformed, expired, wrong-signature/issuer/audience JWT.falseMint a valid platform JWT.
403insufficient-scopeValid AlphaTest principal lacks endpoint scope.falseRequest the documented least-privilege AlphaTest scope.
404resource-not-foundAbsent resource or a resource owned by another tenant. Same response prevents enumeration.falseVerify the upstream ID in the caller’s tenant.
409idempotency-key-reusedWithin the same verified tenant + HTTP method + canonical path + key-HMAC scope, the stored canonical request hash differs from the current canonical request hash. Cross-tenant or cross-path use of the same literal key is a separate scoped operation and does not trigger this error.falseFor an intentional new request in the same scope, use a new key. For a retry, send the original canonical request unchanged; an identical hash resumes and recomposes semantically.
409stream-conflictContent response hash drift, conflicting QTI outcomes, token/session mismatch, or an existing pseudonymous offer conflicts with the selected artifact. Start and advance may return it while composing; inspect may return it when its mandatory reread proves the continuation no longer identifies one coherent immutable stream.falseAfter start or advance, call :inspect once with the latest continuation and do not overwrite upstream state. If :inspect itself returns this code, the conflict is terminal for that continuation: retain the problem requestId for support/audit, correct the upstream identity or version drift, and start a new run. Do not retry inspect or advance with the conflicted continuation.
409adaptive-pool-version-driftThe reread immutable QTI root/member/KC projection no longer matches the token-pinned version, ETag, or resolvedPoolHash.falseStop the run; do not substitute a newer pool or generic artifact-list result. Start a new run only against a newly certified immutable version.
412stream-conflictIf-Match does not equal the current strong ETag.trueCall :inspect, reconcile, then advance with currentEtag and a fresh key because it is a new semantic operation.
413simulation-limit-exceededSimulation has more than 100 profiles or any profile has more than 500 KC entries.falseSplit into bounded requests; do not send real learner profiles.
422calibration-invalidMissing/incompatible item or KC parameters, CASE framework mismatch, expired/unlicensed/bad-checksum anchor, or unsupported subject/grade.falseChoose a valid immutable calibration or publish a corrected version.
424upstream-unavailableA required Bank manifest, provisioned same-tenant Platform3 service profile, Content/QTI/CASE/Results/Caliper/anchor binding, version, capability, or safe response is transiently unavailable. The released route never treats a missing owner contract as a permanent successful steady state.true only for a transient safe read or idempotent writeInspect upstream.service, upstream.operation, and the binding table. Retry only when true, reusing the same key for the identical request; never supply a credential, item list, or local substitute.
424finalization-incompleteA required finalization write/read-back was attempted but rejected or became unavailable. A safely composed run may instead return 200 status=finalizing while acknowledgement is pending. QTI session closure is never required.trueRetry the identical advance with the same key only when instructed; otherwise inspect before a new semantic advance.
428precondition-requiredAdvance omitted If-Match.falseCall :inspect and send its strong ETag.
502qti-adaptive-pool-invalidThe terminal Bank manifest or its independent QTI reconciliation failed: a root ref did not resolve exactly once, a member was outside the immutable graph, CASE/KC arrays were empty/non-canonical, package identity/hash disagreed, or repeat reads were unstable.falsePreserve the request/receipt ID and report the owner-contract violation; never select from the partial projection.

Problem type URI rule: type is the absolute, stable documentation URI for the matching catalog code; clients branch on code, not on title or detail. A type URI may gain documentation without changing its meaning. ITD-009.

No untyped 5xx contract. Missing dependency contracts use typed 424; a present-but-invalid QTI pool projection uses typed 502 qti-adaptive-pool-invalid; request/concurrency/calibration failures use their named types. Every unexpected 5xx still uses ProblemDetails with a redacted request ID and never leaks a stack, token, body, or upstream payload.

Reviewed upstream binding status

Download upstream-bindings.json, the only executable upstream contract. Manifest mastery-engine-upstreams-2026-07-17-r7 has status bank_contract_blocks_architecture_journey_blocks_implementation: Content identity and QTI root reads are bound; Bank’s terminal manifest is the mandatory owner projection; provisioned Platform3 service JWT profiles are bound; Results component writes remain the production learner gap. ITD-028031.

Operation IDStatusPublished binding or required normalized contractRelease consequence
platform3.provisioned_service_jwtboundServer-held approved base URLs plus PLATFORM3_TENANT and PLATFORM3_JWT. The verified AcmeTest tenant must equal the selected profile tenant before wire I/O; the client JWT is never forwarded.Enables owner-backed conformance and learner flows for configured tenants; anonymous and bidirectional cross-tenant probes remain mandatory.
content.read_test_specboundGET /tenants/{tenantId}/alpha/content/items/{testSpecId}/blueprint; require role=spec and stable complete normalized hash.Blueprint identity/constraints ship.
content.validate_adaptive_bank_identityboundGET /tenants/{tenantId}/alpha/content/items/{testBankId}/bank-members; require bank/spec match, qti_adaptive_selection, and data=[].Bank identity ships; Content is explicitly not the adaptive member owner.
qti.read_adaptive_pool_rootbound root onlyGET /tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/delivery-json; require matching immutable version/ETag, assessment-test root, ordered refs, and stable repeat hash.Real 200 receipt proves the QTI root seam, not selection readiness.
bank.read_adaptive_pool_manifestmandatory owner contractGET /v1/bank-operations/{operationId}/manifest; terminal same-tenant evidence must contain root packageId, artifact/version, QTI identifier, package hash, and a non-empty ordered member projection with native artifact/version, package-scoped QTI identifier, and non-empty canonical CASE/KC GUID arrays. Repeat ETag/hash and independent QTI-root bijection must agree.Positive redacted receipt blocks architecture; the full start-to-stop journey blocks implementation and later. Invalid=502, drift=409; absence is never permission to omit the route.
qti.read_candidate_runtimeboundGET /tenants/{tenantId}/qti/candidates/{candidateRef}/runtime-data; filter to token-named sessions and canonicalize attempts.Scored-stream replay ships.
qti.offer_selected_itemboundPOST /tenants/{tenantId}/qti/delivery-sessions; exact selected artifact, derived pseudonymous candidate, non-empty delivery snapshot.Real QTI offers ship.
qti.score_item_attemptboundAcmeTest player calls POST .../delivery-sessions/{deliverySessionId}/attempts; engine consumes durable outcome and processing trace.Real QTI scoring boundary ships.
case.resolve_mappingboundGET /ims/case/v1p1/CFItems/{sourcedId}; sourcedId and URI must match the pinned mapping.Live KC identity ships.
nweamap.verify_anchorboundGET /nweamap/v1/r90; exact table version/source point and non-null source ref.Scale anchoring ships; no rank output.
results.write_result_recordboundPOST /alpha/results/v1/result-records; acknowledgement echoes deterministic producer_result_id.Base durable outcome ships.
results.write_kc_componentsupstream_gapRequires atomic or idempotently attachable KC components containing Results record ID, CASE GUID, classification, posterior, evidence refs, policy version, and calibration version; response acknowledges every component ID/count.Blocks mastery publication.
caliper.emit_completion_or_simulationboundPOST /caliper/v1p2/events; learner completion only after Results, simulation as non-learner conformance evidence.Audit/synthetic evidence ships.
caliper.read_evidence_ackboundGET /caliper/v1p2/events?eventIri={eventIri}; IRI/generated refs match the emitted receipt.Immutable evidence acknowledgement ships.
Gate rule: architecture approval requires the positive Bank adaptivePool receipt plus independent QTI-root reconciliation (ITD-028). From implementation onward, start, inspect, advance, and score-recovery must ship and a replayable owner-backed start-to-stop journey must pass; a missing owner projection never authorizes absent routes, permanent 404/424 responses, or a configuration-only product (ITD-029). Production learner completion additionally requires results.write_kc_components. The suite proves own-tenant inspect and indistinguishable 404s for both cross-tenant continuation replays (ITD-030, ITD-031).

Ownership and traceability matrix

Fact familyAuthoritative ownerAlphaTest behaviorPersistent locally?Decision
Blueprint + adaptive bank identityPlatform3 Content test_spec / test_bankRead bound blueprint and bank identity; require qti_adaptive_selection and exactly zero Content member rows.NoITD-028
Adaptive pool root + immutable member versionsAlphaTest Bank provenance + Platform3 QTI package graphRead the terminal Bank evidence manifest, require its complete package/member/CASE/KC projection, independently reconcile an exact ordered bijection to QTI, and hash the result in memory.NoITD-028
Tenant-bound upstream credentialPlatform3 operator provisioned service profileSelect server-held approved base URLs, PLATFORM3_TENANT, and PLATFORM3_JWT only when configured tenant equals the verified AcmeTest claim. Never forward or accept a caller credential.Server configuration only; never learner dataITD-030
Delivery session, offered item, scored outcomesPlatform3 QTIRead/command on wire; canonicalize in memoryNoITD-002, 016
Standard/KC GUID + relationshipsPlatform3 CASEResolve live; pin mapping version; return refsNoITD-014
Selection/stopping/classification rulesAlphaTest mastery_engineImmutable policy rowYes, configuration onlyITD-015
Model, scale transform, anchor provenance/toleranceAlphaTest configuration + licensed anchor sourceImmutable calibration row; verify anchor on wireYes, configuration onlyITD-017
Idempotency conflict/retry coordinationAlphaTest mastery_engineStore only scoped key HMAC, canonical request hash, deterministic operation ID, lifecycle/status, and timestamps; recompose responses from upstream ownersYes, control metadata for exactly 24 hoursITD-007
Durable mastery / KC result componentsPlatform3 ResultsWrite idempotently; return acknowledged refNoITD-019
Completion eventPlatform3 CaliperWrite idempotently; return acknowledged refNoITD-010, 019
Simulation evidence receiptPlatform3 CaliperWrite non-learner conformance event; read back event IRI and envelope hashNoITD-021
Upstream contracts are explicit and fail closed: manifest r7 distinguishes bound routes, the mandatory Bank owner projection, the independently reconciled QTI root, provisioned service authentication, and the remaining Results component gap. A release receipt covers service-profile selection, Content→Bank manifest→QTI root/member/runtime→CASE/anchor→Results (production only)→Caliper, with approved hosts, response hashes, and two-way tenant-isolation results. Inspect every normalized schema and release rule. ITD-028, ITD-031.