Versioning and contract evolution
Versioning
Every response carries contract_version (semver).
| Change | Bump | Old-client behavior |
|---|---|---|
| New component or field | minor | ignore the unknown |
| Change to a field’s semantics | major | we try to avoid it |
| Major above what the client supports | — | “update the app” screen |
Graceful degradation
- Unknown component
type: skipped in release, placeholder with the type name in dev. The page doesn’t crash. - Unknown fields of known components are ignored.
Before you deploy — checklist
The client enforces these rules at runtime; check them while authoring so a page doesn’t render empty or reject an action:
- Required fields present:
typeon every component;idon everyfield. - Enum values are valid:
role,kind,presentation,style,sentiment, … (see each component’s page). - No absolute URLs in
navigate,submit,rows_endpoint,badge_source,search.endpoint,source— they are rejected. Use relative paths. - A
destructiveaction has aconfirm. - No more than 5 tabs (they won’t fit on iPhone).
sourceis same-origin with the manifest (cross-origin is rejected).