Owner-issued IDs
Content test spec/bank IDs, the terminal Bank operation ID, immutable policy/calibration IDs, and—in production—the Results student ID.
Give AlphaTest immutable Content, Bank, selection-policy, and scale-calibration IDs. Deliver the native Platform3 QTI sessions it returns. You receive a vertically comparable scale score and explicit mastered, gap, and not-yet knowledge components—without creating a second learner record.
Content test spec/bank IDs, the terminal Bank operation ID, immutable policy/calibration IDs, and—in production—the Results student ID.
Deterministic Bayesian KC updates, stopping rules, vertical-scale transform, encrypted continuation, and payload-free retry control.
Bank proves generation provenance. QTI owns delivery and scoring. CASE owns KC identity. Results owns durable mastery. Caliper owns audit events.
A scale only when reportable, uncertainty/provenance, and each KC classified mastered, gap, or not_yet.
Requirements: Bash, curl, jq, and uuidgen. Each block is valid shell. Use a verified JWT with mastery:run and mastery:read; AlphaTest derives tenant only from that JWT and selects a same-tenant, server-held provisioned Platform3 service profile. Never send an upstream host, tenant, or credential. Wire conventions · ITD-030
export ALPHATEST_BASE_URL="https://alphatest-mastery-engine.vercel.app"
export ALPHATEST_JWT="<platform-issued-jwt>"
export SELECTION_POLICY_ID="<immutable-selection-policy-id>"
export SCALE_CALIBRATION_ID="<immutable-scale-calibration-id>"
export TEST_SPEC_ID="<content-test-spec-id>"
export TEST_BANK_ID="<content-test-bank-id>"
export BANK_OPERATION_ID="<terminal-bank-operation-id>"
export RESULTS_STUDENT_ID="<same-tenant-results-student-id>"The Bank operation—not a caller-supplied pool—binds the package root and ordered native member/CASE/KC projection. For synthetic conformance, omit resultsStudentId and use runMode=owner_conformance. All seven production fields →
START_KEY="$(uuidgen)"
curl --fail-with-body -sS -D /tmp/mastery-start.headers \
-X POST "$ALPHATEST_BASE_URL/v1/adaptive-runs" \
-H "Authorization: Bearer $ALPHATEST_JWT" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $START_KEY" \
--data "$(jq -n \
--arg policy "$SELECTION_POLICY_ID" \
--arg calibration "$SCALE_CALIBRATION_ID" \
--arg spec "$TEST_SPEC_ID" \
--arg bank "$TEST_BANK_ID" \
--arg operation "$BANK_OPERATION_ID" \
--arg student "$RESULTS_STUDENT_ID" \
'{selectionPolicyId:$policy,scaleCalibrationId:$calibration,
testSpecId:$spec,testBankId:$bank,bankOperationId:$operation,
runMode:"production_learner",resultsStudentId:$student}')" \
| tee /tmp/mastery-run.json
ETAG="$(awk 'tolower($0) ~ /^etag:/{sub(/^[^:]+:[[:space:]]*/,"");sub(/[[:cntrl:]]$/,"");print;exit}' /tmp/mastery-start.headers)"
CONTINUATION="$(jq -er '.continuationToken' /tmp/mastery-run.json)"
QTI_SESSION="$(jq -er '.offeredItem.deliverySessionId' /tmp/mastery-run.json)"Released success is 201 AdaptiveRun plus a strong ETag, receipt ID, and exactly one native QTI delivery session. Keep the ETag and continuation together; never parse, log, or put the continuation in a URL. Response contract →
# Pass this native ID directly to the Platform3 QTI player.
printf 'Deliver this QTI session: %s\n' "$QTI_SESSION"
# Wait until QTI reports a durable scored attempt.
# Send no response, answer, score, or item body to AlphaTest.Your player submits to Platform3 QTI. AlphaTest rereads the token-named scored outcome; it never returns item content or accepts candidate answers. OfferedItem → · ITD-018 →
ADVANCE_KEY="$(uuidgen)"
curl --fail-with-body -sS -D /tmp/mastery-next.headers \
-X POST "$ALPHATEST_BASE_URL/v1/adaptive-runs:advance" \
-H "Authorization: Bearer $ALPHATEST_JWT" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $ADVANCE_KEY" \
-H "If-Match: $ETAG" \
--data "$(jq -n --arg token "$CONTINUATION" \
'{continuationToken:$token}')" \
| tee /tmp/mastery-run-next.json
ETAG="$(awk 'tolower($0) ~ /^etag:/{sub(/^[^:]+:[[:space:]]*/,"");sub(/[[:cntrl:]]$/,"");print;exit}' /tmp/mastery-next.headers)"
CONTINUATION="$(jq -er '.continuationToken' /tmp/mastery-run-next.json)"If status=in_progress, deliver the next non-null offeredItem.deliverySessionId and repeat. If finalizing, call :inspect and deliver nothing. If completed, publish only when scaleReportability=reportable. All endpoint contracts →
jq '{
status, stopReason, scaleReportability,
scale: (if .scaleReportability == "reportable" then .scale else null end),
mastered: [.kcClassifications[] | select(.classification == "mastered")],
gaps: [.kcClassifications[] | select(.classification == "gap")],
notYet: [.kcClassifications[] | select(.classification == "not_yet")]
}' /tmp/mastery-run-next.jsonnot_yet means insufficient evidence, not failure. Treat unknown future reportability values as non-reportable. anchor_unavailable makes every KC classification provisional and forbids publishing a mastery result. KC fields → · Scale fields →
Treat continuation and ETag as one compare-and-swap unit. A 412 stream-conflict means inspect, reconcile, then use currentEtag and a fresh key because the reconciled advance is new semantic work. ITD-006
Reuse a key only for the identical request after a transport or safe dependency retry. Changing a canonical body under the same tenant + method + path + key scope yields 409 idempotency-key-reused. ITD-007
Every error is RFC 9457 application/problem+json. Branch on stable code, record requestId, obey retryable, and never parse title or detail. ProblemDetails fields · complete 14-row catalog · ITD-009
| Signal | Meaning | Correct action |
|---|---|---|
409 idempotency-key-reused | Same scoped key, different canonical request. | Restore the identical request for a retry, or use a new key for intentional work. |
409 stream-conflict | Content identity or QTI outcomes no longer form one coherent stream. | Inspect once after start/advance. If inspect returns it, stop that continuation and preserve the request ID. |
409 adaptive-pool-version-drift | The pinned Bank/QTI pool projection changed. | Stop. Never swap in a newer or locally reconstructed pool; begin a new run only after certification. |
412 stream-conflict | Your If-Match is stale. | Inspect, reconcile, then advance with currentEtag and a fresh key. |
424 upstream-unavailable | A required owner binding or same-tenant service profile is transiently unavailable. | Retry only when retryable=true; reuse the key only for the identical request. Never supply credentials or a local substitute. |
424 finalization-incomplete | A required durable acknowledgement is pending or failed. | Retry the identical advance with the same key only when instructed; otherwise inspect. |
502 qti-adaptive-pool-invalid | The Bank manifest or independent QTI reconciliation failed integrity checks. | Stop, preserve request/receipt ID, and report the owner-contract violation. |
| Capability | Status | Required proof |
|---|---|---|
bank.read_adaptive_pool_manifest | BLOCKS ARCHITECTURE RECEIPT | A timestamped Bank 200 exposes immutable root identity plus a non-empty ordered native member/CASE/KC projection; repeat ETag/hash match and independent QTI-root reconciliation is exact. |
| Owner-backed adaptive journey | BLOCKS IMPLEMENTATION RELEASE | Deployed start 201 → native QTI delivery and score → advance to a named stop → reportable scale and explicit mastered/gap/not_yet arrays, with replay and tenant-isolation evidence. |
results.write_kc_components | BLOCKS PRODUCTION COMPLETION | Results atomically or idempotently acknowledges one component per CASE GUID. Synthetic owner conformance never fakes this learner write. |
| Provisioned Platform3 authentication; Content/QTI root/runtime; CASE; anchor; base Results record; Caliper | BOUND CONTRACTS | Server-held profiles are tenant-matched before wire I/O; successful release still requires the receipts above. |
modifiedSince, webhook, bulk, or DELETE endpoints.Methods, scopes, headers, successes, and endpoint-specific failures.
Type, presence, range, allowed values, owner, and decision provenance.
Status, stable code, trigger, retryability, and exact action.
Policy/calibration reads, simulation, owner contracts, release consequences, and downloadable manifest.