Skip to main content

Approve the schema contract

Nothing you ingested is a model input yet. The schema contract is where you decide what the model may see: Tessera infers a draft from the profiling of everything landed so far, you review the per-attribute roles, and you approve a version that datasets and serving bundles will pin by fingerprint.

03-approve-contract.sh
#!/usr/bin/env bash
# Quickstart step 3 — review the inferred schema contract and approve it.
set -euo pipefail

: "${TESSERA_API_BASE:?e.g. https://api.staging.tessera.zone/v1}"
: "${TESSERA_API_KEY:?your tsk_test_… key}"
AUTH=(-H "Authorization: Bearer $TESSERA_API_KEY")

# Infer a draft from everything profiled so far (the upload + your streamed
# events). The draft applies deny-by-default: unreviewed attributes never
# become model inputs.
DRAFT="$(curl -sS -X POST "$TESSERA_API_BASE/contracts" "${AUTH[@]}" \
-H "Idempotency-Key: quickstart-contract-draft")"
VERSION="$(printf '%s' "$DRAFT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')"

# Review what the model would see: event types and per-attribute roles.
printf '%s' "$DRAFT" | python3 -c '
import json, sys
contract = json.load(sys.stdin)
print("draft contract v%s: %s" % (contract["version"], contract["status"]))
for event_type, section in sorted(contract["event_types"].items()):
roles = {key: spec["role"] for key, spec in section["attributes"].items()}
print(" %s [%s]: %s" % (event_type, section["status"], json.dumps(roles, sort_keys=True)))
'

# Approve it. Datasets and serving bundles will pin this exact version.
APPROVED="$(curl -sS -X POST "$TESSERA_API_BASE/contracts/$VERSION:approve" "${AUTH[@]}")"
printf '%s' "$APPROVED" | python3 -c '
import json, sys
contract = json.load(sys.stdin)
print(json.dumps({k: contract[k] for k in ("version", "status", "fingerprint")}, indent=2))
'

Download quickstart/03-approve-contract.sh — this exact file runs in CI on every change (hosts shown are for this environment).

Read the draft before approving — the roles are the whole point:

  • numeric columns (order_value, item_count) inferred as feature/quantile; low-cardinality strings (category, payment_method) as feature/categorical_hash;
  • anything matching identifier heuristics can never be a feature — identity is not behavior;
  • anything ambiguous lands excluded — deny by default: an attribute nobody reviewed is never a model input.

In real projects this review is a PATCH /contracts/{version} conversation (flip a role, exclude an event type) before approving; the sample data needs no edits. Approval stamps approved_by/approved_at and freezes the version — new attributes that show up later accumulate into the next draft instead of silently entering the model.

Next: define the label.