Platform starts as a pre-1.0 project, but K1 and F8 introduce explicit compatibility rules across Codex, BFF, Toolset/Panel, and renderer adapters.
See also:
- Compatibility matrix — contract owners and gates
- Contract artifacts — schema, TS types, fixtures
- Versioning — semver and release levels
Stable APIs are expected to remain compatible within a major version. Breaking changes require an RFC and ADR.
Experimental APIs may change, but changes must be documented. Use this for remote modules, marketplace packages, and LLM-generated proposals until proven by multiple products.
Internal APIs have no compatibility promise and must not be imported by modules.
The BFF UI contract is versioned separately from Platform semver. Current contract:
bff.v1.
Products and renderer adapters may depend on the symbols below without expecting Platform kernel changes for each new app. Everything else is experimental, product-owned, or internal until promoted.
| Area | Stable symbols / artifacts | Notes |
|---|---|---|
| Contract identity | bff.Version, schema/bff/v1/* |
Versioned separately from Platform semver |
| Page shell | PageModel, ShellModel, NavigationModel, SessionModel |
Templ in-process; JSON via /bff/* |
| Screen model | render.ScreenModel fields proven by v1 fixtures |
Table, form, error, empty-state proof set |
| State envelopes | ValidationModel, ErrorModel, EmptyStateModel |
Portable across renderers |
| Actions | ActionDescriptor, ActionRequest, ActionResult, ActionRegistry, ExecutorRegistry |
Product registers handlers |
| Runtime boundaries | ScreenHydrator, HydrateRequest, Resolver, Navigator, Principal |
Platform orchestrates; products implement |
| Published artifacts | JSON Schema, web/contract TS types, golden fixtures, conformance matrix |
See Contract artifacts |
bff.v1 currently uses render.ScreenModel as the renderer-visible screen ABI.
The frozen promise is the JSON shape validated by schema/bff/v1/screen.schema.json,
the TypeScript contract in web/contract, and golden fixtures under
pkg/conformance/testdata/bff/v1/. Because render.ScreenModel embeds
panel.Column and panel.Field, the JSON shape of those field and column objects
is also part of the frozen bff.v1 surface when emitted through BFF. A future
dedicated bff.ScreenModelV1 DTO may decouple internals, but only through an RFC,
ADR, and either additive v1 compatibility or a new bff.v2 contract.
Allowed to evolve within bff.v1 with fixture/schema alignment. Not a promise of
final payload semantics until repeated cross-product reuse:
| Area | Examples | Rule |
|---|---|---|
| Dashboard widgets | SectionModel, WidgetModel, MetricModel, StatusModel, ChartModel, ActivityFeedModel |
Additive fields only within v1 |
| Realtime hints | SubscriptionHint, subscriptions[] on widgets/sections |
Hints only; transports live outside Platform core |
| Custom views | view: "chat", view: "kanban", product metadata |
Product/module owned until promoted |
| Renderer SDKs | web/react, hooks (useScreen, useAction, useSession, useNavigation), shadcn mapping, Vite proxy examples, create-fastygo-app |
Deferred DX proof; not Platform default; not frozen |
| Future adapters | Next, Vue, PHP, Handlebars examples | Consume same BFF JSON; evolve independently |
Future frontend DX may depend on frozen bff.v1 artifacts (schema, TS contract,
fixtures) without making React/Vite/shadcn part of Platform core. Platform
package stabilization does not require shipping hooks, shadcn mapping, or a full
frontend SDK.
| Area | Owner | Platform provides |
|---|---|---|
| Action executors | Product app / module | ExecutorRegistry, envelopes, validation |
| Hydration data | Product app / module | ScreenHydrator interface |
| Special screens | Product app appschema |
Resolver.Special, descriptors |
| Domain records | Module pkg/module |
Toolset/panel contracts |
| Public themes | Product app | BFF may expose surface metadata later |
platform/internal/*- Product app imports inside Platform
pkg/(forbidden by boundary tests) - Unexported helpers and test-only fixture writers
Allowed in bff.v1 without a new contract version:
- new optional fields on
ScreenModel, sections, widgets, rows, or action results; - new widget types or subscription hints when schema, Go types, TS types, validators, and fixtures stay aligned;
- new golden fixtures that prove optional features;
- new conformance cases for existing fixture groups.
These require a new contract version (for example bff.v2), not silent edits to v1
schemas:
- removing or renaming a field;
- changing the meaning of an existing field;
- making an optional field required;
- tightening JSON Schema in a way that rejects previously valid payloads.
When bff.v2 ships, v1 fixtures remain frozen for adapters that declare bff.v1
support.
Every BFF contract change must do one of the following:
- Update fixtures — regenerate or edit files under
pkg/conformance/testdata/bff/v1/and extend conformance cases inpkg/conformance/bffparity/. - Declare no fixture impact — document in the PR or release notes that schema/Go/TS changes are internal-only or do not alter golden fixture semantics.
If a change affects renderer-visible semantics, fixtures must change.
Codex compatibility and BFF renderer conformance are tracked separately:
| Layer | Tracks | Does not track |
|---|---|---|
| Codex | Observable CMS URLs, REST envelopes, admin/theme/plugin/capability behavior | UI layout, renderer HTML, SPA hydration |
| BFF | Screen/nav/session/action JSON, golden fixtures, adapter parity | Codex REST byte-for-byte parity |
Platform CI runs BFF/renderer gates by default. Codex conformance runs against declared profiles when Codex test suites are available; it is not folded into renderer adapter tests.
Breaking changes include:
- removing a stable type or method;
- changing the meaning of a stable field;
- changing route compatibility in a codex profile;
- weakening security defaults;
- changing profile semantics in a way that breaks existing apps.
Non-breaking changes include:
- adding optional fields;
- adding new experimental adapters;
- adding new renderer types;
- adding new codex profiles;
- adding new conformance tests for optional features.
Use this checklist before merging Platform changes that touch public contracts.
Allowed when all of the following hold:
- new fields or optional behaviors only;
- Go structs, JSON Schema, TS types, and validators stay aligned;
- golden fixtures updated or no fixture impact declared;
- conformance matrix updated when renderer-visible semantics change;
- Platform
pkg/still has no product app/module imports.
Requires bff.v2 (or Platform major semver for non-BFF ABI), RFC, ADR, and:
- new schema family or versioned contract;
- frozen v1 fixtures remain available for adapters declaring
bff.v1support; - migration notes in release notes.
Allowed only when the change is internal or does not alter renderer-visible JSON semantics validated by golden fixtures. Document explicitly in PR or release notes.
Widgets, realtime hints, custom views, and future adapter SDKs may evolve within
bff.v1 additively but are not part of the frozen public API until promoted
after repeated cross-product reuse.
Action executors, hydration, special screens, public/portal routes, and domain records belong in product apps/modules. Platform provides contracts and boundaries only.
- Platform
pkg/must not importgithub.com/fastygo/app-*orgithub.com/fastygo/module-*. - Platform core
pkg/must not importgithub.com/fastygo/templ(renderer adapters only). - AppCMS must not import UI8Kit as an active requirement.
- Third-party renderer examples must not import Go Platform apps or modules.
Enforced by pkg/conformance/import_boundary_test.go, adapter_boundary_test.go,
and governance_test.go.
| Layer | When | Gate |
|---|---|---|
| Platform package | Before Platform tag/publish | .github/workflows/bff-parity.yml or ./scripts/bff-parity.sh |
| BFF contract change | Before merge | BFF contract change gate in Release checklist |
| Product assembly | Before product-scale production | Product assembly gate |
Codex conformance is tracked separately and must not be folded into BFF renderer tests.
Stable ABI changes require an RFC before implementation and an ADR after acceptance.