---
name: timeback-caliper-1edtech
description: Use when building apps, reports, QA probes, or deliverables against the TimeBack platform3 Caliper 1EdTech surface. The skill teaches an agent to use the live Caliper Analytics 1.2 API, demo token minting, tenant headers, Sensor API envelope writes, and event/envelope read projections without re-implementing Caliper normalization, schema parsing, hashing, enumeration tables, persistence, or business rules.
---

# TimeBack Caliper 1EdTech

Use this skill when the user asks for a working app, report, integration proof, API probe, or customer deliverable that uses the platform3 Caliper 1EdTech surface.

Do not use it for the Alpha surface, for generic Caliper research, or for database work outside the public API.

## First actions

1. Fetch or open the canonical customer website and data dictionary before making claims:
   - Customer website: https://platform3-andymontgomery-9773s-projects.vercel.app/caliper/1edtech/customer_website/
   - Data dictionary: https://platform3-andymontgomery-9773s-projects.vercel.app/caliper/1edtech/data_dictionary/
   - Architecture decisions: https://platform3-andymontgomery-9773s-projects.vercel.app/caliper/1edtech/architecture/
2. Use `CALIPER_BASE_URL` if credentials supply it. Otherwise use:
   `https://platform3-andymontgomery-9773s-projects.vercel.app/caliper/1edtech/implementation/api`
3. Choose the credential path:
   - Demo: call `POST $CALIPER_BASE_URL/dev/mint?tenantId=00000000-0000-4000-8000-00000000ca12`, then use the returned `token`, `tenantId`, and `sensorIri`.
   - Real/reviewer tenant: use the operator-supplied bearer token such as `CALIPER_REVIEWER_JWT`; use the supplied tenant id or the token's `tenantId` claim for `X-Timeback-Tenant`.
4. For live proof, read `references/worked-example.md` and run the smallest workflow that proves the user job.
5. Before final output, run the binary leak check in `references/leak-check.md`.

## API perimeter

The public Caliper 1EdTech surface is intentionally narrow:

- `POST /dev/mint?tenantId=00000000-0000-4000-8000-00000000ca12` mints a demo JWT and sensor IRI.
- `POST /caliper/v1p2/events` receives a Caliper Analytics 1.2 Sensor API envelope and returns `204 No Content`.
- `GET /caliper/v1p2/events?eventIri=<iri>` reads the tenant-scoped event projection for a known event IRI.
- `GET /caliper/v1p2/envelopes?hash=<sha256>` reads the tenant-scoped envelope projection for a returned envelope hash.

The write response has no JSON body. Use the `caliper-envelope-hash` response header and the event IRI from the envelope for read-back evidence.

## Non-negotiables

Treat these as binary rules, not preferences:

- Version discipline: Caliper payloads use `dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2"`.
- Tenant identity: `X-Timeback-Tenant` must match the bearer token tenant claim. Never infer tenant from learner, actor, class, group, or sensor identifiers.
- Sensor identity: use the demo `sensorIri` returned by `/dev/mint` or an operator-supplied sensor IRI for the tenant. Do not invent a real-tenant sensor.
- Write result: envelope ingest success is `204 No Content`; the only write proof is the server-returned `caliper-envelope-hash` header plus later read-back.
- Event minimum: event rows need `id`, `type`, `actor`, `action`, `object`, and `eventTime`.
- Read model: reads are exact lookups by event IRI or envelope hash. No list/search/discovery primitive ships.
- Error model: failed requests return Problem JSON. Do not hide `400`, `401`, `403`, `404`, `409`, `415`, or `422` behind local retries.

## Do not add hidden surface logic

The skill pack is instructions-only. When building an app or report:

- Do not compute Caliper canonical hashes locally. Read the `caliper-envelope-hash` header.
- Do not normalize, infer, or validate Caliper profiles/actions/event types outside the API. If the API returns `422`, show the Problem JSON and point to the docs.
- Do not copy event type, action, profile, entity type, or relation enum tables into the app unless the user is quoting the hosted data dictionary.
- Do not read the implementation source or database to complete a user-facing workflow.
- Do not create local persistence for Caliper domain data. Browser state is acceptable for UI preferences and recent request handles only.
- Do not invent list, search, cursor, `modifiedSince`, webhook, DELETE, PATCH, or official certification behavior. Those are unshipped or deferred commitments.

If the user job needs one of those missing primitives, stop and report a surface gap. Do not work around the gap with private code.

## Common build pattern

For a proof app or report, use this shape:

1. Ask for or mint credentials.
2. Build or accept a valid Caliper Analytics 1.2 envelope.
3. POST the envelope with `Authorization`, `X-Timeback-Tenant`, `Content-Type: application/json`, and optional `Idempotency-Key`.
4. Capture the returned `caliper-envelope-hash` header.
5. Read `GET /events?eventIri=...` and `GET /envelopes?hash=...`.
6. Present only fields returned by the surface: event IRI, event type, profile, action, event time, envelope status, event count, and hashes returned by the API.
7. Link any field interpretation back to the customer website or data dictionary.

## Reference files

- Read `references/canonical-surface.md` when you need endpoint, credential, status, or deferred-behavior details.
- Read `references/worked-example.md` when you need a runnable demo workflow.
- Read `references/leak-check.md` before shipping an app, report, or deliverable.

## Expected output quality

Every output should make the platform more useful than a generic agent:

- It should run against the live Caliper API, not a mock.
- It should include the exact API calls or enough evidence to reproduce them.
- It should name which canonical docs it used.
- It should disclose any missing surface primitive instead of hiding it.
