# QTI 1EdTech Surface QA Report

## Run

- Run id:
- Generated at:
- Operator:
- Agent:
- Base URL: `https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/implementation/api`
- Tenant mode: demo | real tenant
- Tenant id:
- JWT handling: raw token redacted; source was demo mint | operator secret

## Canonical Sources Cited

- Customer website quickstart: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/customer_website/#quickstart
- API contracts: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/customer_website/#api-contracts
- Data dictionary: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/data_dictionary/
- Implementation root: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/implementation/api

## Endpoint Evidence

| Step | Endpoint | Evidence file | Key returned values | Verdict |
|---|---|---|---|---|
| 0 | `checks/qti-surface-check.sh` |  | redacted `check-summary.json`, API-returned pinned answers |  |
| 1 | `POST /dev/mint?tenantId=demo` |  | `tenantId`, `demoCandidateRef`, `demoPackageZipUrl` |  |
| 2 | `POST /tenants/{tenantId}/qti/packages` |  | `packageId`, `artifactId`, `artifactVersionId` |  |
| 3 | `GET /tenants/{tenantId}/qti/packages` |  | `items`, `nextCursor` |  |
| 4 | `GET /tenants/{tenantId}/qti/artifacts` |  | `items`, `nextCursor` |  |
| 5 | `GET /tenants/{tenantId}/qti/artifact-versions` |  | `items`, `nextCursor` |  |
| 6 | `GET /tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/delivery-json` |  | `documentId` |  |
| 7 | `GET /tenants/{tenantId}/qti/artifacts/{artifactId}/authoring-json` |  | `ETag`, authoring envelope present |  |
| 8 | `PUT /tenants/{tenantId}/qti/artifacts/{artifactId}/authoring-json` |  | saved `artifactVersionId` |  |
| 9 | `GET /tenants/{tenantId}/qti/artifact-versions/{artifactVersionId}/xml` |  | nonzero XML bytes |  |
| 10 | `POST /tenants/{tenantId}/qti/delivery-sessions` |  | `deliverySessionId` |  |
| 11 | `POST /tenants/{tenantId}/qti/delivery-sessions/{deliverySessionId}/attempts` |  | `attemptId`, `outcomeState.SCORE`, processing trace |  |
| 12 | `GET /tenants/{tenantId}/qti/candidates/{candidateRef}/runtime-data` |  | session count, attempt count |  |
| 13 | `DELETE /tenants/{tenantId}/qti/candidates/{candidateRef}/runtime-data` |  | HTTP `204` |  |
| 14 | `POST /qti/conformance-runs` |  | `conformanceRunId`, `status`, assertion summary |  |

## Result Summary

- Package ingest:
- Delivery JSON:
- Authoring read/write:
- XML export:
- Session and attempt:
- Runtime-data cleanup:
- Conformance:

## Data Dictionary References

- `qti.content_package`: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/data_dictionary/#table-qti-content-package
- `qti.artifact_version`: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/data_dictionary/#table-qti-artifact-version
- `qti.attempt`: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/data_dictionary/#table-qti-attempt
- `qti.conformance_run`: https://platform3-andymontgomery-9773s-projects.vercel.app/qti/1edtech/data_dictionary/#table-qti-conformance-run

## Leak Check

Answer each item yes or no:

- Did the app/report avoid a local QTI parser?
- Did the app/report avoid a local scoring or response-processing engine?
- Did the app/report avoid copied schema, enum, norm, or database tables?
- Did the app/report avoid a local idempotency replay ledger?
- Did the app/report avoid local search, filtering, joins, and paging behavior beyond published surface endpoints?
- Did every result value come from a saved API response body?

If any answer is no, record the blocked job and route it as a surface leak instead of treating it as a skill-pack fix.

## Open Issues

- 
