Skip to content

docs: retire the API freeze, keep the removal check#1083

Merged
zachshallbetter merged 2 commits into
mainfrom
docs/api-surface-honesty
Jul 20, 2026
Merged

docs: retire the API freeze, keep the removal check#1083
zachshallbetter merged 2 commits into
mainfrom
docs/api-surface-honesty

Conversation

@zachshallbetter

Copy link
Copy Markdown
Owner

The problem

The surface was described as frozen for 0.x. That list has been edited 40 times.

A stability promise that gets revised whenever it becomes inconvenient is not a promise — it is a claim that quietly stops being true. It also forced an "is this breaking?" debate on changes that were plainly improvements.

What is kept, and why

The check does something narrower than the promise claimed, and that narrow thing is worth having.

It only fails when something disappears. Every failure condition is a listed symbol that stopped being exported, stopped being declared, or stopped registering. It has never failed on an addition and cannot — new exports land freely.

The point was never to prevent removals. It is to make them deliberate: a removed export should be a decision with a migration note, not something a consumer discovers before CI does.

Changes

  • FROZEN_*PROTECTED_* across the data, type gate, runtime check, parity generator and four site pages (I initially renamed a hand-listed set and broke the site build by missing two importers — found by building, then fixed by searching).
  • Failure messages now name what happened and what to do: drop the entry in the same change, add a CHANGELOG note.
  • api-stability.md and /docs/api/stability rewritten to describe removal protection rather than a freeze.

Verified the gate can still fail

Injecting a phantom protected symbol exits 1 with the new message. A gate that cannot fail is not a gate.

Two inaccuracies fixed in passing

  • The docs page claimed entries "fail the build if they change" — only removal fails.
  • The canonical doc cited "the frozen 17" where the check reports 20.

Gates

typecheck · full suite · check:api · check:docs · check:links · site build — all green. Published page now reads "20 entries that fail the build if they disappear."

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fundamental-engine Ready Ready Preview Jul 20, 2026 7:44pm

Request Review

@github-actions

Copy link
Copy Markdown

API surface delta (frozen public contract — see docs/canonical/api-stability.md):

Added (allowed in a patch):

  • PROTECTED_ELEMENTS · @fundamental-engine/elements · field-cell
  • PROTECTED_ELEMENTS · @fundamental-engine/elements · field-root
  • PROTECTED_TYPES · @fundamental-engine/core · FieldHost
  • PROTECTED_TYPES · @fundamental-engine/core · FieldPattern
  • PROTECTED_TYPES · @fundamental-engine/core · FieldRecipe
  • PROTECTED_TYPES · @fundamental-engine/dom · FieldPlatform
  • PROTECTED_VALUES · @fundamental-engine/core · compilePattern
  • PROTECTED_VALUES · @fundamental-engine/core · compileRecipe
  • PROTECTED_VALUES · @fundamental-engine/core · createField
  • PROTECTED_VALUES · @fundamental-engine/dom · applyPattern
  • PROTECTED_VALUES · @fundamental-engine/dom · applyRecipe
  • PROTECTED_VALUES · @fundamental-engine/dom · bindData
  • PROTECTED_VALUES · @fundamental-engine/dom · browserHost
  • PROTECTED_VALUES · @fundamental-engine/dom · createFieldPlatform
  • PROTECTED_VALUES · @fundamental-engine/elements · FIELD_VERSION
  • PROTECTED_VALUES · @fundamental-engine/react · FIELD_VERSION
  • PROTECTED_VALUES · @fundamental-engine/vanilla · FIELD_VERSION
  • PROTECTED_VALUES · @fundamental-engine/vanilla · browserHost
  • PROTECTED_VALUES · @fundamental-engine/vanilla · createField

Removed / renamed (BREAKING — needs a 0.MINOR bump + CHANGELOG migration note):

  • FROZEN_ELEMENTS · @fundamental-engine/elements · field-cell
  • FROZEN_ELEMENTS · @fundamental-engine/elements · field-root
  • FROZEN_TYPES · @fundamental-engine/core · FieldHost
  • FROZEN_TYPES · @fundamental-engine/core · FieldPattern
  • FROZEN_TYPES · @fundamental-engine/core · FieldRecipe
  • FROZEN_TYPES · @fundamental-engine/dom · FieldPlatform
  • FROZEN_VALUES · @fundamental-engine/core · compilePattern
  • FROZEN_VALUES · @fundamental-engine/core · compileRecipe
  • FROZEN_VALUES · @fundamental-engine/core · createField
  • FROZEN_VALUES · @fundamental-engine/dom · applyPattern
  • FROZEN_VALUES · @fundamental-engine/dom · applyRecipe
  • FROZEN_VALUES · @fundamental-engine/dom · bindData
  • FROZEN_VALUES · @fundamental-engine/dom · browserHost
  • FROZEN_VALUES · @fundamental-engine/dom · createFieldPlatform
  • FROZEN_VALUES · @fundamental-engine/elements · FIELD_VERSION
  • FROZEN_VALUES · @fundamental-engine/react · FIELD_VERSION
  • FROZEN_VALUES · @fundamental-engine/vanilla · FIELD_VERSION
  • FROZEN_VALUES · @fundamental-engine/vanilla · browserHost
  • FROZEN_VALUES · @fundamental-engine/vanilla · createField

The surface was described as frozen for 0.x. That list has been edited 40 times. A
stability promise revised whenever it becomes inconvenient is not a promise — it is a
claim that quietly stops being true, and it forced an is-this-breaking debate on changes
that were plainly improvements.

The check is kept, because it does something narrower and worth having: it fails when a
listed symbol stops being exported, stops being declared, or stops registering. It has
never failed on an addition and cannot. The point was never to prevent removals, only to
make them deliberate — a removed export should be a decision with a migration note, not
something a consumer finds before CI does.

FROZEN_* → PROTECTED_* across the data, the type gate, the runtime check, the parity
generator and four site pages. Failure messages now name what happened and what to do
about it: drop the entry in the same change and add a CHANGELOG note.

Verified the check can still fail: injecting a phantom protected symbol exits 1 with the
new message. A gate that cannot fail is not a gate.

Two inaccuracies fixed in passing. The docs page claimed the entries 'fail the build if
they change' — only removal fails. The canonical doc cited 'the frozen 17' where the check
reports 20.

typecheck clean; full suite passes; check:api, check:docs, check:links green; site builds
and the published page now reads '20 entries that fail the build if they disappear'.
RELEASING.md, PUBLISHING.md, docs/canonical/README.md, agent-consumption-model.md and
agent-safety-model.md still described a freeze. substrate-api.md cited 'the frozen 17'
twice where the check reports 20 — a stale count, not just stale wording.

Deliberately untouched, because the word means something else in each: Object.freeze'd
policy clones in agent-safety-model.md, 'frozen design history' for the planning archive,
'freeze the sim' for reduced motion, and 'frozen particles' in the poster render mode. A
pattern-matched sweep would have damaged all four.

Freeze wording survives in prose across several other canonical docs. That is stale
phrasing rather than a wrong claim about the gate, and chasing it through fifteen files
belongs in its own change rather than blocking a release.
@zachshallbetter
zachshallbetter merged commit 1b148a0 into main Jul 20, 2026
16 checks passed
@zachshallbetter
zachshallbetter deleted the docs/api-surface-honesty branch July 20, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant