# Worked Example: Grade 3 CASE-Backed Course Panel

This recipe builds the data layer for a Grade 3 math course and gate panel. It calls the live Curriculum Alpha API only. For a student-specific app, the student state remains Results-owned; Curriculum returns shared refs and contracts.

## 1. Mint Or Accept A Token

```sh
export CURRICULUM_BASE_URL="${CURRICULUM_BASE_URL:-https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/implementation/api}"
export CURRICULUM_TOKEN="${CURRICULUM_TOKEN:-$(curl -fsSL -X POST "$CURRICULUM_BASE_URL/dev/mint?tenantId=demo" | jq -r '.token')}"
```

## 2. Read The Descriptor

```sh
curl -fsSL "$CURRICULUM_BASE_URL" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{module, surface, modelGate, quickstart, allowedValues, responseShapes, modulePlacement}'
```

Keep `allowedValues` next to the app builder. Do not copy them into app code.

## 3. List Standards Frameworks

```sh
curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/standards-frameworks?subjectId=math&limit=10" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{frameworks: [.data[] | {standards_framework_id, name, standard_count, stored_as}]}'
```

Standards are frozen CASE documents/items. Their links to registry KCs live only in `alpha.standard_kc_map`.

## 4. Read The Course Component Tree

```sh
export COURSE_ID="${COURSE_ID:-66666666-6666-4666-8666-666666666660}"

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/components/$COURSE_ID/tree" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{root_component_id, components: [.components[] | {component_id, kind, name, parent_component_id, position, depth, target_ref, renderer_ref, renderer_kind, passing_criteria_ref, stored_as}]}'
```

Every component row should report `stored_as=case.cf_item`. The tree order comes from `case.cf_association` `isChildOf` edges and their sequence numbers.

## 5. Read The Registry KC And Prerequisite Graph

```sh
export KC_ROOT_ID="${KC_ROOT_ID:-eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee0}"

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/kcs/$KC_ROOT_ID" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{kc_id, current_version_id, kc_granularity, subject_id, grade_ids, stored_as}'

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/kc-prerequisites?kcId=$KC_ROOT_ID" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{data: [.data[] | {prerequisite_id, prerequisite_kc_id, dependent_kc_id, stored_as}]}'
```

`alpha.kc_prerequisite` is the sole prerequisite DAG; `alpha.kc_relation` holds other typed graph semantics; KCs have no containment tree. Mastery and recommendations point at canonical registry KCs, not standards, lessons, source ids, or CASE rows.

## 6. Read Placement Candidates

```sh
export TRACK_ID="${TRACK_ID:-44444444-4444-4444-8444-444444444440}"

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/tracks/$TRACK_ID/placement-candidates?studentId=student_demo&subjectId=math" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{track_id, entry_policy_ref, candidates, results_owner}'
```

Curriculum returns the shared gate candidates and Policy ref. Results records the selected student placement.

## 7. Read Gate Contract, Status, And Remediation

```sh
export GATE_ID="${GATE_ID:-bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbb0}"

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/gates/$GATE_ID" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{gate_component_id, target_ref, renderer_ref, renderer_kind, passing_criteria_ref, on_fail, stored_as}'

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/renderer-registry" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{registration_semantics, capability_matrix_url, renderers: [.data[] | {id, accepted_content_kinds, registered_for_routing, verified_rendering, rendering_state, verified_scope, capability_matrix_url}]}'
# Current truth: qti-item is verified only for 8/21 interactions (including bounded graphicGapMatch); qti-test is verified only for exact forms whose members stay inside that subset.

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/gates/$GATE_ID/status?studentId=student_demo" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{gate_component_id, student_id, gate_status, passing_criteria_ref, source_state_refs}'

curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/gates/$GATE_ID/remediation?studentId=student_demo&resultRecordId=result-demo-gate-fail" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{gate_component_id, remediation_entries, results_owner, source_state_refs}'
```

The app renders remediation entries returned by the surface. It does not classify missed items.

## 8. Optional: Resolve A Results-Owned Next Lesson

```sh
curl -fsSL "$CURRICULUM_BASE_URL/alpha/curriculum/v1/courses/$COURSE_ID/next-lesson?studentId=student_demo&subjectId=math" \
  -H "Authorization: Bearer $CURRICULUM_TOKEN" \
  | jq '{student_id, course_id, component_id, kind, reason, target_ref, renderer_ref, renderer_kind, source_state_refs}'
```

This read is a resolver over a Results-owned next-task reference. Do not choose the next lesson by locally sorting the tree.

## What This Example Proves

- The app used only the live API.
- Components came from CASE-backed component reads; the KC identity and prerequisite graph came from registry-native reads. No CASE export, source-id fallback, or KC containment tree was used.
- Content was referenced by an exact-version `target_ref`; no latest-version lookup, Content body, QTI answer key, producer verdict, score, mastery, event, roster, credential, or secret entered the app.
- Gate behavior stayed on the gated component; thresholds stayed in Policy; student state stayed in Results.
