Inference Contracts and Schema Validation
An inference contract is a compatibility promise between a caller and a particular model-serving capability. It covers syntax, feature meaning, units, allowed domains, model identity, outputs, errors, and evolution—not merely whether JSON parses.
Prerequisites
Complete Batch vs Online Inference. Be familiar with the Study Sprint artifact's source_features, learned preprocessing statistics, and immutable model version.
Learning goals
- separate malformed, structurally invalid, out-of-domain, and incompatible requests.
- version the caller contract and requested model independently.
- make error responses stable enough for callers to handle without string parsing.
Worked example
Study Sprint accepts exactly this top-level object:
{
"schema_version": 1,
"model_version": "study-sprint-completion@1",
"request_id": "session-1042",
"instances": [
{
"prior_score": 60,
"practice_minutes": 35,
"learning_track": "foundations"
}
]
}
prior_score is a finite number from 0 through 100; practice_minutes is a finite number from 0 through 180; learning_track is advanced or foundations. One request contains 1–100 instances. Required fields cannot silently default, booleans are not accepted as numbers, and unknown fields are rejected so a misspelling cannot pass unnoticed.
The successful response preserves correlation and identity:
{
"schema_version": 1,
"model_version": "study-sprint-completion@1",
"request_id": "session-1042",
"predictions": [{"class": 0, "probability": 0.254037}]
}
The probability is a model score under the published threshold, not certainty, causal effect, or permission to automate a consequential action.
Stable failures
Every caller-visible failure has the same envelope:
{
"schema_version": 1,
"error": {
"code": "OUT_OF_DOMAIN",
"message": "request does not satisfy the inference contract",
"details": [
{"field": "instances[0].prior_score", "reason": "must be between 0 and 100"}
]
}
}
The verifier covers MALFORMED_JSON, INVALID_REQUEST, OUT_OF_DOMAIN, UNSUPPORTED_SCHEMA_VERSION, and MODEL_VERSION_MISMATCH. Programs branch on code; humans use message and details. Do not expose stack traces, filesystem paths, training rows, or secrets.
Schema validation cannot establish semantic truth. A value of 60 may fit the numeric range but still use the wrong assessment, timestamp, population, or unit. Producers and consumers need named definitions and provenance checks in addition to type/range validation.
Evolution rules
Adding an optional field can be compatible only if old servers and clients define how to treat it. This teaching contract rejects unknown fields, so additions require a new schema version or a coordinated rollout. Changing feature meaning, class order, preprocessing, or response interpretation is incompatible even if the JSON shape stays the same. Keep old model versions addressable only as long as their contracts and operational support remain valid.
Common mistakes
- Treating missing and explicit
nullas equivalent. - Coercing strings to numbers and hiding upstream defects.
- Returning a different error shape from each validation branch.
- Using model version and request schema version as one number.
- Assuming a JSON Schema alone documents timestamps, units, ownership, or intended use.
Practice
Add a hypothetical days_since_last_session feature. Specify type, unit, clock, range, missingness policy, event-time rule, and whether the change requires a new request schema, model version, or both. Then write one valid and four invalid requests.
Next steps
Building a Prediction API maps this contract onto a small local HTTP boundary without pretending that a teaching server is production infrastructure.
Primary sources
Checked 2026-10-15: OpenAPI Specification 3.2.0, JSON Schema object validation, RFC 8259 JSON, and RFC 9110 HTTP semantics.