---
name: timeback-events-alpha
description: Register producer activity sources and read or write TimeBack Events Alpha activity streams, source-shaped imports, activity-source details, and read-only attendance or discipline moments through the live Alpha Events API. Use when integrating producer apps, building teacher activity reports, migration probes, QA checks, or apps that ask what a student or class did. Do not compute Results, mastery, minutes, Caliper mappings, Ed-Fi descriptors, dedupe, or database logic locally.
---

# TimeBack Events Alpha

Events is the activity stream: app opens, content views, question answers, video scrubs, hint requests, submissions, attendance moments, and discipline moments. Use this skill to call the public Alpha Events surface and let the platform handle Caliper, Ed-Fi, ingest normalization, identity checks, dedupe, and redaction.

## Instructions

1. Set the API bases:
   - `EVENTS_BASE_URL=${EVENTS_BASE_URL:-https://platform3-andymontgomery-9773s-projects.vercel.app/events/alpha/implementation/api}`
   - `PEOPLE_ORGS_BASE_URL=${PEOPLE_ORGS_BASE_URL:-https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/implementation/api}`
2. Choose credentials:
   - Demo: `POST $EVENTS_BASE_URL/dev/mint?tenantId=demo` returns a tenant-scoped Events bearer, tenant id, default activity source, and identity boundary contract. The examples use seeded demo ids `student-ada-001` and `content-fractions-video-01`.
   - Teacher reports with roster names: in real or reviewer tenants, resolve the returned Events `studentId` through `GET $PEOPLE_ORGS_BASE_URL/people/{personId}` when that tenant uses People & Orgs person ids.
   - Real/reviewer tenant: use operator-supplied bearer credentials such as `EVENTS_REVIEWER_JWT`; never store them in the skill files.
3. Send every non-mint Events request with `Authorization: Bearer <token>` and `X-Timeback-Tenant: <tenant id>`. Add `Content-Type: application/json` on writes and `Idempotency-Key` on retryable `POST /events` or `POST /source-imports`.
4. When onboarding a producer, use an operator-supplied token with `events:sources:write` and call `POST /activity-sources` with only `sourceIri` and `name`. Store the platform-returned UUID as `activitySourceId`; never derive or choose it in the app. An identical retry returns the same UUID. The public demo token cannot register sources.
5. For a first read, call `GET /events?studentId={studentId}&pageSize=5`. Use returned event ids, cursors, fields, and activity-source ids exactly as returned.
6. For freshness, reuse one `modifiedSince` high-watermark and returned opaque cursor per tenant/filter set. Follow `references/canonical-surface.md#poll-cadence-and-backoff`; Events Alpha has no webhook, SSE, push, or notifications subscription surface today.
7. For a teacher report, read Events for the student id, optionally resolve the display name in People & Orgs for aligned real/reviewer tenants, then format returned fields only. Do not parse names from event labels or app URLs.
8. For migration probes, call `POST /source-imports` with source-shaped `timeback_production` or `horizons_sis` rows, then verify accepted rows materialized through `GET /events`, `GET /attendance-events`, or `GET /discipline-events`.
9. Load references only when needed:
   - `references/canonical-surface.md` for endpoint/status/query details.
   - `references/worked-example.md` for the copy-paste teacher activity workflow and expected output.
   - `references/runnable-check.md` for the acceptance check.
   - `references/leak-check.md` before shipping an app, report, or probe.

## Examples

Read one student's demo activity:

```bash
export EVENTS_BASE_URL="${EVENTS_BASE_URL:-https://platform3-andymontgomery-9773s-projects.vercel.app/events/alpha/implementation/api}"
MINT=$(curl --max-time 20 --retry 3 --retry-all-errors --retry-delay 2 -fsS -X POST "$EVENTS_BASE_URL/dev/mint?tenantId=demo")
TOKEN=$(printf '%s' "$MINT" | node -e 'let s="";process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>process.stdout.write(JSON.parse(s).token))')
TENANT_ID=$(printf '%s' "$MINT" | node -e 'let s="";process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>process.stdout.write(JSON.parse(s).tenantId))')

curl --max-time 20 --retry 3 --retry-all-errors --retry-delay 2 -fsS "$EVENTS_BASE_URL/events?studentId=student-ada-001&pageSize=5" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Timeback-Tenant: $TENANT_ID"
```

Build a teacher-facing "what did Ada do today?" report:

```bash
# Use the single copy-paste workflow in references/worked-example.md.
# It mints demo Events credentials, writes one content_viewed event for
# student-ada-001, reads it back, and prints report JSON.
```

Prove the skill pack against the live surface:

```bash
# Run the command block in references/runnable-check.md.
# Passing output ends with {"result":"pass", ... "checkedBySurfaceCallsOnly":true}.
```

## Guidelines

- Event is not Result. Do not compute score, mastery, working grade, report card, XP, content effectiveness, NWEA, or minutes facts in an Events app.
- Content is not attempt. Content holds blank material; Events records interactions; Results owns settled outcomes.
- Attendance and discipline are read-only in Events Alpha. Write or correct those records through the Ed-Fi base surface.
- Activity-source registration is Events-owned. Do not write `caliper.sensor`, reuse another app's UUID, derive a UUID from `sourceIri`, or place credentials in the request.
- `kind`, dates, student ids, content ids, org ids, descriptors, and source import outcomes are typed fields returned or validated by the surface. Do not recover them by parsing strings.
- Do not read `caliper.*`, `platform.*`, Supabase, Postgres, private logs, implementation source, raw Caliper payloads, raw Ed-Fi payloads, or bearer-token contents for a user-facing workflow.
- If the user asks for a missing primitive such as webhooks, SSE, push, notifications subscriptions, event updates/deletes, raw payload export, descriptor maintenance, or Results computation, report a surface gap instead of adding private logic.
