AcmeTest maintainer
The engineer integrating generated tests and diagnostics into a thin Platform3 app.
Architecture decisions for the API an AcmeTest maintainer uses to turn an existing Platform3 QTI delivery session into a deterministic diagnostic, a cross-grade mastery scale score, and an explicit KC gap map.
The engineer integrating generated tests and diagnostics into a thin Platform3 app.
Advance a diagnostic across QTI-scored item sessions and receive Results-native mastery evidence without computing scores in AcmeTest.
AlphaTest owns selection policy and calibration only. QTI owns sessions/responses; Results owns mastery; Caliper owns the event trail; CASE owns standards.
Identical scored streams select identical items and outcomes. Simulated known mastery is recovered within each calibration version’s published tolerance.
An adaptive run is a stateless composition identified by an authenticated-encrypted, opaque continuationToken (JWE). The token carries only native references, hashes, per-offer pseudonymous QTI candidate/session ids, sequence, expiry, and a random nonce; it carries no response values or mastery estimates and is never persisted by AlphaTest. Each offered item is a real Platform3 QTI delivery session, and each response is scored by the QTI player before AlphaTest consumes it.
adaptivePool contract plus a redacted 200 receipt and independent QTI-root reconciliation; it does not require a Mastery deployment that cannot exist until the implementation cell. From implementation onward, v1 is not releasable with zero executable business routes: POST /v1/adaptive-runs, inspect, advance, and score-recovery MUST be present and MUST pass the ITD-031 acceptance trace. Pool membership comes from GET /v1/bank-operations/{operationId}/manifest—never caller arrays or local inference. The supplied 2026-07-16 QTI root receipt remains a useful negative control, not release evidence.| Method and path | Purpose | Success | Concurrency / side effects |
|---|---|---|---|
| POST /v1/adaptive-runs | Start from immutable policy/calibration refs, Content test_spec/test_bank refs, and the terminal Bank operationId whose evidence manifest binds the QTI pool and every member. | MANDATORY SHIP; 201 with first native QTI deliverySessionId, continuation token, ETag, profile, and receipt id. A missing or incomplete owner manifest is a build/release failure, never an acceptable absent-route steady state. | Idempotency-Key required. No caller member list, response, score, or upstream token is accepted. |
| POST /v1/adaptive-runs:inspect | Validate a continuation token, reread its Content identity, QTI pool/version/runtime, and CASE sources, and compose current classifications. | 200 + strong ETag over token pins, canonical QTI pool projection, and attempts. | Read-through only; no local student cache, pool copy, or lookup index. |
| POST /v1/adaptive-runs:advance | Consume newly scored QTI attempts named by the token, update posterior, then stop or create exactly one QTI item session. | 200 with in_progress, or finalizing until Results KC write is bound. | Idempotency-Key and If-Match required; request-scoped advisory serialization by token nonce. |
| GET /v1/selection-policies/{policyId} | Read immutable selection, classification, coverage, and stopping rules used by an adaptive run. | 200 | Tenant-scoped or published-system policy; immutable version. |
| GET /v1/scale-calibrations/{calibrationId} | Read provenance, validity window, item/KC parameters, scale transform, anchor source, tolerance, and limitations. | 200 | Never returns licensed anchor payloads the caller is not entitled to see. |
| POST /v1/score-recovery-simulations | Run the bounded deterministic known-mastery harness against the owner-backed immutable QTI adaptive pool. | MANDATORY SHIP; 200 includes tolerance verdict, trace receipt, and acknowledged Caliper evidence. | Idempotent and synchronous within published caps; synthetic profiles only; no Results learner write. |
Every required axis is pinned. “Deferred” is a deliberate contract: the named trigger must occur before reconsideration.
| Axis | Decision | State | ITD |
|---|---|---|---|
| Write granularity | Per-resource start/advance/inspect/simulate; no bulk writes. | SHIP | ITD-003 |
| Read shape | Policy/calibration detail plus bounded run composition; no lists or sub-collections. | SHIP | ITD-004 |
| Query model | No search, filter, sorting, cursor, or modifiedSince on this surface. | DEFERRED | ITD-005 |
| Concurrency | Strong ETag, required If-Match, and request-scoped advisory serialization by token nonce. | SHIP | ITD-006 |
| Idempotency | Required key on every POST; deploy-wide 24-hour request fingerprint; deterministic operation identity and upstream keys; semantic replay. | SHIP | ITD-007 |
| Auth shape | Verified JWT: issuer/audience + role + scopes + tenantId + sub. | SHIP | ITD-008 |
| Eventing | Client polls via :inspect; completion and recovery evidence emit to Caliper. No AlphaTest webhooks. | SHIP / DEFER | ITD-010 |
| Error envelope | Typed RFC 9457 problem details with stable type URIs and request IDs. | SHIP | ITD-009 |
| Tenant routing | Tenant only from verified JWT; never URL, header, or body. | SHIP | ITD-008 |
| Conformance evidence | Contract suite, deterministic replay, cross-tenant probes, upstream wire trace, simulation recovery. | SHIP | ITD-011 |
| Privacy / retention | No student facts in engine store; deletion delegated to owning upstream and auditable. | SHIP | ITD-012 |
| List endpoints | No collection lists; discover sessions/results through their owning services. | DEFERRED | ITD-004 |
| Engine decision | Pinned choice | ITD |
|---|---|---|
| Selection ownership vs delivery | AlphaTest owns deterministic selection; Platform3 QTI owns each selected item session, response, scoring outcome, and runtime read-back. | ITD-015 |
| Mastery estimate per KC | Versioned Bayesian posterior updated only from QTI-scored outcomes. | ITD-013 |
| Stopping rules | Policy-pinned classification, precision, coverage, maximum-item, and time rules with a named stop reason. | ITD-015 |
| RIT-like scale anchor | Monotonic mastery-scale transform with licensed NWEA anchor provenance, uncertainty, and no rank claim. | ITD-017 |
| Determinism and replay | Canonical QTI stream plus immutable policy, calibration, pool, mapping, and runtime versions. | ITD-016 |
| AlphaTest / Platform3 storage split | AlphaTest stores policy and calibration only; upstream systems retain all learner facts. | ITD-001 |
| Score-recovery harness | Bounded deterministic synthetic simulation with Caliper-persisted tolerance evidence. | ITD-021 |
| Blueprint and pool source | Content owns blueprint/bank identity and adaptive rule; the Bank evidence manifest projects the QTI-owned immutable package graph, native member versions, and CASE/KC tags. No Content adaptive member rows. | ITD-028 |
A calibration pins the item/KC parameters, priors, and monotonic vertical-scale transform. Scored QTI outcomes are the only observations. Missing or invalid parameters are a typed dependency error, never an inferred default.
mastered: posterior above the KC cut meets the policy confidence. gap: posterior below the cut meets it. not_yet: evidence remains insufficient. Thresholds live in the immutable policy.
Eligible QTI items must satisfy CASE/KC coverage, blueprint, exposure, accessibility, and prior-use constraints. Max expected posterior entropy reduction wins; the stable QTI identifier breaks exact ties.
Stop only on a versioned policy rule: all required KCs classified, precision target reached after coverage floors, max items, or time budget. Response names the rule and unmet constraints.
Return scaleScore, standardError, scale/calibration IDs, anchor provenance, validity window, and crosswalk limitation. Never return percentile or rank.
Filter candidate runtime data to token-named sessions; order by offered-session sequence, attempt number, and attempt id; reject conflicts; pin policy, calibration, Content identity hash, QTI root ETag/version, ordered resolved member-version/KC hash, CASE mappings, and runtime version.
| Upstream | Wire obligation | Owns | Fail-closed condition |
|---|---|---|---|
| Platform3 Content | BOUND FOR IDENTITY: authenticated tenant-scoped reads resolve the test_spec blueprint and test_bank identity/rule. For qti_adaptive_selection, data must be empty; Content rows are never interpreted as pool members. | Blueprint, bank identity, association, and membership rule—not adaptive membership. | Wrong tenant, bank/spec mismatch, rule other than qti_adaptive_selection, any adaptive bank_member row, or identity-hash drift. |
| AlphaTest Bank + Platform3 QTI | MANDATORY OWNER COMPOSITION: read the terminal Bank evidence manifest, require its package-bound ordered member projection, then independently read the exact immutable QTI assessment-test version and verify a bijection by package-scoped QTI identifier and native artifact version. Create one QTI item session per selected member and read scored runtime. | Bank owns generated-slot provenance and the downloadable projection; QTI owns package structure, immutable member identities, sessions, responses, scored outcomes, and processing traces. | Absent/non-terminal manifest; root/version/package-hash mismatch; unresolved/duplicate ref; empty member/CASE/KC arrays; projection drift; missing token-named session; unscored/conflicting attempt. Any condition fails the release trace. |
| Platform3 CASE 1.1 | Resolve live CASE GUIDs, KC relationships, and framework provenance. | Standards and competency graph. | Unknown, deleted, or cyclic mapping; calibration framework mismatch. |
| Platform3 Results | Idempotent upsert of one result_record with per-KC test_result_components. | Durable student mastery and result facts. | Write not acknowledged; final response remains finalizing, never falsely completed. |
| Platform3 Caliper endpoint | Emit learner completion after Results acknowledgement; persist synthetic recovery as a non-learner conformance event and read it back. | Learning-event trail and immutable synthetic evidence receipt. | Event or read-back rejection; completion remains finalizing or simulation fails. |
| NWEA MAP module / licensed anchor source | Fetch the exact immutable anchor version named by calibration and verify entitlement/checksum. | Licensed RIT/grade norm source and its permitted crosswalk inputs. | Missing license, version, checksum, validity, or subject/grade coverage. |
502 qti-adaptive-pool-invalid; changed pinned projection is 409 adaptive-pool-version-drift; absence during deployed smoke fails release rather than legitimizing a zero-route API.Download the machine-readable manifest. Each required capability pins an approved method/path, server-held credential profile, normalized response, acknowledgement, and reviewed source. The provisioned Platform3 service JWT is the operative credential; no nonexistent token-exchange primitive gates the product. Review date: 2026-07-17.
| Operation | Status | Reviewed wire binding or gap | Release effect |
|---|---|---|---|
platform3.provisioned_service_jwt | BOUND | Server-held PLATFORM3_TENANT + PLATFORM3_JWT + approved service base URLs; reject a client tenant that has no matching provisioned profile. Never forward the AcmeTest JWT. | Enables the owner-backed demo and learner flow now; migrate only if Platform3 later publishes an exchange. |
content.read_test_spec | BOUND | GET /tenants/{tenantId}/alpha/content/items/{testSpecId}/blueprint; published read:content contract and observed 200 envelope. | Transport ready; exact projection is canonically hashed. |
content.validate_adaptive_bank_identity | BOUND | GET /tenants/{tenantId}/alpha/content/items/{testBankId}/bank-members; use only bank_id, spec_id, membership_rule, updated_at and require data=[]. | Validates Content identity/rule without inventing adaptive members. |
qti.read_adaptive_pool_root | BOUND + 200 RECEIPT | GET /tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/delivery-json; require the Bank-returned native version, ETag equality, qti-assessment-test, and ordered item refs. | Proves the QTI-owned root; see downloadable receipt. |
bank.read_adaptive_pool_manifest | MANDATORY CONTRACT | GET /v1/bank-operations/{operationId}/manifest; terminal adaptive evidence must contain root package/artifact/version/hash and ordered members with native artifactId/artifactVersionId, QTI identifier, non-empty caseStandardGuids[], and non-empty knowledgeComponentGuids[]. | Must pass before architecture-to-implementation approval; cannot become an absent-route steady state. |
case.resolve_mapping | BOUND | GET /ims/case/v1p1/CFItems/{sourcedId}; tenant comes only from JWT. | Live KC identity available. |
nweamap.verify_anchor | BOUND | GET /nweamap/v1/r90 with pinned tableVersion and exact sourceRef. | RIT-to-grade anchor available; no rank output used. |
results.write_result_record | BOUND | POST /alpha/results/v1/result-records with Results idempotency acknowledgement. | Base outcome write available. |
qti.read_candidate_runtime | BOUND | GET /tenants/{tenantId}/qti/candidates/{candidateRef}/runtime-data; token session ids bound the projection. | Deterministic scored stream available. |
qti.offer_selected_item | BOUND | POST /tenants/{tenantId}/qti/delivery-sessions with selected immutable artifact version. | Each selection is a real QTI session. |
qti.score_item_attempt | BOUND | AcmeTest player calls POST .../delivery-sessions/{id}/attempts; engine consumes QTI outcome and trace. | Published scoring boundary; no invented close call. |
results.write_kc_components | UPSTREAM GAP | No callable atomic/idempotent per-KC component write and acknowledgement for a trusted scorer. | Additional learner-completion blocker. |
caliper.emit_completion_or_simulation + read ack | BOUND | POST /caliper/v1p2/events, then read by eventIri; synthetic payload has no learner identity. | Completion audit and recovery evidence available. |
404 resource-not-found envelope.Provenance: ITD-001 through ITD-027 were authored by alphatest-loop on 2026-07-16. ITD-028 through ITD-031 were authored on 2026-07-17 from integration evidence and triage decision 2026-07-17-001. Superseded decisions remain visible; links are symmetric.
Chosen: AlphaTest stores only immutable/versioned selection policies and scale calibrations; every learner fact is read from or written to Platform3 systems of record.
Rejected: shadow attempts (simpler reads, split truth); local mastery cache (faster, stale and privacy-bearing); event-sourced learner ledger (powerful, directly violates ownership). This preserves the product’s thin-platform promise and makes a QTI session the single correlation key.
Chosen: An A256GCM authenticated-encrypted compact JWE continuation identifies the adaptive composition and carries only tenant-bound native refs, configuration/content hashes, per-offer pseudonymous QTI candidate/session ids, sequence, iat/exp, kid, and a random nonce; AlphaTest persists no run row.
Rejected: AlphaTest run UUID plus database row (shadow learner state); one QTI session as run identity (QTI exposes no adaptive append contract); signed-only or caller-editable continuation (confidentiality, integrity, and cross-tenant risk). Tokens last 24 hours, renew on valid advance, have a 7-day absolute lifetime, and accept the current plus previous key by kid during rotation. They never contain responses, posterior values, or scores.
Chosen: start, advance, inspect, and bounded synthetic simulation are individual POST operations; no bulk write ships.
Rejected: bulk-only (blocks live delivery); both bulk and single (two semantics for no job gain). Reopen bulk only when one registered audience must initialize ≥500 diagnostics in one transaction and every required upstream offers atomic bulk operations.
Chosen: Detail-only reads ship for policy and calibration; adaptive state is a bounded detail composition returned by :inspect/:advance, with KC classifications embedded; no collection list or sub-collection ships.
Rejected: list + detail (duplicates QTI/Results discovery); sub-collection endpoints (pagination complexity without an audience job); GET with a bearer continuation in the URL (token leakage). Reopen a list only when AcmeTest cannot discover the required native reference upstream.
Chosen: lookup by exact immutable identifier only.
Rejected: filter/sort and cursors because there are no public collections; modifiedSince because QTI/Results/Caliper already own change feeds. Reopen when a shipped list endpoint has a measured payload above 1 MB or a current consumer needs incremental sync not supplied upstream.
Chosen: Inspect/start return a strong ETag over token pins and canonical token-named QTI attempts; advance requires exact If-Match and acquires a tenant-scoped advisory lock on the token runNonce only for the request.
Rejected: last-write-wins (double offers); a persisted run lock/row (learner glue becomes state); dependence on nonexistent QTI conditional offer. A mismatch is 412 with no side effect; the advisory lock stores no learner fact and expires at request end.
Chosen: Every POST requires a 1–255 character Idempotency-Key. Before any side effect, one server-only Postgres transaction inserts or reads a 24-hour control record uniquely keyed by (tenant_id, method, canonical_path, HMAC(server_secret, key)) and containing only canonical_request_hash, operation_id, lifecycle state, terminal status, and timestamps—never a response, answer, score, candidate id, session id, or result id. A different canonical request hash returns 409 idempotency-key-reused before upstream work. The same hash resumes/recomposes semantically: runNonce, QTI candidate refs, operation id, and downstream idempotency keys derive deterministically from the scoped key plus request hash, and the engine rereads authoritative upstreams rather than replaying stored learner data. The table is API-fronted, tenant-scoped, inaccessible to anon/authenticated browser roles, and purged after 24 hours.
Rejected: process-local memory (cannot enforce 409 or dedupe across serverless instances); a learner-bearing response cache (violates the storage split); optional keys (unsafe retries); byte-for-byte historical replay (requires forbidden payload persistence); artifact-only QTI dedupe (ambiguous on legitimate reuse). This is the minimum durable mechanism that makes the published 409 and retry behavior deploy-wide.
Chosen: verify signature, iss, aud, exp; require sub, role, tenantId, and endpoint scopes (mastery:run, mastery:read, mastery:simulate). Every upstream lookup is tenant-qualified.
Rejected: role-only (too broad); tenant header/path/body (spoofable); browser datastore keys (public data path). Anonymous is 401; valid but insufficient scope is 403; cross-tenant resource probes are 404.
Chosen: application/problem+json following RFC 9457: type, title, status, detail, instance, code, requestId, retryable, and optional invalidParams/currentEtag/upstream.
Rejected: ad hoc JSON (unstable); opaque 500 (hides upstream gaps); exposing raw upstream bodies (secrets/PII). Stable types include invalid-request, precondition-required, stream-conflict, upstream-unavailable, calibration-invalid, and finalization-incomplete.
Chosen: clients call :inspect with the continuation token for current detail; AlphaTest emits acknowledged completion and synthetic recovery evidence to Caliper.
Rejected: AlphaTest webhooks (new delivery ledger, signing, retry state); SSE (poor serverless fit); no Caliper emission (breaks audit trail). Reopen outbound webhooks when a registered integrator cannot consume Platform3 events and has a measured completion-SLA missed by inspect polling.
Chosen: publish an OpenAPI contract suite; replay golden streams across process restarts; probe anonymous/cross-tenant access; capture upstream host/operation/request IDs; run known-mastery simulations with calibration-specific tolerance.
Rejected: unit tests alone (cannot prove integration); screenshots (behavior, not wires); self-attestation (not auditable). External consumer integration is mandatory before release.
Chosen: policy/calibration tables contain no candidate, session, response, or result fields. Logs redact tokens, item response values, candidate identifiers, and request bodies; correlation IDs expire under the platform operational-log policy.
Rejected: DELETE façade (pretends ownership); local retention windows (still duplication); analytics copy (Results/Analytics owns it). Erasure is routed to QTI/Results/Caliper owners, with their deletion receipts composed for audit.
Chosen: calibration pins posterior model family, priors, item/KC parameters, scoring transform, numeric precision, and runtime version; only QTI-scored outcomes update it.
Rejected: percent-correct (not adaptive/comparable); unversioned ML service (not replayable); LLM judgment (non-deterministic and unauditable). Unknown item parameters or CASE mappings fail with calibration-invalid.
Chosen: policy pins KC cut score and confidence threshold. Above-cut confidence yields mastered; below-cut confidence yields gap; everything else is not_yet, always with posterior probability and evidence item refs.
Rejected: binary default (false certainty); norm percentile (wrong question); inferred standard labels (CASE owns labels). Standard rollups reference live CASE GUIDs and expose mapping version.
Chosen: filter by blueprint/CASE coverage, accessibility, exposure, prior use, and pool eligibility; choose maximum expected posterior entropy reduction; stable QTI ID breaks ties. Policy pins coverage floors, precision, classification, max-item, and time rules.
Rejected: random tie breaks (not replayable); difficulty staircase (weak multidimensional evidence); opaque vendor CAT (cannot explain gaps). Every completion states stopReason and remaining uncertainty.
Chosen: Filter QTI runtime data to token-named sessions; order by token offer sequence, attemptNumber, then attemptId; canonicalize numbers; reject conflicts; pin policy/calibration, Content identity hash, QTI root artifactVersionId/ETag, ordered resolved member-version/CASE/KC hash, CASE mapping, runtime versions, and stable tie-breaking.
Rejected: candidate-wide receipt order (unrelated sessions and network sensitivity); mutable latest aliases (irreproducible); seeded randomness (unnecessary state). Replay returns the selected sequence, posterior checkpoints, final score, and source hashes.
Chosen: a calibration applies a monotonic vertical transform to the posterior and includes standard error, anchor source/version/checksum/license scope, subject/grade coverage, validity, recovery tolerance, and limitations.
Rejected: claim of official MAP RIT identity (unsupported); percentile output (norms-based); unanchored fallback score (misleading continuity). Anchor failure blocks scale publication but may return provisional KC posteriors marked non-reportable.
Chosen: Content, QTI, CASE, Results, Caliper, and NWEA-anchor capabilities use server-side base URLs, but only manifest operations backed by a reviewed live contract and passing wire probes may be status=bound; runtime traces resolved host/operation/request ID without payloads.
Rejected: guessed vendor paths (fabrication); local adapters labeled Platform3 (DoD failure); silent fallback (false evidence). Missing required operation is a typed 424 dependency problem and release blocker.
Chosen: production_learner completed means every token-named QTI item attempt is submitted and scored, Results acknowledges the result_record and every per-KC component, and Caliper completion is read back; owner_conformance completed is explicitly synthetic and requires the same QTI scoring plus Caliper conformance read-back but creates no learner Results fact. Neither status claims QTI delivery sessions are closed.
Rejected: nonexistent QTI close prerequisite (fabricated surface); fire-and-forget (lost outcomes); local outbox (learner state); completion before Results for a learner (lying contract); synthetic profiles written as students (pollution). Until a profile's acknowledgements exist, status is finalizing.
Chosen: /v1 path version; policy/calibration IDs are immutable versions; response additions are compatible; enum consumers must tolerate unknown values; removals/semantic changes require /v2 and migration window.
Rejected: date headers (harder cold integration); mutable resources (break replay); unversioned endpoints (Hyrum risk). Deprecation and sunset headers precede removal, with docs pinned per version.
Chosen: POST runs a bounded deterministic synthetic profile matrix synchronously and returns recovery errors, tolerance verdict, content hashes, and a Caliper eventIri/envelope hash read-back as the immutable evidence receipt.
Rejected: an asynchronous local job ledger (new state); real-student backtesting (privacy); QTI conformance rows relabeled as mastery evidence (wrong owner); CI-only evidence (not customer-downloadable). Requests above the published profile/item cap are 413.
Chosen: advance makes bounded parallel reads, then serialized QTI/write operations; published SLOs measure p95 excluding upstream time and end-to-end including it separately. Every upstream call has deadline, retry class, and correlation ID.
Rejected: stale local caches (ownership violation); unlimited retries (delivery stalls); success with partial data (false mastery). Retry only safe reads and idempotent writes with capped exponential backoff.
Chosen: Platform3 Content test_spec/test_bank remain the blueprint and bank identities; validate spec_id, bank_id, membership_rule=qti_adaptive_selection, and exactly zero Content bank_member rows. The adaptive pool source is the Bank-returned native QTI assessment-test artifactId/artifactVersionId. Read that immutable version with GET /qti/1edtech/implementation/api/tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/delivery-json; require HTTP 200, matching version/ETag, qti-assessment-test, and ordered item refs. Before selection, QTI must resolve each ref in that same immutable package graph to native member artifactId/artifactVersionId and canonical CASE standard/KC GUIDs. Hash SHA-256(rootArtifactVersionId, ETag, ordered(memberArtifactVersionId, qtiIdentifier, CASE GUIDs, KC GUIDs)), carry only the hash/native refs in the encrypted continuation, and reread before every offer. The root read is SHIP; member/KC resolution is DEFERRED until QTI publishes it.
Rejected: Content adaptive member rows (contradicts Bank’s approved zero-row contract); generic QTI artifact-list plus identifier/href joins (collisions and no package-scoped proof); caller item arrays (integrity risk); copied/local pool tables (duplicate truth); treating a root-only 200 as selection readiness (false D5 evidence). Reopen when the owner-published QTI response names the exact immutable member versions and CASE/KC GUIDs and a demo-tenant 200 receipt proves all refs resolve, repeat-read hashes match, a changed version produces a new hash, and anonymous/cross-tenant reads fail.
Chosen: upstream-bindings.json is the executable contract: each required capability maps to a published method/path, named workload-auth profile, tenant propagation, normalization, acknowledgement, source, and orchestration rule; route status and credential status are separate, and either gap keeps the capability unreleased with a concrete trigger.
Rejected: base URLs alone (reachability only); “forward Bearer JWT” without an issuer/exchange contract (the observed upstream 401); free-form environment JSON (uncertifiable); adapter code as contract (too late); invented one-to-one operations when a reviewed composition suffices. Manifest version and checksum are pinned per release.
Chosen: Keep both start and score-recovery simulation absent while qti.resolve_adaptive_pool_members is a gap; a root-only 200 is evidence of the seam, not a usable pool. owner_conformance ships only after a demo QTI pool read resolves every member version and CASE/KC attribution and the full trace ends in 200/201. production_learner additionally requires real-tenant workload authentication and Results acknowledgement of one durable component per CASE GUID. Read-only policy/calibration endpoints may ship independently.
Rejected: permanent public 424 business endpoints (not a product); Content-member fallback (cross-module contradiction); generic list scans (ambiguous); local/caller pools (fabrication); health or root-read status as readiness; completion before Results. Conformance reopens on the exact QTI member/KC receipt and full synthetic trace; production reopens on that receipt plus the two published contracts, bidirectional tenant isolation, and Results write/read-back.
Chosen: Use two non-interchangeable server-side auth profiles. owner_conformance may mint short-lived tokens only from each owner-published POST {serviceBaseUrl}/dev/mint?tenantId=demo route, only for synthetic runMode=conformance, and never exposes or accepts those tokens at the AlphaTest boundary. production_learner requires a Platform3-published real-tenant workload exchange yielding tenant-, audience-, and operation-scoped JWTs; until published it is DEFERRED and no production learner route exists. Neither profile forwards the AcmeTest JWT, accepts caller upstream credentials, or uses a broad cross-tenant bearer.
Rejected: forwarding the client JWT (observed 401); caller-supplied tokens (confused deputy); demo minting for real tenants; operator static tokens; one broad bearer; host reachability as readiness. Production reopens only after owner-published contract plus tenant-A success, anonymous denial, bidirectional isolation, least privilege, expiry/refresh, and redaction probes.
Chosen: The release receipt is one redacted tenant-scoped trace, not a health check: Content blueprint plus adaptive-bank identity/rule with zero members; QTI immutable root read plus complete member-version/CASE/KC resolution and stable repeat hash; QTI delivery-session create and scored-runtime reads; CASE and NWEA anchor reads; deterministic stop with replay hash; for production_learner, Results result_record plus one acknowledged component per CASE GUID; Caliper POST plus read-back; and a final AlphaTest 200/201 containing scaleScore, standardError, mastered, gap, not_yet, stopReason, and receiptId. Each span records profile, approved host, manifest operation id, HTTP status, upstream request id, native content/version IDs, fixture id/version, and response hash—never tokens, learner identifiers, responses, or scores.
Rejected: root-only or health-only readiness (vacuous); unit trace (no D5 proof); guessed/local upstream; Content adaptive members; payload-bearing logs; success before Results/Caliper acknowledgement. Synthetic conformance explicitly omits learner-only Results writes rather than faking them.
Chosen: POST /v1/adaptive-runs requires the terminal Bank operationId that produced the adaptive bank. Mastery Engine reads the approved GET /v1/bank-operations/{operationId}/manifest route with a server-held credential and requires one immutable adaptivePool projection: root packageId, artifactId, artifactVersionId, qtiIdentifier, and packageHash; plus an ordered non-empty members[] where every member carries native artifactId, immutable artifactVersionId, package-scoped qtiIdentifier, non-empty canonical caseStandardGuids[], and non-empty knowledgeComponentGuids[]. Mastery Engine independently reads the root QTI delivery JSON and requires an exact ordered bijection to that owner projection before selection. Content still contains zero adaptive bank_member rows.
Rejected: waiting for a new QTI endpoint (created the zero-route deadlock); joining a generic artifact list by href or identifier (ambiguous); caller-supplied members (integrity risk); Content adaptive members (contradicts Bank); local copies or inferred CASE/KC tags (DoD D5 failure). Bank already owns generation provenance and its terminal evidence route; extending that immutable evidence with the native projection is the narrowest owner-backed seam. Architecture approval requires a redacted timestamped 200 receipt, repeat-read ETag/hash equality, native IDs, complete arrays, and independent QTI-root reconciliation.
Chosen: architecture approval requires the positive Bank adaptivePool receipt and independent QTI-root reconciliation pinned in ITD-028, but not a deployed Mastery journey. Implementation and every later release require one owner-backed demo journey in which POST /v1/adaptive-runs returns 201, at least one native QTI delivery session is attempted and scored, advance reaches a documented policy stop, and the terminal response contains scaleScore, standardError, non-empty evidence plus explicit mastered, gap, and not_yet arrays, stopReason, and receiptId. Inspect, advance, and score-recovery publish with start. A missing owner projection routes rollback to Bank; from implementation onward it never authorizes absent business routes, permanent 404s or 424s, or a read-only configuration product.
Rejected: requiring a deployed journey before implementation exists (self-deadlocking sequencing); approving policy/config reads alone at implementation (does not do the customer’s job); permanent 404 or 424 business routes (documents failure as product); health/root receipts (no adaptive journey); local fixtures relabeled upstream (false integration). Reopen this invariant only if the mastery_engine module is removed from the product contract—not when an upstream is inconvenient.
Chosen: Platform3 calls use server-held service profiles consisting of approved base URLs, PLATFORM3_TENANT, and PLATFORM3_JWT; the verified AcmeTest tenantId must select a profile with the identical configured tenant before any upstream call. The client JWT is never forwarded, and callers cannot supply an upstream token, host, or tenant. The current deployment’s provisioned profile is sufficient for the executable owner-backed journey; support for additional tenants is server configuration, not a new public API primitive.
Rejected: a nonexistent workload-token exchange (self-inflicted deadlock); demo mint routes as production auth; forwarding client JWTs; caller-supplied tokens; one broad cross-tenant bearer. If Platform3 later publishes an exchange, migrate through a successor ITD only after the existing journey and tenant probes remain green.
Chosen: the release receipt is a redacted timestamped trace that an independent deployed smoke can replay: provisioned service-profile selection; Content blueprint/bank identity with zero adaptive Content members; Bank terminal manifest read with complete native member-version/CASE/KC projection; independent QTI root reconciliation and stable repeat hash; QTI delivery-session create and scored-attempt read; CASE and licensed anchor reads; deterministic offers and named stop; Caliper acknowledgement; and final AlphaTest 201/200 bodies containing the complete mastery result. The same suite creates one tenant-A run and one tenant-B run, proves each tenant’s own inspect succeeds, and proves A→B and B→A continuation replays return the same 404 resource-not-found envelope as an unknown run. Production learner completion additionally proves Results result_record/component acknowledgement; synthetic conformance never writes a learner Results fact.
Rejected: screenshots or unit-only evidence (no wire proof); a negative-control QTI root as release evidence; anonymous-only auth tests (miss cross-tenant leakage); shared configuration as tenant-data fixture (false test); payload-bearing logs; success before required acknowledgements. Every span records approved host, operation ID, HTTP status, upstream request ID, native version IDs, fixture version, ETag/hash, and timestamp—never credentials, learner identity, responses, or scores.