# Platform 1EdTech Contract Map

Use these links as provenance when producing apps, reports, or QA notes. Most of the map names where to look rather than copying a surface's schema or business rules. The Incept section composes the existing Platform, Content, and Curriculum contracts into one producer handoff because no single module owns the whole workflow.

## Core Docs

- Customer website: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/
- Data dictionary: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/
- Architecture: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/architecture/
- Implementation API: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/implementation/api
- Skill manifest: /platform/1edtech/skill_pack/skill-pack.json
- Agent install: /platform/1edtech/skill_pack/pack/references/agent-install.md

## Auth And Errors

- Authentication overview: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#authentication
- Authorization header: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#auth-authorization
- Tenant claim: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#auth-tenant-id
- Idempotency-Key header: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#auth-idempotency-key
- Error envelope: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#errors
- Real-tenant token path: /platform/1edtech/skill_pack/pack/references/agent-install.md#credential-handoff

## Endpoint Sources

- Demo token: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-mintdemotoken
- List modules: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-listmodules
- Get module: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-getmodule
- Create tenant: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-createtenant
- Get tenant: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-gettenant
- List tenant audit rows: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-listauditlog
- Inspect idempotency key: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-getidempotency
- List producer surfaces: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-list-producer-surfaces
- Get Incept producer surface: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-get-incept-producer-surface
- List Incept progress: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-list-incept-progress
- List Incept projection checkpoints: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-list-incept-checkpoints

## Incept Producer-to-Platform Acceptance Envelope

Use this envelope for a Content or Curriculum handoff from Incept. It documents existing owners; it does not add an Incept acceptance endpoint. `/platform/producer-surfaces/incept`, `/progress`, and `/projection-checkpoints` are authenticated operational provenance and status reads. They never accept Content bytes, KC attribution, Curriculum placement, trust, QC receipts, or a release verdict.

### Before Content import

1. Freeze the exact source bytes. Record a stable producer source identifier, repository, revision, path, byte length, and SHA-256. The repository revision and path are provenance; they are not Content release-eligibility inputs.
2. Bind one `Idempotency-Key` to one exact import request identity: package SHA-256, byte length, and `X-QTI-Source-Name`. Send those same bytes to Content's existing QTI import route. Do not mint or derive a Platform `content_id` or `content_version_id` in producer code.
3. From a clean checkout at the declared producer revision, run the cohort's committed zero-write verifier. It must fail independently when source bytes, exact bank/form/question graph, Platform version tuples, governed KC facts, Curriculum scope/targets, or the producer QC artifact drift.

Content owns the import behavior: [QTI import probe](https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/skill_pack/pack/references/app-build-protocol.md#qti-import-probe).

### After Content import

1. Retain each `content_id`, `content_kind`, and immutable version UUID returned by Content. QTI import rows expose that UUID as `latest_version_id` at creation time; pin it as `content_version_id` in the handoff and never resolve a later mutable latest pointer.
2. Read or write governed attribution through `/items/{contentId}/kc-tags`: canonical active `kc_id`, independent `weight`, `is_primary`, `confidence`, and `provenance`. KC tags are item-scoped and version-invariant; a graph verifier may repeat them beside every exact question occurrence, but must not create question-version-scoped tag identity. Similarity or text-derived hints do not substitute for active governed tags.
3. Read back the exact bank-to-form-to-question graph where applicable. Give Curriculum only the exact `{content_id, content_version_id, content_kind}` target plus its governed component/KC references. Curriculum validates that tuple at authoring and again at launch; it never receives Content bodies or a copied verdict.
4. Ask Content for the current answer for every exact version:

   `GET /tenants/{tenantId}/alpha/content/items/{contentId}/versions/{versionId}/release-eligibility?producer_surface=incept%2Falpha`

   A success has exactly eight top-level fields: `content_id`, `content_version_id`, `content_kind`, `usage_scope`, `trust_status`, `serveable`, `release_eligible`, and `problem_code`. Continue only when identity and kind match the requested tuple, `usage_scope=practice_eligible`, `trust_status` is `trusted` or `degraded`, both booleans are `true`, and `problem_code` is `null`. Fail closed on any other response.

Producer QC and Content QC are deliberately separate. A producer QC artifact may be hash-bound provenance checked by the producer verifier. It is not Content's internal server-owned QC receipt, does not set `trust_status`, and is never appended to release eligibility. Content's QTI import or governed publication command performs Content QC and records the exact-version receipt; a later version cannot inherit it.

### Runnable preflight

Run the producer cohort verifier first, then run the installed Content Alpha verifier to prove the live eight-field contract:

```sh
node checks/verify-skill-pack.mjs
```

The canonical verifier is [Content Alpha `verify-skill-pack.mjs`](https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/skill_pack/pack/checks/verify-skill-pack.mjs). It proves the server contract on a governed fixture; it does not replace the cohort verifier. For every cohort tuple, make the exact eligibility read and fail unless this predicate succeeds:

```sh
: "${CONTENT_BASE_URL:=https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/implementation/api}"
: "${CONTENT_TENANT:?set CONTENT_TENANT}"
: "${CONTENT_TOKEN:?set CONTENT_TOKEN}"
: "${CONTENT_ID:?set CONTENT_ID}"
: "${CONTENT_VERSION_ID:?set CONTENT_VERSION_ID}"
: "${CONTENT_KIND:?set CONTENT_KIND}"

eligibility="$(curl -fsS -G \
  -H "Authorization: Bearer $CONTENT_TOKEN" \
  --data-urlencode "producer_surface=incept/alpha" \
  "$CONTENT_BASE_URL/tenants/$CONTENT_TENANT/alpha/content/items/$CONTENT_ID/versions/$CONTENT_VERSION_ID/release-eligibility")"

jq -e --arg content_id "$CONTENT_ID" --arg version_id "$CONTENT_VERSION_ID" --arg kind "$CONTENT_KIND" '
  (keys == ["content_id", "content_kind", "content_version_id", "problem_code", "release_eligible", "serveable", "trust_status", "usage_scope"]) and
  .content_id == $content_id and .content_version_id == $version_id and .content_kind == $kind and
  .usage_scope == "practice_eligible" and
  (.trust_status == "trusted" or .trust_status == "degraded") and
  .serveable == true and .release_eligible == true and .problem_code == null
' <<<"$eligibility" >/dev/null
```

Current producer examples are patterns, not extra acceptance lanes:

- [AP Human Geography PR #357](https://github.com/InceptTrilogy/ap-one/pull/357) demonstrates source-file hashes and a deterministic 16-article manifest. Its producer `qc_verdict` reference remains provenance, not the Content receipt.
- [AP Chemistry PR #358](https://github.com/InceptTrilogy/ap-one/pull/358) demonstrates a zero-write exact graph/digest verifier after Platform identities exist. Its accepted producer verdict still does not replace the eligibility read above.
- [AP Literature PR #356](https://github.com/InceptTrilogy/ap-one/pull/356) demonstrates snapshot/self-hash and coverage checks, but the PR explicitly leaves canonical KC IDs, weight, primary role, and confidence unresolved. Reuse the integrity pattern; do not treat that partial handoff as accepted.

Owner references:

- Content exact-version rule: https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/skill_pack/pack/references/app-build-protocol.md#exact-version-release-eligibility
- Content eligibility object: https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/data_dictionary/#object-content-release-eligibility
- Item-scoped KC relationship: https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/data_dictionary/#object-content-kc-tag
- Curriculum exact target rule: https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/skill_pack/pack/references/source-shaped-ingest.md#source-shaped-timeback-course-reference-ingest

## Incept Traffic Class

`trafficClass` is a Platform-owned Incept producer-surface field, not an app-local metric switch. Allowed values are mastered in the data dictionary as `incept_traffic_class`:

- `customer`: counts in headline customer Accuracy.
- `goal-run`: owner-directed materialization, backfill, or repair traffic; visible in drilldown lanes only.
- `self-test`: loop, reviewer, CI, smoke, or synthetic checks; visible in drilldown lanes only.

Source links:

- Data dictionary enum: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#enum-incept-traffic-class
- Incept progress response: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#response-incept-progress

## Create Tenant Request Body

Use this body for `POST /platform/tenants`; do not infer more fields from examples or local source code:

```json
{
  "tenantKey": "agent-1700000000",
  "displayName": "Agent agent-1700000000",
  "metadata": {
    "source": "timeback-platform-1edtech-skill"
  }
}
```

Field provenance:

- `tenantKey`: required body string, lowercase slug, 3 to 64 characters; source https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#schema-createtenant-request-tenantkey and https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#field-platform-tenant-tenant-key
- `displayName`: required body string, 1 to 160 visible characters; source https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#schema-createtenant-request-displayname and https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#field-platform-tenant-display-name
- `metadata`: optional body object for small redacted operational facts, no secrets or PII; source https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#schema-createtenant-request-metadata and https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#field-platform-tenant-metadata
- `status`: optional `provisioning` (default) or `active`; direct `active` creation requires the exact `platform-operator` tenant principal, Platform `service` role, and `platform:tenant:create` or `platform:*` scope, so every tenant-bound module service is denied; source https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#endpoint-create-tenant and https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#field-platform-tenant-status

Required headers:

- `Authorization: Bearer <token>` from demo mint or TimeBack operator handoff; source https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#schema-createtenant-request-authorization
- `Idempotency-Key: <caller retry key>`; source https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/customer_website/#schema-createtenant-request-idempotency-key

## Data Dictionary Sources

- Shared schema: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#shared-schema
- `platform.tenant`: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#table-platform-tenant
- `platform.idempotency_key`: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#table-platform-idempotency-key
- `platform.audit_log`: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#table-platform-audit-log
- Allowed values: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#allowed-values
- Module release state: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#module-release-state
- Dictionary conventions: https://platform3-andymontgomery-9773s-projects.vercel.app/platform/1edtech/data_dictionary/#dictionary-conventions

## Provenance Discipline

For each output claim, cite one customer-website endpoint link and, when the claim names a table, field, or allowed value, one data-dictionary link. If a claim cannot be tied to one of those links or to a live response field, do not publish it as platform truth.

## Runnable Check

- Pack proof script: /platform/1edtech/skill_pack/pack/checks/verify-skill-pack.mjs
- Check instructions: /platform/1edtech/skill_pack/pack/references/workflows.md#runnable-pack-check

The check calls the live surface only: demo mint, module list/detail, tenant create/read, audit log, and idempotency inspection. It compares live responses to each other rather than carrying saved expected answers.
