Release notes
Changes that affect operators and site developers, newest first.
How changes are recorded
Section titled “How changes are recorded”- Dee Wan has not had a release yet. Everything below is under Unreleased. A released version gets its own heading with its version and date.
- Any change that removes or changes behaviour someone outside this repository could rely on gets an entry here, even if we believe nobody relies on it.
- The public read API is versioned in its path (
/v1/). Withinv1, documented paths, parameters, status codes and response keys keep their meaning. See What is stable. A breaking change to it ships under a new path version. - Page documents carry a
formatnumber. A change in how existing documents are read gets a new format number. See the page-document contract.
Unreleased
Section titled “Unreleased”Added: coordinated authoring and consumer delivery
Section titled “Added: coordinated authoring and consumer delivery”Draft saves now defer empty required fields by default; publication still requires complete values. Choose strict Draft validation on a model to require complete saves. CSV/XLSX imports add Create and Upsert beside Update. Project labels can follow the admin language without changing stored keys or option values.
Editorial work gains locale owners, required review tasks, field threads with replies and mentions, retained batch AI proposals, and separately editable future versions tied to releases. Native lists can filter and sort by related display values. Model promotion reviews selected definition changes between sites.
Media gains language-specific originals with retained version pins. Sites can explicitly grant other sites access to published shared content. Point fields support spatial queries; zoned datetimes retain their IANA timezone. Consumers can resume incremental reads through GET /v1/_sync, including deletion records and explicit checkpoint resets. See content editing, models and fields, media, sites and public API.
Management API additions use minor contract 1.12.0. Schema changes remain in the initial migration before the first release. Final integrated acceptance and the paused external-provider work remain release requirements.
Added: integration and editorial completion
Section titled “Added: integration and editorial completion”The source adds lifecycle, workflow, release, media and model webhook events; one atomic same-site publication command; multi-model links inside components; plugin workspaces and dashboard placements; retained form-submission details and per-form notifications; a direct Media workspace with custom asset fields; and collection-wide manual ordering.
Plugins can use the existing moderation, redirect, Trash, eligible media-deletion and approved-template mail services. Versioned renderer metadata, structured inline elements and published hierarchy breadcrumbs share the existing content and rendering paths. npm run reference:starter -- --out <directory> --config <file> emits the maintained live-API Astro starter.
These changes are unreleased. Focused verification, the complete browser gate, live mobile/desktop review and real-provider release acceptance remain pending. The new schema belongs to the initial migration; no incremental migration is provided before the first release.
Native forms also gain private file attachments with field-level type, count and size limits, retained-submission downloads and erasure cleanup. Approved plugin email templates can resolve the recipient from an authorized entry’s author or assigned reviewer. Both additions reuse the existing services and remain pending final acceptance.
Added: October account, editorial, plugin and migration source changes
Section titled “Added: October account, editorial, plugin and migration source changes”Current source supports AND/OR groups in content-list filters and contextual choices for relation and select fields. Reviewed CSV/XLSX updates can change existing entries using JSON cells for relations, media and components. Core role rules restrict access by entry. Rich text supports alignment, relation controls, repeatable plugin groups and isolated HTML/CSS/JavaScript vendor snippets. Plugins support delegated CRUD, version and media operations, reviewed upgrades and isolated custom UI.
Account security verifies a new mailbox before changing the same account’s email, keeps memberships, credentials and history, and ends sessions. Sign-in offers self-service password reset when mail is configured, with the same response for known and unknown addresses. AI suggestions for alt text and captions require review. To update translations when saving the source, users must select the target languages and explicitly consent to replacing their text. Connected WordPress REST acquisition produces ordinary WXR and supports explicit, revision-bound replacement of title, tagline, logo, icon, SEO description and supplied indexability through import receipts and undo.
Native site bundles now use format 1.16 and history files 3.1, including entry-folder trees and placements; history also carries placement events. Current readers require these formats and entry-folders.json; export older files again from a matching source.
Focused local checks exist. Final browser integration and live visual review are pending, entry-folder source still awaits final integration acceptance, and no deployment or real-provider acceptance is claimed. See the capability matrix.
Changed: site search finds linked items by their published names only
Section titled “Changed: site search finds linked items by their published names only”Site search and suggestions find an item by the names of the items it links to only while those items are published, public and not in Trash, under their published names. A name saved from a draft is never searched or shown, and a result’s summary holds no linked names. See Linked items.
Changed: each spreadsheet sheet carries its own address
Section titled “Changed: each spreadsheet sheet carries its own address”The slug column on each sheet of an exported workbook is now that language’s own address. Before,
every sheet carried the primary language’s address, so an untouched workbook of an item with
different addresses per language was blocked with spreadsheet_slug_mismatch. Export such
workbooks again. The check also blocks a change in a language the role may read but not change
(locale_denied) and values typed into a language the item has no translation in
(spreadsheet_locale_missing). See Spreadsheet round trip.
Changed: site administrators can reactivate a site
Section titled “Changed: site administrators can reactivate a site”GET /api/sites also lists an inactive site to a person whose role there holds site:settings, and
the admin offers them Reactivate. Before, only a superadmin saw an inactive site. Editors,
viewers and people without a grant still do not see it, and content work on an inactive site stays
refused. See Reactivate a site.
Changed: a field key that kept versions still hold cannot be reused
Section titled “Changed: a field key that kept versions still hold cannot be reused”A model or component save that gives a key a new field while kept versions still hold a value under
it is refused: 409 model_change_blocked with a retained_key_reuse change, or
409 retained_key_reuse for a component. Choose another key. A component created or forked under a
slug the site already reads is judged the same way, against the definition the slug read before.
Confirming the override does not lift the refusal. On a per-site deployment a shared component
change that would read stored values another way, or add a field while content uses the component,
is refused with 409 split_topology_reinterpretation_unsupported. Carried history and a language
put back from Trash wait for a component change that holds their content type, like a save. An
import refuses an entry or carried version whose value sits under a key a field took after the
import’s check (409 import_definition_changed); give that field another key, then continue. A
site copy or history file is also judged against the source’s own definitions: a value under a key
the source did not define, which a field here would read, blocks the check (unmapped_source_key),
whether that field was here before the check or came after it. Give that field another key, then
choose Check again. A value the source keeps private is refused where this site’s field is
public (source_private_value); make that field private. A value under a key the destination will
not have is refused at the check (unsupported_source_key) instead of failing the run with
unknown_fields. See Private fields.
Changed: shared-draft answers follow read access
Section titled “Changed: shared-draft answers follow read access”Read access to a shared draft is decided apart from write access. A person who may change an item
but not read that row or language gets no draft back: current: null on 409 draft_conflict, and
draft: null from a management take over. A discard refused after a take over says
Not discarded — taken over. Your work is kept. See Shared draft.
Changed: access sign-in rules check the role ceiling at commit
Section titled “Changed: access sign-in rules check the role ceiling at commit”Saving a Cloudflare Access sign-in rule saves nothing when the mapped role or the saver’s own access
changed during the save. The answer is 403 escalation_refused or 403 missing_permission when the
rule is now out of reach, otherwise 409 access_authority_changed. See
Sign in through Cloudflare Access.
Changed: mail sends give up after 10 seconds
Section titled “Changed: mail sends give up after 10 seconds”Every mail the CMS sends, form deliveries included, gives up after 10 seconds without an answer and counts as failed. Each form delivery is claimed just before its own send. See Email delivery.
Changed: deleting a model needs model:delete
Section titled “Changed: deleting a model needs model:delete”DELETE /api/models/:id needs the model:delete permission instead of model:apply. A role that
holds only model:apply can no longer delete a model. Refusals, cleanup, audit and site isolation
are unchanged.
Changed: a page needs an address before it is published
Section titled “Changed: a page needs an address before it is published”Publishing a page-model item without an address answers 409 page_address_required and
publishes nothing. Publishing claims the address in the same write, so an address another item
holds answers slug_reserved and nothing is published. POST /api/pages/:id/address sets or
changes a page’s address in a new draft version. The live page keeps its address until that version
is published, and the publication adds a redirect from the old address. See
Build and edit pages.
Changed: a repeated save key replays only for the same person
Section titled “Changed: a repeated save key replays only for the same person”A content save that repeats an idempotency key is replayed only to the person who made it. Another
person’s matching key and body answers 409 idempotency_key_reused and writes nothing.
Removed: the Blog System preset
Section titled “Removed: the Blog System preset”The model builder no longer offers the Blog System preset. A Blog is a site purpose with its own starter. See Blog sites.
Moved: the Error reports switch
Section titled “Moved: the Error reports switch”The switch for reports to Dee Wan is now under Installation → Error reports. It was under Settings → Integrations.
2026-09-19 — documentation and delivery contract update
Section titled “2026-09-19 — documentation and delivery contract update”This entry describes source changes, not a released version or an accepted Cloudflare deployment. The documentation banner identifies the exact source revision and build date. Its upgrade target is that revision only for a clean checkout. A modified checkout is not a reproducible upgrade target.
Operator action: use the GitHub workflow matrix before changing credentials. Verify ACCESS_CONFIG and complete the detachment runbook before removing CMS dependencies. Replace upsert-only external search with the complete-generation contract.
Plugin action: reject out-of-range limits and duplicate capabilities. Validate URL formats and semantic origin/grant constraints. Align command retries with Protocol v1: structured mismatches are terminal, bare transient statuses can retry, and recovered requests reuse their key. Install both root and frontend dependencies for local integration.
Documentation: task-based navigation adds first publication, fields, accounts, migration, backups, webhooks, preview/client and detachment guidance in English, Russian and Thai. Builds require current translation hashes, locale-correct screenshot references and source provenance. Translated pages omit admin screenshots where the admin UI has no real locale support. Genuine localized installer captures remain published.
Authentication source change: a fresh installation can create its first superadmin with password, magic link, Google or GitHub. Every method proves the one normalized BOOTSTRAP_ADMIN_EMAIL. Ordinary sign-in remains closed to account creation. Provider callbacks cannot rewrite canonical account email; the verified owner flow described above now permits an explicit change, same-email verified providers link to one account, a replacement superadmin is promoted with guards on its Settings → People row, and the old one is deactivated on the Installation page under Superadmins. These are source changes, not evidence of a released or deployed build.
Removed: permission templates
Section titled “Removed: permission templates”GET, POST, PATCH and DELETE on /api/permission_template and
/api/permission_template/:id now return 404 for every caller. No permission brings the route
back.
The permission_template table is gone from the initial database schema. It stored per-model
permission templates that nothing read: access comes from a site’s roles. Express
permissions as roles instead, under Settings → Roles.
Because Dee Wan has not been released, no deployed database holds this table. A local database created from an earlier development schema still has it. Recreate that database from the current schema.
Removed: legacy media MIME repair
Section titled “Removed: legacy media MIME repair”The doctor and setup check that counted media rows without a MIME type, and the repair scripts
behind it, are removed. Every write path records a verified MIME type, and no earlier version wrote
rows without one.
Changed: npm run doctor checks the DB binding
Section titled “Changed: npm run doctor checks the DB binding”npm run doctor reports a missing or blank DB D1 binding in its own row, D1 binding (DB).
Unreleased / pre-MVP; no stable version
Source revision: fe23db481c422b40e317b92fc98116b4c0c26a87 (modified checkout)
Build date (UTC): 2026-10-18T09:22:34.630Z
Upgrade target: unavailable: modified checkout. Release notes