Host and renderer backward compatibility
Required runtime behavior for previously published TCK bundles as authoring rules evolve.
The TCK host and renderer MUST remain backward compatible with every previously published .tckb bundle for the bundle's declared ABI. This is a release-blocking runtime invariant, not a best-effort migration policy.
New authoring and build rules may become stricter. They may reject deprecated source patterns, require new fields, or emit migration warnings. Those rules apply when producing a new bundle. The host and renderer must not reuse a new authoring requirement as a runtime rejection gate for a historical bundle.
An incompatible render path can throw while a client is mounting server-provided content. In native and web clients that can crash the card surface or the client itself. Therefore host/renderer compatibility must be preserved even when the old behavior is incomplete, visually dated, or no longer recommended for new source.
Compatibility rules
- Build strictness and runtime compatibility are separate. A new build may fail for an invalid or deprecated authoring shape while the renderer still accepts the equivalent shape from an existing bundle.
- Prefer warning and fallback over throwing. When a safe legacy interpretation exists, render the widget, emit a diagnostic warning, and use that interpretation.
- Preserve ABI paths. A host must continue serving and mounting the shared dependencies for every ABI label still referenced by published bundles. A new ABI is added alongside an old ABI; it does not overwrite it.
- Keep historical behavior executable. Deprecated DOM, CSS, manifest, and action shapes remain supported for their declared ABI unless a separately coordinated migration proves that no published bundle relies on them.
- Test the old input through the current runtime. Every new authoring constraint that overlaps published behavior needs a runtime regression test or a Preview compatibility fixture before release.
Historical v1 behavior
| Historical input | New authoring/build behavior | Required host/renderer behavior |
|---|---|---|
Action with action="chat.composer.fill" and no usable payload.text | TypeScript build fails; new source must provide a complete, self-contained payload | Render without throwing, warn, and fall back to the visible label when invoked |
Direct <a href="today://..."> or ordinary web anchor | Bundler warns when the anchor appears to be a host-action CTA; typed Action is preferred | Render the anchor and keep the host's existing link-routing path available |
Widget with no tck-coarse classes | New source may opt into coarse-pointer typography explicitly | Render the original classes unchanged; absence of the variant is not an error |
These rules describe compatibility behavior, not recommended authoring. New widgets follow the current SDK types, generated project documentation, and build checks.
Regression fixtures
The Preview Playground keeps intentionally old widgets under apps/preview-playground/compatibility. pnpm --filter @todayai-labs/preview-playground dev builds them and exposes them in Stage and Canvas as Compatibility (Legacy).
The directory currently covers:
- a chat action without an explicit payload;
- a direct
today://anchor; - typography with no
tck-coarsesupport.
Do not modernize these fixtures in place. Add a current authoring example elsewhere, and keep the compatibility fixture in its historical shape so future host/renderer changes continue exercising the old contract.
Change checklist
Before shipping a stricter authoring rule or changing host mount behavior:
- Identify whether already-published bundles can contain the old input.
- Keep the current ABI runtime tolerant, with a warning and fallback where possible.
- Add or update a compatibility fixture and an automated runtime assertion.
- Document both the new build rule and the old runtime behavior.
- Add a changeset describing the user-visible compatibility behavior.
See Platform ABI for ABI-path lifetime and Action protocol for the typed action contract.