Who
The AcmeTest maintainer already delivering Platform3 QTI attempts.
The intended post-gate v1 wire contract for attempt reports, mastery gaps, readiness, owner-produced item analytics, per-source alignment proofs, and revision orders. Every field below has a type, null rule, validation rule, owner, and approved architecture citation.
The AcmeTest maintainer already delivering Platform3 QTI attempts.
Fetch attempt evidence, page candidate history, materialize safely, and consume audit-grade improvement receipts without computing a score or aggregate.
Reports composes live Platform3 facts. It stores no attempt, score, roster, mastery state, item statistic, or cohort aggregate.
null means “known absence” only where listed. [] means the section was requested and the authority returned zero rows. Unknown request fields and repeated scalar query parameters return 400. Clients must ignore additive response fields per ITD-015.The commands are client-construction contracts for use only after their named gates pass; they do not claim the routes currently exist.
curl --fail-with-body --get \
"$REPORTS_BASE_URL/v1/attempt-reports/att_7F3k9" \
-H "Authorization: Bearer $REPORTS_TOKEN" \
-H "Accept: application/json" \
--data-urlencode "view=evidence"{
"object":"attempt_report","attemptId":"att_7F3k9","qtiSessionId":"session_A92",
"qtiTestId":"qti_form_math5_b","resultRecordId":"result_4821",
"candidateSourcedId":"student_1042","administrationId":"admin_fall_2026",
"contentTestSpecId":"spec_tx_math_5_gate_v3","testKind":"mastery_gate","status":"scored",
"score":{"value":87,"minimum":0,"maximum":100,"unit":"percent","scaleVersion":null},
"mastery":[{"kind":"standard","caseGuid":"case_tx_5_3a","parentCaseGuid":null,
"state":"gap","estimate":0.71,"threshold":0.80,"uncertainty":0.04,
"uncertaintyKind":"standard_error","policyId":"gate-policy-5","policyVersion":"3",
"evidence":[{"qtiItemId":"item_301","qtiOutcomeId":"outcome_901",
"resultComponentId":"component_77","contribution":-0.09,"observedAt":"2026-07-15T14:22:09Z"}]}],
"gate":{"status":"fail","criteriaVersion":"3","achieved":0.71,"required":0.80,
"gapCaseGuids":["case_tx_5_3a"],"coverageEvidenceId":"coverage_552"},
"diagnostic":null,
"sources":[
{"service":"qti","resourceId":"att_7F3k9","observedAt":"2026-07-15T14:22:10Z","version":"qti-etag-19","status":"current"},
{"service":"results","resourceId":"result_4821","observedAt":"2026-07-15T14:22:10Z","version":"result-v4","status":"current"},
{"service":"content","resourceId":"spec_tx_math_5_gate_v3","observedAt":"2026-07-15T14:22:10Z","version":"3","status":"current"}],
"omitted":["readiness"],"incompleteSections":[],"observedAt":"2026-07-15T14:22:10Z",
"requestId":"req_N7h2","traceId":"trace_J5m8"
}Exact schema: AttemptReport. diagnostic is null because the report is a mastery gate; readiness is omitted because it is a focused sub-resource.
curl --fail-with-body --get \
"$REPORTS_BASE_URL/v1/attempt-reports/att_diag_8K2m" \
-H "Authorization: Bearer $REPORTS_TOKEN" \
-H "Accept: application/json" \
--data-urlencode "view=evidence"{
"object":"attempt_report","attemptId":"att_diag_8K2m","qtiSessionId":"session_diag_D41",
"qtiTestId":"qti_adaptive_math5_fall","resultRecordId":"result_diag_7102",
"candidateSourcedId":"student_1042","administrationId":"admin_diag_fall_2026",
"contentTestSpecId":"spec_math5_diagnostic_v2","testKind":"adaptive_diagnostic","status":"scored",
"score":{"value":214.6,"minimum":null,"maximum":null,"unit":"mastery_scale","scaleVersion":"ams-math-2"},
"mastery":[
{"kind":"standard","caseGuid":"case_math5_num","parentCaseGuid":null,
"state":"mastered","estimate":0.91,"threshold":0.80,"uncertainty":0.03,
"uncertaintyKind":"standard_error","policyId":"adaptive-math5","policyVersion":"2",
"evidence":[{"qtiItemId":"item_diag_101","qtiOutcomeId":"outcome_diag_501","resultComponentId":"component_diag_801","contribution":0.14,"observedAt":"2026-07-15T15:03:01Z"}]},
{"kind":"knowledge_component","caseGuid":"case_math5_num_frac","parentCaseGuid":"case_math5_num",
"state":"mastered","estimate":0.88,"threshold":0.80,"uncertainty":0.04,
"uncertaintyKind":"standard_error","policyId":"adaptive-math5","policyVersion":"2",
"evidence":[{"qtiItemId":"item_diag_102","qtiOutcomeId":"outcome_diag_502","resultComponentId":"component_diag_802","contribution":0.11,"observedAt":"2026-07-15T15:03:34Z"}]},
{"kind":"standard","caseGuid":"case_math5_geo","parentCaseGuid":null,
"state":"not_yet","estimate":0.72,"threshold":0.80,"uncertainty":0.05,
"uncertaintyKind":"standard_error","policyId":"adaptive-math5","policyVersion":"2",
"evidence":[{"qtiItemId":"item_diag_103","qtiOutcomeId":"outcome_diag_503","resultComponentId":"component_diag_803","contribution":-0.04,"observedAt":"2026-07-15T15:04:02Z"}]},
{"kind":"knowledge_component","caseGuid":"case_math5_geo_volume","parentCaseGuid":"case_math5_geo",
"state":"not_yet","estimate":0.69,"threshold":0.80,"uncertainty":0.06,
"uncertaintyKind":"standard_error","policyId":"adaptive-math5","policyVersion":"2",
"evidence":[{"qtiItemId":"item_diag_104","qtiOutcomeId":"outcome_diag_504","resultComponentId":"component_diag_804","contribution":-0.06,"observedAt":"2026-07-15T15:04:39Z"}]},
{"kind":"standard","caseGuid":"case_math5_alg","parentCaseGuid":null,
"state":"gap","estimate":0.43,"threshold":0.80,"uncertainty":0.04,
"uncertaintyKind":"standard_error","policyId":"adaptive-math5","policyVersion":"2",
"evidence":[{"qtiItemId":"item_diag_105","qtiOutcomeId":"outcome_diag_505","resultComponentId":"component_diag_805","contribution":-0.19,"observedAt":"2026-07-15T15:05:10Z"}]},
{"kind":"knowledge_component","caseGuid":"case_math5_alg_patterns","parentCaseGuid":"case_math5_alg",
"state":"gap","estimate":0.38,"threshold":0.80,"uncertainty":0.05,
"uncertaintyKind":"standard_error","policyId":"adaptive-math5","policyVersion":"2",
"evidence":[{"qtiItemId":"item_diag_106","qtiOutcomeId":"outcome_diag_506","resultComponentId":"component_diag_806","contribution":-0.22,"observedAt":"2026-07-15T15:05:42Z"}]}
],
"gate":null,
"diagnostic":{"scaleScore":214.6,"scaleVersion":"ams-math-2","calibrationVersion":"cal-2026-01",
"standardError":2.7,"stoppingReason":"classifications_complete","administeredItemCount":24,"nweaNormsSet":null},
"sources":[
{"service":"qti","resourceId":"att_diag_8K2m","observedAt":"2026-07-15T15:06:00Z","version":"qti-etag-27","status":"current"},
{"service":"results","resourceId":"result_diag_7102","observedAt":"2026-07-15T15:06:00Z","version":"result-v6","status":"current"},
{"service":"content","resourceId":"spec_math5_diagnostic_v2","observedAt":"2026-07-15T15:06:00Z","version":"2","status":"current"},
{"service":"case","resourceId":"case_math5","observedAt":"2026-07-15T15:06:00Z","version":"case-etag-44","status":"current"},
{"service":"mastery_engine","resourceId":"run_diag_3301","observedAt":"2026-07-15T15:06:00Z","version":"ams-math-2/cal-2026-01","status":"current"},
{"service":"oneroster","resourceId":"student_1042","observedAt":"2026-07-15T15:06:00Z","version":"oneroster-etag-18","status":"current"},
{"service":"unknown","resourceId":"admin_diag_fall_2026","observedAt":"2026-07-15T15:06:00Z","version":"administration-v3","status":"current"}
],
"omitted":["readiness"],"incompleteSections":[],"observedAt":"2026-07-15T15:06:00Z",
"requestId":"req_diag_P4s8","traceId":"trace_diag_Q9t2"
}How to read this fixture. gate is a known inapplicable value and therefore JSON null; nweaNormsSet is null because this fixture makes no MAP crosswalk. readiness is the only omitted section and is named in omitted; incompleteSections: [] says no requested enrichment failed. The six mastery rows contain both CASE entity kinds and all three required diagnostic classifications, each with a nonempty QTI/Results evidence chain. The score, classification policy, terminal reason, count, and versions are fixed synthetic pass-through values—not calculations by Reports. The seven receipts make the fixture’s consulted authorities explicit; service: unknown preserves the current SourceRef vocabulary for the Administration receipt instead of inventing an enum. Provenance: ITD-003, ITD-005, ITD-007, and ITD-012.
curl --fail-with-body --get \
"$REPORTS_BASE_URL/v1/candidates/student_1042/attempt-reports" \
-H "Authorization: Bearer $REPORTS_TOKEN" \
--data-urlencode "testKind=mastery_gate" \
--data-urlencode "limit=2"{
"data":[],
"nextCursor":"eyJvcGFxdWUiOiJjdXJzb3IifQ",
"hasMore":true,
"observedAt":"2026-07-15T14:22:10Z",
"sources":[{"service":"results","resourceId":"student_1042","observedAt":"2026-07-15T14:22:10Z","version":"page-v8","status":"current"}]
}curl --fail-with-body --get \
"$REPORTS_BASE_URL/v1/candidates/student_1042/attempt-reports" \
-H "Authorization: Bearer $REPORTS_TOKEN" \
--data-urlencode "testKind=mastery_gate" \
--data-urlencode "limit=2" \
--data-urlencode "cursor=eyJvcGFxdWUiOiJjdXJzb3IifQ"data: [] is valid: that page has zero authoritative rows. It does not mean omitted. A real row is the summary projection of AttemptReport.
curl --fail-with-body \
"$REPORTS_BASE_URL/v1/attempt-reports:materialize" -X POST \
-H "Authorization: Bearer $REPORTS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acmetest-att-7F3k9-v1" \
--data '{"attemptId":"att_7F3k9","administrationId":"admin_fall_2026","view":"summary"}'{"operationId":"op_93wK","report":{"object":"attempt_report","attemptId":"att_7F3k9","qtiSessionId":"session_A92","qtiTestId":"qti_form_math5_b","resultRecordId":"result_4821","candidateSourcedId":"student_1042","administrationId":"admin_fall_2026","contentTestSpecId":"spec_tx_math_5_gate_v3","testKind":"mastery_gate","status":"scored","score":{"value":87,"minimum":0,"maximum":100,"unit":"percent","scaleVersion":null},"mastery":[],"gate":{"status":"fail","criteriaVersion":"3","achieved":0.71,"required":0.80,"gapCaseGuids":["case_tx_5_3a"],"coverageEvidenceId":"coverage_552"},"diagnostic":null,"sources":[{"service":"results","resourceId":"result_4821","observedAt":"2026-07-15T14:22:10Z","version":"result-v4","status":"current"}],"omitted":["mastery","itemEvidence","readiness"],"incompleteSections":[],"observedAt":"2026-07-15T14:22:10Z","requestId":"req_R6v3","traceId":"trace_C1n7"}}For 24 hours, an identical retry suppresses writes, preserves operationId, recomposes current Platform3 truth, and adds Idempotent-Replayed: true. A changed body with the same key is 409.
HTTP/1.1 409 Conflict
Content-Type: application/problem+json
{"type":"https://alphatest-andymontgomery-9773s-projects.vercel.app/reports/integrator_api/data_dictionary/problems/idempotency-conflict","title":"Idempotency key conflicts with an earlier request","status":409,"detail":"Use a new Idempotency-Key for a different request body.","instance":"/problems/occurrences/req_Z2d6","requestId":"req_Z2d6","traceId":"trace_M9p1","retryable":false,"dependency":null,"fieldErrors":null,"operationId":"op_93wK"}All stable suffixes and recovery semantics are in the registry; each type URI dereferences.
{
"object":"improvement_run",
"improvementRunId":"ir_2026_math5_0042",
"administrationId":"admin_fall_2026",
"contentTestSpecId":"spec_tx_math_5_gate_v3",
"contentTestSpecVersion":"3",
"status":"completed",
"analysisPolicyId":"reports-item-policy",
"analysisPolicyVersion":"4",
"formulaVersion":"alignment-v1",
"metricStatuses":[
{"metric":"item_difficulty","status":"available","artifactRef":"analytics:item-form:af_881","reasonCode":null},
{"metric":"item_discrimination","status":"available","artifactRef":"analytics:item-form:af_881","reasonCode":null},
{"metric":"distractor_distribution","status":"unavailable","artifactRef":null,"reasonCode":"owner_artifact_missing"},
{"metric":"form_summary","status":"available","artifactRef":"analytics:item-form:af_882","reasonCode":null}
],
"namedSourceCount":2,
"alignmentRecordCount":2,
"revisionOrderCount":1,
"blockedOrderCount":0,
"omissions":["distractor_distribution"],
"receipt":{"mediaType":"application/zip","sha256":"946cf2f5d3e0a611b87e17fc1bf93fe663d82b99ae6bc5204d0c95efb3c2d91a","downloadUrl":"https://receipts.alphatest.example/r/ir_2026_math5_0042?sig=opaque","expiresAt":"2026-07-24T16:15:00Z"},
"createdAt":"2026-07-24T15:00:00Z",
"completedAt":"2026-07-24T15:14:03Z",
"requestId":"req_improve_42",
"traceId":"trace_improve_42"
}Exact schemas: ImprovementRun, MetricStatus, and ReceiptLink. An unavailable independent metric is named in both metricStatuses and omissions; it does not authorize private Reports math. Completion is valid because all named sources have alignment records and every tripped order is acknowledged or explicitly blocked, as required by ITD-040.
result_record/test_result_components writes, conditional/idempotent behavior, matching Caliper profile, exact read-back, and a duplicate-free forced partial-failure replay are proven. No local outbox containing learning facts and no guessed body. ITD-032.?qtiAttemptId= lookup primitive is confirmed, but its published contract does not yet return the dereferenceable candidate, Administration, QTI session/test/item outcomes, Content test_spec, test kind, gate decision, KC/mastery, and component evidence required for a report. Runtime-only collection fields, producer-id guessing, canonical-response parsing, tenant scans, partial reports, and local correlation tables are forbidden substitutes. ITD-028.unavailable; missing receivers become blocked_upstream. Reports never substitutes local analytics, edits owner resources, or marks an undelivered order complete. Release also requires the production acceptance chain in ITD-040.| Name | Type / range | Meaning and validation | Owner · provenance |
|---|---|---|---|
| Platform3 reference | string, 1–255 UTF-8 bytes | Opaque, case-sensitive pass-through; whitespace rejected; no UUID/prefix assumption. | Upstream · ITD-003 |
| Instant | RFC 3339 UTC string | Terminal Z; fractional seconds accepted; offsets and leap seconds rejected. | Reports normalization · ITD-012 |
| Proportion | number, 0–1 inclusive | Finite JSON number, at most six fractional digits. | Blueprint/Analytics pass-through · ITD-010/011 |
| Count | integer, 0–2,147,483,647 | Non-negative snapshot count, never inferred from an omitted array. | Upstream · ITD-009 |
Authorization | Bearer JWT | Required claims: sub, tenantId, iat, exp, role, and reports:read or reports:write. studentIds/schoolSourcedIds/classSourcedIds narrow access. | Reports · ITD-021/024 |
Idempotency-Key | 1–255 visible ASCII | Required for materialize and improvement analyze; no whitespace/control chars; tenant+method+path scope; 24-hour replay retention. | Reports · ITD-020/038 |
Idempotent-Replayed | response token | true when writes were suppressed and live truth recomposed; absence means false. | Reports · ITD-020 |
| Field | Type | Null? | Meaning / validation | Owner · provenance |
|---|---|---|---|---|
object | enum | No | Always attempt_report. | Reports · ITD-004 |
attemptId | Platform3 ref | No | Exact QTI attempt id; equals path value. | QTI · ITD-003 |
qtiSessionId | Platform3 ref | Yes | Null only if authoritative contract has no separate session ref. | QTI · ITD-004 |
qtiTestId | Platform3 ref | No | Administered QTI test/form. | QTI · ITD-003 |
resultRecordId | Platform3 ref | No | Settled Results record read back after write-through. | Results · ITD-002 |
candidateSourcedId | Platform3 ref | No | OneRoster candidate, intersected with JWT claims. | OneRoster · ITD-003/014 |
administrationId | Platform3 ref | No | Administration glue id; not a roster/attempt alias. | Administration · ITD-004 |
contentTestSpecId | Platform3 ref | No | Content test_spec governing criteria and crosswalk. | Content · ITD-003 |
testKind | enum | No | mastery_gate|adaptive_diagnostic|formative|unknown; unknown response-only. | Content · ITD-008/015 |
status | enum | No | scored|indeterminate|unknown. An attempt without the settled Results fact required to construct this resource returns the pinned dependency-incomplete problem (503), so an unscored state is never projected as an AttemptReport. | Results/QTI · ITD-002/023 |
score | Score | No | Settled upstream score; never recomputed. | Results · ITD-001 |
mastery | MasteryRow[], max 5,000 | No | Unique by kind+caseGuid. Empty and named in omitted when projection excludes it. | Results/CASE · ITD-005 |
gate | GateDecision | Yes | Required for mastery_gate; null otherwise. Missing criteria yields indeterminate object. | Results/Content · ITD-006 |
diagnostic | DiagnosticDetail | Yes | Required for adaptive_diagnostic; null otherwise. | Mastery engine/Results · ITD-007 |
sources | SourceRef[], 1–32 | No | Receipt for every consulted upstream; required failure returns 503. | Reports · ITD-012 |
omitted | unique enum[] | No | Values: mastery, itemEvidence, readiness; projection omissions only. | Reports · ITD-004 |
incompleteSections | ProblemDetails[] | No | Optional enrichment failures; empty means complete. | Reports · ITD-012 |
observedAt | Instant | No | Live composition completion time. | Reports · ITD-012 |
requestId, traceId | string, 1–128 | No | Boundary/distributed correlation; no learning facts. | Reports · ITD-013 |
| Field | Type / null | Rule |
|---|---|---|
| value | finite number · no | Settled upstream value. |
| minimum, maximum | finite number · yes | Null only for unbounded scale; when present minimum ≤ value ≤ maximum. |
| unit | enum · no | points, percent, mastery_scale, unknown. |
| scaleVersion | string 1–128 · yes | Required for mastery_scale; otherwise null only if source has no version. |
| Field | Type/null | Rule |
|---|---|---|
| service | enum/no | qti, results, analytics, content, case, oneroster, caliper, mastery_engine, bank, blueprint, unknown. |
| resourceId | Platform3 ref/no | Native upstream id. |
| observedAt | Instant/no | Time this request observed source. |
| version | string 1–255/yes | ETag/version; null only when upstream supplies neither. |
| status | enum/no | current, stale, unavailable, unknown; required sources must be current. |
The common receipt fields derive from ITD-012; Bank and Blueprint receiver receipts are required by ITD-038.
| Field | Type | Null? | Rule / owner |
|---|---|---|---|
| kind | enum | No | standard or knowledge_component · CASE/Results. |
| caseGuid | Platform3 ref | No | Live-dereferenceable CASE GUID. |
| parentCaseGuid | Platform3 ref | Yes | Required for child KC when parent exists; null for root standard. |
| state | enum | No | mastered, not_yet, gap, insufficient_evidence, unknown. |
| estimate, threshold | finite number | No | Upstream estimate and applied policy threshold; no default. |
| uncertainty | number ≥0 | No | Magnitude interpreted by uncertaintyKind. |
| uncertaintyKind | enum | No | standard_error, interval_half_width, policy_margin, unknown. |
| policyId, policyVersion | string 1–255 | No | Immutable Results/blueprint policy identity. |
| evidence | ItemEvidence[], 1–500 | No | At least one contribution; empty invalid. |
Every row and field is the evidence-bearing contract pinned by ITD-005; values pass through Results, QTI, CASE, or the mastery engine as named.
| Field | Type | Null? | Rule / owner |
|---|---|---|---|
| qtiItemId | Platform3 ref | No | Administered item id, not copied content · QTI. |
| qtiOutcomeId | Platform3 ref | No | Scored item outcome · QTI. |
| resultComponentId | Platform3 ref | Yes | Null only until Gate B exposes a stable Results component id. |
| contribution | finite number | No | Signed policy contribution; Reports does not compute it. |
| observedAt | Instant | No | Authoritative outcome time. |
| Field | Type/null | Rule |
|---|---|---|
| status | enum/no | pass, fail, indeterminate, unknown; Results-owned. |
| criteriaVersion | string/no | Immutable Content criteria. |
| achieved | finite number/yes | Null only when indeterminate has no valid measurement. |
| required | finite number/no | Blueprint threshold; absence forces an indeterminate problem. |
| gapCaseGuids | unique refs[]/no | Complete on fail, empty on pass, possibly nonempty when indeterminate. |
| coverageEvidenceId | Platform3 ref/yes | Null forces indeterminate. |
| Field | Type/null | Rule |
|---|---|---|
| scaleScore | finite number/no | RIT-like mastery score, not NWEA-issued. |
| scaleVersion, calibrationVersion | string/no | Immutable versions. |
| standardError | number ≥0/no | Score uncertainty. |
| stoppingReason | enum/no | classifications_complete, precision_target_met, max_items, time_budget, unknown. |
| administeredItemCount | integer ≥1/no | QTI count. |
| nweaNormsSet | string/yes | Required only for a MAP crosswalk. |
ITD-007 requires the terminal reason; the allowed values are a reviewed pass-through from the approved Mastery Engine AdaptiveRun source binding.
| Path | Type/null | Rule · owner |
|---|---|---|
| attemptId | Platform3 ref/no | QTI attempt. |
| entries | array 1–100/no | Unique sourceTest+sourceVersion. |
| entries[].decision | enum/no | projected_pass, not_ready, indeterminate, unknown. |
| sourceTest, sourceVersion, crosswalkVersion | string/no | Named test/publication and immutable blueprint crosswalk. |
| coverageFraction | proportion/no | Must equal 1 for projected_pass. |
| dokDominance | enum/no | satisfied, not_satisfied, indeterminate; satisfied required to project pass. |
| qualifyingBlueprintSlotIds | unique refs[]/no | Nonempty for projected_pass. |
| decisionRuleId, decisionRuleVersion | string/no | Named versioned rule. |
| limitations | string[], max 50/no | Each 1–500 chars; empty only when none. |
| sources | SourceRef[], 1–32/no | Results/Content/blueprint receipts. |
| Field | Type/null | Rule · owner |
|---|---|---|
| qtiTestId, comparisonQtiTestIds | ref + unique refs[]/no | Subject/compared QTI forms. |
| contentTestSpecId | ref/no | Shared Content blueprint. |
| coverageMatch, dokMatch | boolean/no | Blueprint evidence. |
| sampleSizes | object<formId,count>/no | Exactly one Analytics count per form. |
| method, analysisVersion | string/no | Named Analytics method/version. |
| statistic, confidenceInterval.lower/upper, tolerance | finite numbers/no | lower ≤ statistic ≤ upper; tolerance ≥0. |
| decision | enum/no | equivalent, not_equivalent, insufficient_evidence, unknown. |
| evidenceArtifactUrl | HTTPS URL/yes | Null only for insufficient evidence. |
| sources | SourceRef[], 1–32/no | QTI/Analytics/Content/blueprint receipts. |
| Field | Type/null | Rule |
|---|---|---|
| scope.type | enum/no | class or school_grade; matching sourcedIds/OneRoster grade required. |
| rollupId, formulaVersion | ref + string/no | Native Analytics identity/formula. |
| asOf | Instant/no | Analytics snapshot. |
| populationCount | count/no | Population under Analytics definition. |
| suppression.status | enum/no | not_suppressed, suppressed, unknown; suppressed exposes no derivable values. |
| source | SourceRef/no | Analytics receipt. |
ITD-009. This is a post-gate outbound obligation, not a fabricated mapping.
| Field | Type | Null? | Meaning / validation | Owner · provenance |
|---|---|---|---|---|
object | enum | No | Always improvement_run. | Reports · ITD-040 |
improvementRunId | string 1–255 | No | Opaque AlphaTest workflow id; immutable in tenant. | Reports engine · ITD-039 |
administrationId | Platform3 ref | No | Exact scored administration analyzed; equals command path. | Administration · ITD-038 |
contentTestSpecId, contentTestSpecVersion | ref + string | No | Immutable Content blueprint and version used by every alignment row. | Content · ITD-037/038 |
status | enum | No | queued|analyzing|completed|completed_with_omissions|blocked_upstream|failed|unknown. completed is legal only when ITD-040 acceptance invariants hold. | Reports engine · ITD-039/040 |
analysisPolicyId, analysisPolicyVersion | string 1–255 | No | Released threshold-policy identity; immutable for the run. | Reports policy · ITD-038 |
formulaVersion | string 1–255 | No | Alignment formula version; currently alignment-v1. | Reports policy · ITD-037 |
metricStatuses | MetricStatus[], exactly 4 | No | Exactly one row for each required item/form metric; unavailable metrics remain present. | Analytics/Caliper composition · ITD-036 |
namedSourceCount | Count | No | Number of named source tests in the immutable blueprint crosswalk. | Content · ITD-037/040 |
alignmentRecordCount | Count | No | Must equal namedSourceCount before completed. | Reports composition · ITD-040 |
revisionOrderCount, blockedOrderCount | Count | No | Total tripped orders and subset explicitly blocked upstream; counts derive from workflow state, never learner facts. | Reports engine · ITD-039/040 |
omissions | unique enum[], max 8 | No | Any unavailable metric names; values: item_difficulty|item_discrimination|distractor_distribution|form_summary|predicted_actual. | Reports · ITD-036/037 |
receipt | ReceiptLink | Yes | Required for completed/completed_with_omissions; null while nonterminal or if evidence dereference fails closed. | Reports evidence surface · ITD-040 |
createdAt, completedAt | Instant | completedAt only | completedAt required exactly for terminal states and not before createdAt. | Reports engine · ITD-039 |
requestId, traceId | string 1–128 | No | Boundary and distributed trace correlation. | Reports · ITD-013 |
| Field | Type/null | Rule |
|---|---|---|
metric | enum/no | item_difficulty|item_discrimination|distractor_distribution|form_summary; exactly one of each per run. |
status | enum/no | available|unavailable|suppressed|stale|unknown. Only available may trigger an order. |
artifactRef | Platform3 ref/yes | Immutable Analytics/Caliper artifact id; required for available or suppressed, null for unavailable. |
populationCount, sampleCount | Count/yes | Owner-produced counts; required when available, null when unavailable or disclosure is suppressed. |
suppressionStatus | enum/no | not_suppressed|suppressed|unknown. |
suppressionRule | string 1–255/yes | Required when suppressed; otherwise null. |
analysisWindow.start, .end | Instant/yes | Both present or both null; start ≤ end; required when available. |
formulaVersion | string 1–255/yes | Owner formula; required when available or suppressed. |
reasonCode | enum/yes | Null when available; otherwise owner_artifact_missing|owner_field_missing|suppressed|stale|receiver_unavailable|unknown. |
All metric values, counts, suppression rules, windows, and formula versions are owner pass-throughs required by ITD-036.
| Field | Type/null | Rule / owner |
|---|---|---|
improvementRunId, sourceKey | ref + string/no | Run id and URL-safe immutable key unique in the run · Reports/Content. |
sourceAssessment, sourceVersion | string 1–255/no | Named external assessment and immutable publication version · Content. |
contentTestSpecId, contentTestSpecVersion | ref + string/no | Target blueprint identity · Content. |
crosswalkHash | 64 lowercase hex/no | SHA-256 of immutable complete crosswalk input · Content. |
formulaVersion | string/no | alignment-v1 for the pinned formula. |
numerator, denominator | finite number/no | Both ≥0; denominator >0. Missing, ambiguous, stale, or lower-DOK rows add zero to numerator but retain weight in denominator. |
alignmentPercent | number 0–100/no | 100 × numerator / denominator, rounded to six fractional digits only for transport. |
contributions | AlignmentContribution[], 1–10,000/no | Exactly one row for every source requirement; sum of weightedContribution equals numerator and sum of weight equals denominator. |
predictedActual | PredictedActualComparison/yes | Present only from an authenticated Analytics external-score artifact; null is explicit and does not alter structural alignment. |
limitations | string[], max 100/no | Each 1–500 chars; names missing, ambiguous, stale, lower-DOK, or suppressed evidence. |
receipt | ReceiptLink/no | Content-addressed immutable bundle for this named source. |
| Field | Type/null | Rule |
|---|---|---|
sourceRequirementId | Platform3 ref/no | Exact source requirement; unique in report. |
caseGuid | Platform3 ref/yes | Mapped CASE GUID; null when no unambiguous mapping exists. |
blueprintSlotId | Platform3 ref/yes | Mapped target slot; null makes coverage 0. |
weight | finite number >0/no | Source blueprint point/item weight; never defaulted or dropped. |
coverage, rigor | integer 0 or 1/no | Coverage is 1 only for a valid mapping; rigor is 1 only when target DOK ≥ source DOK. |
sourceDok, targetDok | integer 1–4; target nullable | Source and mapped target DOK; target null when uncovered. |
weightedContribution | finite number ≥0/no | Exactly weight × coverage × rigor. |
reasonCode | enum/yes | Null only for full contribution; otherwise missing_mapping|ambiguous_mapping|stale_mapping|lower_dok|unknown. |
The zero-penalizing formula and complete contribution ledger are normative in ITD-037.
| Field | Type/null | Rule |
|---|---|---|
artifactRef | Platform3 ref/no | Immutable Analytics external-score comparison artifact. |
populationCount | Count/no | Owner-defined eligible population. |
suppressionStatus, suppressionRule | enum + string/second nullable | Status is not_suppressed|suppressed|unknown; rule required when suppressed. |
method, analysisVersion | string/no | Named Analytics method and immutable version. |
predictedPassCount, actualPassCount, agreementCount | Count/yes | Required when not suppressed; each ≤ populationCount. Null together when suppressed. |
observedAgreement | Proportion/yes | Required when not suppressed and equals agreementCount/populationCount; null when suppressed. |
This is a separate Analytics-owned comparison; it is never blended into the structural score. ITD-037.
| Field | Type/null | Rule / owner |
|---|---|---|
revisionOrderId | string 1–255/no | Deterministic id from tenant + target + native subject ids + policy/version + evidence digest · Reports. |
improvementRunId, administrationId | refs/no | Owning run and native administration · Reports/Administration. |
targetModule | enum/no | bank|blueprint. |
requestedAction | enum/no | regenerate_item|rotate_item|review_miskey|tag_distractor|apply_calibration_delta|repair_crosswalk; must be valid for target. |
qtiItemId, qtiFormId, qtiTestId | Platform3 refs/yes | Native QTI subjects; the policy declares which are required for each action. |
contentTestSpecId, contentTestSpecVersion | ref + string/no | Immutable governing blueprint · Content. |
caseGuids, sourceKeys | unique string[], max 1,000/no | CASE/source-test subjects; empty only when action does not address one. |
reasonCodes | unique enum[], 1–20/no | low_discrimination|difficulty_out_of_band|dead_distractor|untagged_distractor|miskey_evidence|readiness_tolerance_breach|blueprint_coverage_defect|blueprint_rigor_defect. |
observedMetric.name, .value, .unit | string + finite number + enum/no | Owner metric and unit proportion|count|points|percent. |
threshold.operator, .value | enum + finite number/no | Operator lt|lte|gt|gte|outside; deterministic comparison must be true. |
analysisPolicyId, analysisPolicyVersion | string/no | Released trigger policy. |
evidenceRefs | SourceRef[], 1–32/no | Immutable Analytics/Caliper/Content receipts; no copied metrics. |
status | enum/no | pending|accepted|replayed|blocked_upstream|rejected|superseded|unknown. Accepted/replayed require targetReceipt. |
targetReceipt | SourceRef/yes | Bank/Blueprint acknowledgement; null only before acknowledgement or when blocked. |
supersedesRevisionOrderId | string/yes | Same-tenant prior order; null if none. |
createdAt, updatedAt | Instant/no | Lifecycle timestamps; updatedAt ≥ createdAt. |
Every subject, threshold, action, target, and acknowledgement field is required by ITD-038; workflow-only persistence is constrained by ITD-039.
| Field | Type/null | Rule |
|---|---|---|
data | RevisionOrder[], no | 0–100 rows belonging to the path run and verified tenant. |
nextCursor | string 1–2048/yes | Opaque tenant/auth/run/filter-bound cursor; null at end. |
hasMore | boolean/no | Exactly nextCursor != null. |
observedAt | Instant/no | Composition time. |
| Field | Type/null | Rule |
|---|---|---|
mediaType | enum/no | application/zip|application/json. |
sha256 | 64 lowercase hex/no | Digest of immutable receipt bytes. |
downloadUrl | HTTPS URL/no | Short-lived, tenant-authorized URL; contains no credential in the JSON other than the opaque expiring signature. |
expiresAt | Instant/no | Strictly after response observedAt; clients must re-fetch metadata after expiry. |
Bundles contain owner artifact references, per-source contributions, versions, threshold decisions, order lifecycle, receiver receipts, omissions, and digest—never credentials or learner facts. ITD-040.
| Field | Type | Required | Rule |
|---|---|---|---|
| attemptId | Platform3 ref | Yes | Scored QTI attempt in verified tenant/scope · ITD-002. |
| administrationId | Platform3 ref | Yes | Must correlate; mismatch is safe validation failure · ITD-004. |
| view | enum | No | summary default, standards, evidence; response projection only. |
| Input | Type | Required | Rule |
|---|---|---|---|
administrationId path | Platform3 ref | Yes | One scored administration in the verified tenant and caller scope. |
Idempotency-Key header | 1–255 visible ASCII | Yes | Tenant+method+concrete path scoped; deterministic replay returns the same run id and current representation. |
| request body | none | No | Must be absent or zero bytes. Policy and formula are server-released configuration, not caller-selected inputs; a nonempty body returns validation 400. |
The path grain, mandatory idempotency, and versioned policy requirement are fixed by ITD-016 and ITD-038. No caller policy field is invented.
| Field | Type/null | Rule |
|---|---|---|
| data | AttemptReport[], no | 0–100 summary rows; candidate matches path. |
| nextCursor | string 1–2048/yes | Opaque, tenant/auth/filter-bound; null at end. |
| hasMore | boolean/no | Exactly nextCursor != null. |
| observedAt | Instant/no | Page composition time. |
| sources | SourceRef[]/no | Results and identity receipts. |
| Query | Applies | Type/default | Validation |
|---|---|---|---|
| view | attempt detail/materialize | enum/summary | summary, standards, evidence. |
| qtiTestId | candidate list | ref/omitted | Exact native QTI test-id match. This is the wire name for the testId filter concept in ITD-035; testId itself is unsupported because ITD-003 forbids aliases. |
| testKind | candidate list | enum/omitted | mastery_gate, adaptive_diagnostic, formative; matched against authoritative Results→Content data, never caller or fixture labels. |
| status | candidate list | enum/omitted | scored or indeterminate; exact match. |
| status | revision-order list | enum/omitted | Exact RevisionOrder status; response-only unknown cannot be requested. |
| targetModule | revision-order list | enum/omitted | bank or blueprint. |
| modifiedSince | candidate list | Instant/omitted | Inclusive Results modification lower bound. |
| sort | candidate list | enum/-modifiedAt | Only -modifiedAt; attemptId ascending tie-break. |
| limit | candidate or revision-order list | integer/25 | 1–100; no sign, decimal, whitespace, repeat. |
| cursor | candidate or revision-order list | opaque/omitted | Binds tenant, authorization fingerprint, resource id, normalized filters, sort, and limit. Changed, expired, tampered, or wrong-principal cursors return validation 400. |
Every returned row satisfies every supplied filter after authorization. No match returns 200, data: [], nextCursor: null, and hasMore: false. Any unknown query name—including testId—returns the typed unsupported-parameter 400; it is never ignored. Alignment detail and ImprovementRun detail accept no query parameters.
Native ids: ITD-003; query and paging rules: ITD-018; list release gate: ITD-027; server-enforced filter invariants and cursor binding: ITD-035; improvement list shape: ITD-040.
| Field | Type/null | Rule |
|---|---|---|
| type | absolute HTTPS URI/no | Stable, dereferenceable URI. |
| title | string 1–120/no | Stable summary; do not branch on text. |
| status | integer 400–599/no | Equals HTTP status. |
| detail | string 1–1000/no | No cross-tenant existence or upstream body. |
| instance | URI-reference/no | Occurrence id, never tenant-data route. |
| requestId, traceId | string/no | Correlation. |
| retryable | boolean/no | Whether identical retry may succeed. |
| dependency | SourceRef service enum/yes | Non-null for dependency failures. |
| fieldErrors | array max 100/yes | Each: JSON Pointer pointer, stable code, safe message; null outside validation. |
| operationId | Operation id/yes | Non-null after materialization orchestration begins. |
| Type suffix | Status | Retry? | When |
|---|---|---|---|
| authentication-required | 401 | No | Missing/expired/invalid JWT. |
| authorization-denied | 403 | No | Valid token lacks permission scope. |
| not-found | 404 | No | Missing or outside claims; identical detail. |
| validation | 400 | No | Malformed or invalid known field, query, or header; fieldErrors identifies each location. |
| unsupported-parameter | 400 | No | Unknown query parameter or unsupported sort; fieldErrors points to the rejected name. |
| idempotency-conflict | 409 | No | Same key, different request. |
| source-version-conflict | 409 | Yes | Authoritative versions fail to converge. |
| dependency-unavailable | 503 | Yes | Required service unavailable/gate closed. |
| dependency-incomplete | 503 | Yes | Required settled fact absent, including an attempt with no settled Results record. |
| internal-error | 500 | Yes | Unexpected safe boundary failure. |
The base nine symbolic types and RFC 9457 envelope are pinned by ITD-023; unsupported-parameter is added by ITD-035; missing settled facts follow ITD-002.
tenant_id. Service-role credentials remain server-side; anonymous browser access is denied. ITD-001, ITD-026, ITD-039.reports.operation_control NOT CREATED UNTIL B+C| Column | PostgreSQL/null | Constraint/index | Meaning |
|---|---|---|---|
| tenant_id | text/no | part of PK/every index | Verified JWT tenant only. |
| method | text/no | check POST | Canonical operation. |
| canonical_path | text/no | check /v1/attempt-reports:materialize | No query/body. |
| key_hash | bytea/no | 32 bytes; composite PK | SHA-256; raw key never stored. |
| request_hash | bytea/no | 32 bytes | Canonical request hash. |
| operation_id | text/no | unique in tenant | Retry correlation. |
| lifecycle_state | text/no | enum check | started, results_written, caliper_emitted, completed, failed. |
| downstream_key_hashes | jsonb/no | service→SHA-256 | No raw keys/learning ids. |
| terminal_status_code | smallint/yes | 200 or 4xx/5xx | Null before terminal; no body. |
| created_at, updated_at, expires_at | timestamptz/no | expiry index; expires +24h | Hard retention. |
Retention: delete at 24 hours. Indexes: composite primary key (tenant_id,method,canonical_path,key_hash), unique (tenant_id,operation_id), and (tenant_id,expires_at). Owner: Reports attempt-write control per ITD-020/024/026.
reports.improvement_run_control NOT CREATED UNTIL F+D| Column | PostgreSQL/null | Constraint/index | Meaning |
|---|---|---|---|
| tenant_id | text/no | PK prefix/every index | Verified JWT tenant only. |
| improvement_run_id | text/no | PK with tenant_id | Opaque run id. |
| administration_id | text/no | unique (tenant, administration, policy version) | Native Administration ref, not copied administration data. |
| content_test_spec_id, content_test_spec_version | text/no | lookup index with tenant | Native immutable Content refs. |
| analysis_policy_id, analysis_policy_version, formula_version | text/no | nonempty checks | Immutable policy identifiers. |
| lifecycle_status | text/no | enum check | queued, analyzing, completed, completed_with_omissions, blocked_upstream, failed. |
| idempotency_key_hash, request_hash | bytea/no | 32 bytes; unique (tenant,key hash) | Raw key/body never stored. |
| metric_status_refs | jsonb/no | schema check; max 4 | Metric name/status plus immutable owner artifact refs only; no metric values/counts. |
| named_source_keys | jsonb/no | array of unique strings | Complete immutable named-source key set, no crosswalk copy. |
| omission_codes | jsonb/no | enum-array check | Explicit unavailable metrics. |
| receipt_sha256, receipt_object_ref | bytea + text/yes | both null or both non-null; digest 32 bytes | Content address and server-side object ref; no signed URL persisted. |
| created_at, updated_at, completed_at | timestamptz; completed nullable | tenant lifecycle index | Workflow timestamps; completed_at only terminal. |
Primary key (tenant_id,improvement_run_id). Unique (tenant_id,idempotency_key_hash). Indexes (tenant_id,administration_id,created_at desc) and (tenant_id,lifecycle_status,updated_at). No retention period is invented: deletion follows the privacy/retention policy when it is released, and the table cannot ship before that policy is pinned. Owner: Reports engine control state only, ITD-039.
reports.alignment_receipt_control NOT CREATED UNTIL F+D| Column | PostgreSQL/null | Constraint/index | Meaning |
|---|---|---|---|
| tenant_id, improvement_run_id | text/no | composite FK to improvement_run_control | Tenant-safe owning run. |
| source_key | text/no | PK suffix | Immutable named-source key. |
| source_assessment, source_version | text/no | nonempty checks | Named external test identity. |
| crosswalk_hash | bytea/no | 32 bytes | Content-owned crosswalk digest, not copied rows. |
| formula_version | text/no | nonempty | Applied structural formula. |
| receipt_sha256, receipt_object_ref | bytea + text/no | digest 32 bytes | Immutable bundle address and server-side ref; per-requirement contributions live in the receipt, not this table. |
| predicted_actual_artifact_ref | text/yes | native Analytics ref | Null when no authenticated external-score artifact exists. |
| created_at | timestamptz/no | tenant/run index | Receipt creation time. |
Primary key (tenant_id,improvement_run_id,source_key). This table stores proof pointers, not crosswalk contributions, scores, or aggregate values. Owner: Reports evidence-control state under ITD-037/039/040.
reports.revision_order_control NOT CREATED UNTIL F+D| Column | PostgreSQL/null | Constraint/index | Meaning |
|---|---|---|---|
| tenant_id, improvement_run_id | text/no | composite FK to improvement_run_control | Tenant-safe owning run. |
| revision_order_id | text/no | PK suffix | Deterministic order id. |
| target_module, requested_action | text/no | compatible-enum check | Bank/Blueprint target and allowed action. |
| native_subject_refs | jsonb/no | schema check | QTI/Content/CASE/source ids only; no copied objects. |
| reason_codes | jsonb/no | nonempty enum array | Deterministic trigger reasons. |
| policy_version, formula_version | text/no | nonempty | Immutable decision versions. |
| threshold_comparison | jsonb/no | name/operator/value/unit schema | Observed value and released threshold only; no student facts. |
| evidence_refs | jsonb/no | nonempty SourceRef-shaped array | Immutable owner evidence pointers. |
| lifecycle_status | text/no | enum check | pending, accepted, replayed, blocked_upstream, rejected, superseded. |
| delivery_attempts | integer/no | ≥0 | Receiver attempt counter. |
| target_receipt_ref | jsonb/yes | SourceRef shape | Bank/Blueprint acknowledgement only. |
| supersedes_revision_order_id | text/yes | same-tenant FK | Prior workflow order; null if none. |
| created_at, updated_at | timestamptz/no | tenant/status index | Lifecycle timestamps. |
Primary key (tenant_id,improvement_run_id,revision_order_id). Indexes (tenant_id,target_module,lifecycle_status,updated_at) and (tenant_id,improvement_run_id,created_at). Owner: Reports workflow control; receiver resources remain Bank/Blueprint-owned, ITD-038/039.
HTTP bytes only, maximum 30 seconds, keyed by tenant hash + authorization fingerprint + canonical request + source validators. Never persisted or reused across authorization fingerprints.
| Endpoint | Input / post-gate success | Scope | Endpoint-specific failures | Provenance |
|---|---|---|---|---|
| GET/v1/attempt-reports/{attemptId} | ref + view; 200 AttemptReport | reports:read + candidate intersection | Not released C+D; then validation 400, not-found 404, source-version-conflict 409, dependency-unavailable or dependency-incomplete 503 | ITD-004/023/028 |
| GET/v1/candidates/{candidateSourcedId}/attempt-reports | allowlisted query; 200 AttemptReportPage | reports:read + candidate claim | Not released C+D+index; then validation or unsupported-parameter 400, not-found 404, dependency-unavailable or dependency-incomplete 503 | ITD-018/027/028/035 |
| GET/v1/classes/{classSourcedId}/cohort-report | ref; 200 CohortReport | reports:read + class claim + OneRoster | Not released A+D; then not-found 404, dependency-unavailable or dependency-incomplete 503; never local aggregate | ITD-009/023 |
| GET/v1/schools/{schoolSourcedId}/grades/{grade}/cohort-report | school ref + OneRoster grade; 200 CohortReport | reports:read + school claim + OneRoster | Not released A+D; then 400 unknown grade | ITD-009 |
| GET/v1/forms/{qtiTestId}/equivalence | ref; 200 EquivalenceReport | reports:read + authorized form | Not released A+D; then 404,503 | ITD-010 |
| GET/v1/attempt-reports/{attemptId}/readiness | ref; 200 ReadinessReport | reports:read + candidate claim | Not released C+D; then not-found 404, source-version-conflict 409, dependency-unavailable or dependency-incomplete 503 | ITD-011/023/028 |
| POST/v1/attempt-reports:materialize | JSON body + key; 200 operationId+AttemptReport | reports:write + candidate/admin | Not released B+C+D; then validation 400, not-found 404, idempotency-conflict or source-version-conflict 409, dependency-unavailable or dependency-incomplete 503 | ITD-002/020/023/028/032 |
| POST/v1/administrations/{administrationId}/improvement-runs:analyze | No body + Idempotency-Key; 200 ImprovementRun; replay adds Idempotent-Replayed | reports:write + administration claim | Not released F+D; then validation 400, not-found 404, idempotency-conflict or source-version-conflict 409, dependency-unavailable or dependency-incomplete 503 | ITD-016/020/038/040 |
| GET/v1/improvement-runs/{improvementRunId} | ref; 200 ImprovementRun | reports:read + run tenant/admin scope | Not released F+D; then not-found 404; dependency-unavailable/incomplete 503 when required evidence refs do not dereference | ITD-039/040 |
| GET/v1/improvement-runs/{improvementRunId}/alignment-reports/{sourceKey} | refs; 200 AlignmentReport | reports:read + run tenant/admin scope | Not released F+D; then validation 400, not-found 404, source-version-conflict 409, dependency-unavailable/incomplete 503 | ITD-037/040 |
| GET/v1/improvement-runs/{improvementRunId}/revision-orders | allowlisted query; 200 RevisionOrderPage | reports:read + run tenant/admin scope | Not released F+D; then validation or unsupported-parameter 400, not-found 404, dependency-unavailable/incomplete 503 | ITD-038/040 |
Authentication-required 401, authorization-denied 403, and internal-error 500 apply to every route. A missing id and the same id outside verified tenant/claims both return the identical non-enumerating 404. Success uses application/json; errors use application/problem+json. No endpoint accepts a tenant selector. Payload-size and unsupported-media-type behavior remain uncommitted and therefore are not invented here.