diff --git a/.changeset/datadir-guard-239.md b/.changeset/datadir-guard-239.md deleted file mode 100644 index 4bcdbf6b..00000000 --- a/.changeset/datadir-guard-239.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@cloudhal/astro-renderer": patch ---- - -The `cloudflare` target no longer bakes `dataDir` into `virtual:cloudhal/config` (#239, RFC-0046 §11b). The Site Worker reads D1 and R2 through its bindings and never read the field. The baked value was the build machine's absolute data path, so a release bundle built in CI would have carried that path to every deployment. Node targets (`cloudhal dev`, static builds) keep it. - -The virtual module is now typed as `VirtualCloudhalConfig`, with `dataDir` optional; the type is exported, and the starter's `env.d.ts` uses it. Theme code that reads `dataDir` must handle its absence on the Cloudflare Site Worker. diff --git a/.changeset/deploy-release-227.md b/.changeset/deploy-release-227.md deleted file mode 100644 index 6c16ae2f..00000000 --- a/.changeset/deploy-release-227.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@cloudhal/cli": minor -"@cloudhal/release-verify": patch -"@cloudhal/astro-renderer": patch ---- - -`cloudhal deploy --release` installs the signed release of the CLI's own version instead of building the project (RFC-0046 §11b, #227). - -- **Trust lists.** On every run it fetches the signed key list and yank list from cloudhal.dev and verifies them against the pinned root. It never falls back to an older copy. It keeps a yank memory in `~/.cloudhal/release-trust.json`, so a rolled-back list, a replayed key list or a revoked yank key is refused. -- **Before the root ceremony** no root is pinned, so the command refuses and names the ceremony. -- **The release.** The release must be published (not a draft) and carry a bundle; `v0.8.0` and older have none. The CLI verifies it with `@cloudhal/release-verify`: the keys reduced by both lists, yanked versions refused, and every file checked against its digest. -- **The attestation.** It checks the build-provenance attestation with `gh`. `--allow-single-factor` continues on the release key alone when `gh` is unavailable; a failed attestation is always refused. -- **The project.** Its theme files must equal the CLI's own starter, unless `--discard-local-theme` is given. Its `cloudhal.json` build keys must match the starter's, a key the CLI does not know is refused, and the installed wrangler must be at least the bundle's. -- **Refused projects.** Projects attached to another installation, multi-site projects and Workers Builds are refused. -- **Deploying.** The verified files are extracted into a fresh `.cloudhal/deploy/release//`. Both Workers are then deployed with `no_bundle` wrangler configs that upload exactly those bytes. -- **Offline and dry runs.** `--from ` installs offline from the assets and both lists, and `--release --dry-run` stops before wrangler. - -The CLI now depends on `@cloudhal/release-verify`. - -`@cloudhal/release-verify` now typechecks under every consumer's lib settings: WebCrypto inputs are `ArrayBuffer`-backed views, and the gzip pipe is typed through explicitly. `@cloudhal/astro-renderer` names the Site Worker's single-site choice `singleSiteId`, so a test holds that `CLOUDHAL_SITE_ID` overrides the built id. diff --git a/.changeset/pin-root-2026a.md b/.changeset/pin-root-2026a.md deleted file mode 100644 index ad2c1af6..00000000 --- a/.changeset/pin-root-2026a.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@cloudhal/release-verify": patch ---- - -`PINNED_ROOTS` now pins the offline root `cloudhal-root-2026a` (Ed25519, from the owner's root ceremony on 2026-11-15). `verifyKeys` verifies the published `keys.json` with it by default. The first `keys.json` lists the release key `cloudhal-release-2026a` and the yank key `cloudhal-yank-2026a`, and is committed as `security/keys.json`. A CLI built with this version can run `cloudhal deploy --release` once cloudhal.dev serves the lists. diff --git a/.changeset/release-trust-226.md b/.changeset/release-trust-226.md deleted file mode 100644 index 4e31b222..00000000 --- a/.changeset/release-trust-226.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@cloudhal/release-verify": patch -"@cloudhal/core-contracts": patch ---- - -Signed key and yank lists for release bundles (RFC-0046 §9, #226). - -`@cloudhal/core-contracts` gains the `release-keys` root (`keys.json`, signed by an offline root) and the `release-yank-list` root (`yanked.json`, signed by a yank key and expiring 30 days after it is issued). - -`@cloudhal/release-verify` gains: -- `verifyKeys`, which checks a pinned root's signature and that the list is fresh (`expires` at most 13 months after `issuedAt`); -- `verifyYanked`, which checks a signature by an active yank key that `keys.json` lists, and refuses a stale list with `stale-yank-list`; -- `rememberYanks` and the `memory` option of `verifyKeys` and `verifyYanked`, for consumers that keep state: they refuse a rolled-back or pruned yank list, a replayed older `keys.json`, and a revoked or replaced yank key. A `keys.json` may list at most one active yank key; -- `mergeTrust`, which only reduces trust in the pinned keys: it revokes, marks retiring, and narrows a key's validity window, and it never adds a key. - -`verifyRelease` now enforces each key's validity window. A statement's `createdAt` must lie within its key's `[notBefore, notAfter]`. After `notAfter`, a key verifies only while a fresh `keys.json` lists it as retiring; otherwise the release is refused with `key-expired`. `verifyRelease` also refuses a yanked version (`yanked`). `PINNED_KEYS` now carries each key's window. diff --git a/.changeset/release-verify-package.md b/.changeset/release-verify-package.md deleted file mode 100644 index c75f86f6..00000000 --- a/.changeset/release-verify-package.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"@cloudhal/release-verify": patch ---- - -New package `@cloudhal/release-verify` (RFC-0046 §11a). It is the one verifier of Cloudhal release bundles, and it is Worker-safe. - -`verifyRelease` runs these checks in order, and refuses on the first failure: -- the Ed25519 signature on `release-statement.json`, against the pinned release keys; -- that the statement is for the version and channel you asked for; -- both precompiled validators; -- every digest and §7 limit; -- the tarball, in two passes. - -The tarball is never held whole. The first pass checks its digest, and the second yields each entry only once it is verified. Unsafe entry paths (`..`, `.`, empty segments, backslashes, control characters, case-fold duplicates) are refused with `entry-path`. Every refusal carries a stable `code`. - -The package also exports: -- `missingScopes`, which applies §3's rule that `workers-scripts.admin` covers `workers-scripts.edit`; -- `releaseAssetUrls`; -- `PINNED_KEYS`, which can only be reduced. - -The Node-only subpath `@cloudhal/release-verify/attestation` checks the GitHub build attestation with `gh` 2.68.0 or newer. diff --git a/.changeset/render-chrome-start-retries.md b/.changeset/render-chrome-start-retries.md deleted file mode 100644 index b37e140b..00000000 --- a/.changeset/render-chrome-start-retries.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@cloudhal/cli": patch ---- - -`render_page` on Node gives a slow Chrome more chances to start. A launch that hangs past its start budget or exits is killed, and the renderer tries again up to three times. Each try uses a new profile, and the pause doubles from 1 s. The error says how long a launch may take and how many tries were made. A Chrome that crashes after it started is launched again by the next render, and its profile is removed (#207). diff --git a/.changeset/rfc45-step7b-enable.md b/.changeset/rfc45-step7b-enable.md deleted file mode 100644 index 7f791136..00000000 --- a/.changeset/rfc45-step7b-enable.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@cloudhal/core-ts": patch -"@cloudhal/storage": patch -"@cloudhal/cloudflare": patch -"@cloudhal/api": patch -"@cloudhal/cli": patch -"@cloudhal/mcp-server": patch ---- - -RFC-0045 rollout step 7b: **reference and repeater fields are now enabled.** Sites can define `reference` fields (entries of one to five collections of the same site, one or several, with optional conditions) and `repeater` fields (ordered lists of items with up to ten flat sub-fields) wherever the renderer serving them reads the two types. See [docs/guides/fields.md](https://github.com/cloudhal-dev/cloudhal/blob/main/docs/guides/fields.md). - -- **Where.** On Cloudflare, once the site Worker serving the site answers `GET /__cloudhal/features` with `fields: 2` (0.9.0 and later): the admin Worker asks the Worker each site is routed to (`SITE`, or an attached `SITE_n`), as it asks for time gates, and remembers a yes for that Worker only. Time gates are now confirmed per site Worker too, so a site on an older attached Worker no longer inherits the installation Worker's answer. Deploy the site Worker first; until it reports `fields: 2`, the types stay refused with `fields_unsupported` on every path. On Node (`cloudhal dev`, `studio`, self-host, Docker) and in the playground, always, since the renderer runs in the same process (`openLocalStore` passes `FIELDS_SUPPORTED`). -- **Every write path follows the capability:** Studio, MCP, the API, field operations and their dry runs, and every bundle: `cloudhal push` (the admin route passes the store's capability), `pull`, `cloudhal import` (dry runs included), `--replace` and `--revert`. A bundle that defines either type is still refused whole where the capability does not hold, and a site's new snapshot cannot point at another site's held site body to bring the types in. -- **MCP and Studio.** `update_collection` and `change_field_type` list both types, and `/api/instance` answers `features.referenceFields: true`, on servers that have the capability. The store still decides per site. -- **A one-time `entry_refs` check per site** (`rebuildEntryRefs`, new core-ts export): the admin Worker's new `refs.rebuild` system job (every five minutes, offset from `lists.backfill`, until every site is done; then two reads a run), and `openLocalStore` at start-up. Rows are written per entry, anchored on the hash each entry was read with, so a concurrent edit keeps its own rows; each chunk is anchored on the site node's hash, so no statement grows with the site's settings; it leaves a site alone while a text ↔ reference type change runs there; progress is in the new `entry_refs_state` table (storage migration `0034_entry_refs_state`), so a run stopped anywhere resumes. It is a safety net and should find nothing to change. diff --git a/.changeset/ui-dashboard-blocks.md b/.changeset/ui-dashboard-blocks.md deleted file mode 100644 index 11ac10b0..00000000 --- a/.changeset/ui-dashboard-blocks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@cloudhal/cli": patch ---- - -Studio's list toolbars come from one shared `@cloudhal/ui` block. The search now fills the free width of the row, and the filters, other actions, sort and refresh follow in a fixed order. `@cloudhal/ui` also gains `StatusIndicator`, `UsageMeterRow`, a "View docs" pill on `PageLayout`, and a resource mode for one resource's detail page: its tabs under the top bar, actions on the right, and no large title (#228). diff --git a/packages/agent-runtime/CHANGELOG.md b/packages/agent-runtime/CHANGELOG.md index 0a999d3e..d7c409ac 100644 --- a/packages/agent-runtime/CHANGELOG.md +++ b/packages/agent-runtime/CHANGELOG.md @@ -1,5 +1,14 @@ # @cloudhal/agent-runtime +## 0.10.0 + +### Patch Changes + +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/storage@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/agent-runtime/package.json b/packages/agent-runtime/package.json index b1bec95a..e506a6cf 100644 --- a/packages/agent-runtime/package.json +++ b/packages/agent-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/agent-runtime", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal agent runtime: policy engine (actors, scopes, approvals), skill loader, audit log", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/analytics/CHANGELOG.md b/packages/analytics/CHANGELOG.md index 80acbcd8..88f3b417 100644 --- a/packages/analytics/CHANGELOG.md +++ b/packages/analytics/CHANGELOG.md @@ -1,5 +1,14 @@ # @cloudhal/analytics +## 0.10.0 + +### Patch Changes + +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/storage@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 244da050..50503863 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/analytics", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal site analytics (RFC-0006): query model, classifiers, beacon handler, SQLite/D1 store, daily rollups and Workers Analytics Engine adapters. Worker-safe.", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index 6b7ed55e..72ff6523 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -1,5 +1,29 @@ # @cloudhal/api +## 0.10.0 + +### Patch Changes + +- 74d7098: RFC-0045 rollout step 7b: **reference and repeater fields are now enabled.** Sites can define `reference` fields (entries of one to five collections of the same site, one or several, with optional conditions) and `repeater` fields (ordered lists of items with up to ten flat sub-fields) wherever the renderer serving them reads the two types. See [docs/guides/fields.md](https://github.com/cloudhal-dev/cloudhal/blob/main/docs/guides/fields.md). + + - **Where.** On Cloudflare, once the site Worker serving the site answers `GET /__cloudhal/features` with `fields: 2` (0.9.0 and later): the admin Worker asks the Worker each site is routed to (`SITE`, or an attached `SITE_n`), as it asks for time gates, and remembers a yes for that Worker only. Time gates are now confirmed per site Worker too, so a site on an older attached Worker no longer inherits the installation Worker's answer. Deploy the site Worker first; until it reports `fields: 2`, the types stay refused with `fields_unsupported` on every path. On Node (`cloudhal dev`, `studio`, self-host, Docker) and in the playground, always, since the renderer runs in the same process (`openLocalStore` passes `FIELDS_SUPPORTED`). + - **Every write path follows the capability:** Studio, MCP, the API, field operations and their dry runs, and every bundle: `cloudhal push` (the admin route passes the store's capability), `pull`, `cloudhal import` (dry runs included), `--replace` and `--revert`. A bundle that defines either type is still refused whole where the capability does not hold, and a site's new snapshot cannot point at another site's held site body to bring the types in. + - **MCP and Studio.** `update_collection` and `change_field_type` list both types, and `/api/instance` answers `features.referenceFields: true`, on servers that have the capability. The store still decides per site. + - **A one-time `entry_refs` check per site** (`rebuildEntryRefs`, new core-ts export): the admin Worker's new `refs.rebuild` system job (every five minutes, offset from `lists.backfill`, until every site is done; then two reads a run), and `openLocalStore` at start-up. Rows are written per entry, anchored on the hash each entry was read with, so a concurrent edit keeps its own rows; each chunk is anchored on the site node's hash, so no statement grows with the site's settings; it leaves a site alone while a text ↔ reference type change runs there; progress is in the new `entry_refs_state` table (storage migration `0034_entry_refs_state`), so a run stopped anywhere resumes. It is a safety net and should find nothing to change. +- Updated dependencies [4cb3ac6] +- Updated dependencies [f41802b] +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/astro-renderer@0.10.0 + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/core-ts@0.10.0 + - @cloudhal/storage@0.10.0 + - @cloudhal/mcp-server@0.10.0 + - @cloudhal/agent-runtime@0.10.0 + - @cloudhal/analytics@0.10.0 + - @cloudhal/comments@0.10.0 + - @cloudhal/schedules@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/api/package.json b/packages/api/package.json index a1d03aee..6c62b12b 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/api", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal HTTP API (Hono): sites, pages, entries, snapshots, auth — runs on Node and Cloudflare Workers", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/astro-renderer/CHANGELOG.md b/packages/astro-renderer/CHANGELOG.md index 5c36e83e..01e36b14 100644 --- a/packages/astro-renderer/CHANGELOG.md +++ b/packages/astro-renderer/CHANGELOG.md @@ -1,5 +1,34 @@ # @cloudhal/astro-renderer +## 0.10.0 + +### Patch Changes + +- 4cb3ac6: The `cloudflare` target no longer bakes `dataDir` into `virtual:cloudhal/config` (#239, RFC-0046 §11b). The Site Worker reads D1 and R2 through its bindings and never read the field. The baked value was the build machine's absolute data path, so a release bundle built in CI would have carried that path to every deployment. Node targets (`cloudhal dev`, static builds) keep it. + + The virtual module is now typed as `VirtualCloudhalConfig`, with `dataDir` optional; the type is exported, and the starter's `env.d.ts` uses it. Theme code that reads `dataDir` must handle its absence on the Cloudflare Site Worker. +- f41802b: `cloudhal deploy --release` installs the signed release of the CLI's own version instead of building the project (RFC-0046 §11b, #227). + + - **Trust lists.** On every run it fetches the signed key list and yank list from cloudhal.dev and verifies them against the pinned root. It never falls back to an older copy. It keeps a yank memory in `~/.cloudhal/release-trust.json`, so a rolled-back list, a replayed key list or a revoked yank key is refused. + - **Before the root ceremony** no root is pinned, so the command refuses and names the ceremony. + - **The release.** The release must be published (not a draft) and carry a bundle; `v0.8.0` and older have none. The CLI verifies it with `@cloudhal/release-verify`: the keys reduced by both lists, yanked versions refused, and every file checked against its digest. + - **The attestation.** It checks the build-provenance attestation with `gh`. `--allow-single-factor` continues on the release key alone when `gh` is unavailable; a failed attestation is always refused. + - **The project.** Its theme files must equal the CLI's own starter, unless `--discard-local-theme` is given. Its `cloudhal.json` build keys must match the starter's, a key the CLI does not know is refused, and the installed wrangler must be at least the bundle's. + - **Refused projects.** Projects attached to another installation, multi-site projects and Workers Builds are refused. + - **Deploying.** The verified files are extracted into a fresh `.cloudhal/deploy/release//`. Both Workers are then deployed with `no_bundle` wrangler configs that upload exactly those bytes. + - **Offline and dry runs.** `--from ` installs offline from the assets and both lists, and `--release --dry-run` stops before wrangler. + + The CLI now depends on `@cloudhal/release-verify`. + + `@cloudhal/release-verify` now typechecks under every consumer's lib settings: WebCrypto inputs are `ArrayBuffer`-backed views, and the gzip pipe is typed through explicitly. `@cloudhal/astro-renderer` names the Site Worker's single-site choice `singleSiteId`, so a test holds that `CLOUDHAL_SITE_ID` overrides the built id. +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/core-ts@0.10.0 + - @cloudhal/storage@0.10.0 + - @cloudhal/analytics@0.10.0 + - @cloudhal/comments@0.10.0 + ## 0.9.0 ### Minor Changes diff --git a/packages/astro-renderer/package.json b/packages/astro-renderer/package.json index 72e63f35..a9ccd9a9 100644 --- a/packages/astro-renderer/package.json +++ b/packages/astro-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/astro-renderer", - "version": "0.9.0", + "version": "0.10.0", "description": "Render a Cloudhal Site Graph with Astro: data sources (live/snapshot), section components and the cloudhal() integration", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a977909b..1cc4c974 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,53 @@ # @cloudhal/cli +## 0.10.0 + +### Minor Changes + +- f41802b: `cloudhal deploy --release` installs the signed release of the CLI's own version instead of building the project (RFC-0046 §11b, #227). + + - **Trust lists.** On every run it fetches the signed key list and yank list from cloudhal.dev and verifies them against the pinned root. It never falls back to an older copy. It keeps a yank memory in `~/.cloudhal/release-trust.json`, so a rolled-back list, a replayed key list or a revoked yank key is refused. + - **Before the root ceremony** no root is pinned, so the command refuses and names the ceremony. + - **The release.** The release must be published (not a draft) and carry a bundle; `v0.8.0` and older have none. The CLI verifies it with `@cloudhal/release-verify`: the keys reduced by both lists, yanked versions refused, and every file checked against its digest. + - **The attestation.** It checks the build-provenance attestation with `gh`. `--allow-single-factor` continues on the release key alone when `gh` is unavailable; a failed attestation is always refused. + - **The project.** Its theme files must equal the CLI's own starter, unless `--discard-local-theme` is given. Its `cloudhal.json` build keys must match the starter's, a key the CLI does not know is refused, and the installed wrangler must be at least the bundle's. + - **Refused projects.** Projects attached to another installation, multi-site projects and Workers Builds are refused. + - **Deploying.** The verified files are extracted into a fresh `.cloudhal/deploy/release//`. Both Workers are then deployed with `no_bundle` wrangler configs that upload exactly those bytes. + - **Offline and dry runs.** `--from ` installs offline from the assets and both lists, and `--release --dry-run` stops before wrangler. + + The CLI now depends on `@cloudhal/release-verify`. + + `@cloudhal/release-verify` now typechecks under every consumer's lib settings: WebCrypto inputs are `ArrayBuffer`-backed views, and the gzip pipe is typed through explicitly. `@cloudhal/astro-renderer` names the Site Worker's single-site choice `singleSiteId`, so a test holds that `CLOUDHAL_SITE_ID` overrides the built id. + +### Patch Changes + +- 49720db: `render_page` on Node gives a slow Chrome more chances to start. A launch that hangs past its start budget or exits is killed, and the renderer tries again up to three times. Each try uses a new profile, and the pause doubles from 1 s. The error says how long a launch may take and how many tries were made. A Chrome that crashes after it started is launched again by the next render, and its profile is removed (#207). +- 74d7098: RFC-0045 rollout step 7b: **reference and repeater fields are now enabled.** Sites can define `reference` fields (entries of one to five collections of the same site, one or several, with optional conditions) and `repeater` fields (ordered lists of items with up to ten flat sub-fields) wherever the renderer serving them reads the two types. See [docs/guides/fields.md](https://github.com/cloudhal-dev/cloudhal/blob/main/docs/guides/fields.md). + + - **Where.** On Cloudflare, once the site Worker serving the site answers `GET /__cloudhal/features` with `fields: 2` (0.9.0 and later): the admin Worker asks the Worker each site is routed to (`SITE`, or an attached `SITE_n`), as it asks for time gates, and remembers a yes for that Worker only. Time gates are now confirmed per site Worker too, so a site on an older attached Worker no longer inherits the installation Worker's answer. Deploy the site Worker first; until it reports `fields: 2`, the types stay refused with `fields_unsupported` on every path. On Node (`cloudhal dev`, `studio`, self-host, Docker) and in the playground, always, since the renderer runs in the same process (`openLocalStore` passes `FIELDS_SUPPORTED`). + - **Every write path follows the capability:** Studio, MCP, the API, field operations and their dry runs, and every bundle: `cloudhal push` (the admin route passes the store's capability), `pull`, `cloudhal import` (dry runs included), `--replace` and `--revert`. A bundle that defines either type is still refused whole where the capability does not hold, and a site's new snapshot cannot point at another site's held site body to bring the types in. + - **MCP and Studio.** `update_collection` and `change_field_type` list both types, and `/api/instance` answers `features.referenceFields: true`, on servers that have the capability. The store still decides per site. + - **A one-time `entry_refs` check per site** (`rebuildEntryRefs`, new core-ts export): the admin Worker's new `refs.rebuild` system job (every five minutes, offset from `lists.backfill`, until every site is done; then two reads a run), and `openLocalStore` at start-up. Rows are written per entry, anchored on the hash each entry was read with, so a concurrent edit keeps its own rows; each chunk is anchored on the site node's hash, so no statement grows with the site's settings; it leaves a site alone while a text ↔ reference type change runs there; progress is in the new `entry_refs_state` table (storage migration `0034_entry_refs_state`), so a run stopped anywhere resumes. It is a safety net and should find nothing to change. +- 9501d81: Studio's list toolbars come from one shared `@cloudhal/ui` block. The search now fills the free width of the row, and the filters, other actions, sort and refresh follow in a fixed order. `@cloudhal/ui` also gains `StatusIndicator`, `UsageMeterRow`, a "View docs" pill on `PageLayout`, and a resource mode for one resource's detail page: its tabs under the top bar, actions on the right, and no large title (#228). +- Updated dependencies [4cb3ac6] +- Updated dependencies [f41802b] +- Updated dependencies [5baacb4] +- Updated dependencies [61825b8] +- Updated dependencies [3ffdf29] +- Updated dependencies [74d7098] + - @cloudhal/astro-renderer@0.10.0 + - @cloudhal/release-verify@0.10.0 + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/core-ts@0.10.0 + - @cloudhal/storage@0.10.0 + - @cloudhal/cloudflare@0.10.0 + - @cloudhal/api@0.10.0 + - @cloudhal/mcp-server@0.10.0 + - @cloudhal/agent-runtime@0.10.0 + - @cloudhal/analytics@0.10.0 + - @cloudhal/comments@0.10.0 + - @cloudhal/schedules@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index e8ac23a1..65528326 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/cli", - "version": "0.9.0", + "version": "0.10.0", "description": "cloudhal \u2014 create, run and build Cloudhal sites locally", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/cloudflare/CHANGELOG.md b/packages/cloudflare/CHANGELOG.md index bec89b9c..505919c9 100644 --- a/packages/cloudflare/CHANGELOG.md +++ b/packages/cloudflare/CHANGELOG.md @@ -1,5 +1,25 @@ # @cloudhal/cloudflare +## 0.10.0 + +### Patch Changes + +- 74d7098: RFC-0045 rollout step 7b: **reference and repeater fields are now enabled.** Sites can define `reference` fields (entries of one to five collections of the same site, one or several, with optional conditions) and `repeater` fields (ordered lists of items with up to ten flat sub-fields) wherever the renderer serving them reads the two types. See [docs/guides/fields.md](https://github.com/cloudhal-dev/cloudhal/blob/main/docs/guides/fields.md). + + - **Where.** On Cloudflare, once the site Worker serving the site answers `GET /__cloudhal/features` with `fields: 2` (0.9.0 and later): the admin Worker asks the Worker each site is routed to (`SITE`, or an attached `SITE_n`), as it asks for time gates, and remembers a yes for that Worker only. Time gates are now confirmed per site Worker too, so a site on an older attached Worker no longer inherits the installation Worker's answer. Deploy the site Worker first; until it reports `fields: 2`, the types stay refused with `fields_unsupported` on every path. On Node (`cloudhal dev`, `studio`, self-host, Docker) and in the playground, always, since the renderer runs in the same process (`openLocalStore` passes `FIELDS_SUPPORTED`). + - **Every write path follows the capability:** Studio, MCP, the API, field operations and their dry runs, and every bundle: `cloudhal push` (the admin route passes the store's capability), `pull`, `cloudhal import` (dry runs included), `--replace` and `--revert`. A bundle that defines either type is still refused whole where the capability does not hold, and a site's new snapshot cannot point at another site's held site body to bring the types in. + - **MCP and Studio.** `update_collection` and `change_field_type` list both types, and `/api/instance` answers `features.referenceFields: true`, on servers that have the capability. The store still decides per site. + - **A one-time `entry_refs` check per site** (`rebuildEntryRefs`, new core-ts export): the admin Worker's new `refs.rebuild` system job (every five minutes, offset from `lists.backfill`, until every site is done; then two reads a run), and `openLocalStore` at start-up. Rows are written per entry, anchored on the hash each entry was read with, so a concurrent edit keeps its own rows; each chunk is anchored on the site node's hash, so no statement grows with the site's settings; it leaves a site alone while a text ↔ reference type change runs there; progress is in the new `entry_refs_state` table (storage migration `0034_entry_refs_state`), so a run stopped anywhere resumes. It is a safety net and should find nothing to change. +- Updated dependencies [74d7098] + - @cloudhal/core-ts@0.10.0 + - @cloudhal/storage@0.10.0 + - @cloudhal/api@0.10.0 + - @cloudhal/mcp-server@0.10.0 + - @cloudhal/agent-runtime@0.10.0 + - @cloudhal/analytics@0.10.0 + - @cloudhal/comments@0.10.0 + - @cloudhal/schedules@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json index 24c3bd1c..3eb868b7 100644 --- a/packages/cloudflare/package.json +++ b/packages/cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/cloudflare", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal on Cloudflare: the admin Worker (API, auth, MCP, Studio) over D1 + R2", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/comments/CHANGELOG.md b/packages/comments/CHANGELOG.md index c7d8439e..078a20b9 100644 --- a/packages/comments/CHANGELOG.md +++ b/packages/comments/CHANGELOG.md @@ -1,5 +1,15 @@ # @cloudhal/comments +## 0.10.0 + +### Patch Changes + +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/core-ts@0.10.0 + - @cloudhal/storage@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/comments/package.json b/packages/comments/package.json index c713b959..39333f2e 100644 --- a/packages/comments/package.json +++ b/packages/comments/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/comments", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal reader comments (RFC-0007): settings and thread state, text normalising and content rules, linkify, first-party proof of work, the submission pipeline, purge planner, retention plan and the SQLite/D1 store. Worker-safe.", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/core-contracts/CHANGELOG.md b/packages/core-contracts/CHANGELOG.md index f0669b90..d99d902c 100644 --- a/packages/core-contracts/CHANGELOG.md +++ b/packages/core-contracts/CHANGELOG.md @@ -1,5 +1,21 @@ # @cloudhal/core-contracts +## 0.10.0 + +### Patch Changes + +- 61825b8: Signed key and yank lists for release bundles (RFC-0046 §9, #226). + + `@cloudhal/core-contracts` gains the `release-keys` root (`keys.json`, signed by an offline root) and the `release-yank-list` root (`yanked.json`, signed by a yank key and expiring 30 days after it is issued). + + `@cloudhal/release-verify` gains: + - `verifyKeys`, which checks a pinned root's signature and that the list is fresh (`expires` at most 13 months after `issuedAt`); + - `verifyYanked`, which checks a signature by an active yank key that `keys.json` lists, and refuses a stale list with `stale-yank-list`; + - `rememberYanks` and the `memory` option of `verifyKeys` and `verifyYanked`, for consumers that keep state: they refuse a rolled-back or pruned yank list, a replayed older `keys.json`, and a revoked or replaced yank key. A `keys.json` may list at most one active yank key; + - `mergeTrust`, which only reduces trust in the pinned keys: it revokes, marks retiring, and narrows a key's validity window, and it never adds a key. + + `verifyRelease` now enforces each key's validity window. A statement's `createdAt` must lie within its key's `[notBefore, notAfter]`. After `notAfter`, a key verifies only while a fresh `keys.json` lists it as retiring; otherwise the release is refused with `key-expired`. `verifyRelease` also refuses a yanked version (`yanked`). `PINNED_KEYS` now carries each key's window. + ## 0.9.0 ### Patch Changes diff --git a/packages/core-contracts/package.json b/packages/core-contracts/package.json index 1549b990..9b62f753 100644 --- a/packages/core-contracts/package.json +++ b/packages/core-contracts/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/core-contracts", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal domain contracts: JSON Schema source of truth plus generated TypeScript types", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/core-ts/CHANGELOG.md b/packages/core-ts/CHANGELOG.md index 4ddc5934..b383d25f 100644 --- a/packages/core-ts/CHANGELOG.md +++ b/packages/core-ts/CHANGELOG.md @@ -1,5 +1,21 @@ # @cloudhal/core-ts +## 0.10.0 + +### Patch Changes + +- 74d7098: RFC-0045 rollout step 7b: **reference and repeater fields are now enabled.** Sites can define `reference` fields (entries of one to five collections of the same site, one or several, with optional conditions) and `repeater` fields (ordered lists of items with up to ten flat sub-fields) wherever the renderer serving them reads the two types. See [docs/guides/fields.md](https://github.com/cloudhal-dev/cloudhal/blob/main/docs/guides/fields.md). + + - **Where.** On Cloudflare, once the site Worker serving the site answers `GET /__cloudhal/features` with `fields: 2` (0.9.0 and later): the admin Worker asks the Worker each site is routed to (`SITE`, or an attached `SITE_n`), as it asks for time gates, and remembers a yes for that Worker only. Time gates are now confirmed per site Worker too, so a site on an older attached Worker no longer inherits the installation Worker's answer. Deploy the site Worker first; until it reports `fields: 2`, the types stay refused with `fields_unsupported` on every path. On Node (`cloudhal dev`, `studio`, self-host, Docker) and in the playground, always, since the renderer runs in the same process (`openLocalStore` passes `FIELDS_SUPPORTED`). + - **Every write path follows the capability:** Studio, MCP, the API, field operations and their dry runs, and every bundle: `cloudhal push` (the admin route passes the store's capability), `pull`, `cloudhal import` (dry runs included), `--replace` and `--revert`. A bundle that defines either type is still refused whole where the capability does not hold, and a site's new snapshot cannot point at another site's held site body to bring the types in. + - **MCP and Studio.** `update_collection` and `change_field_type` list both types, and `/api/instance` answers `features.referenceFields: true`, on servers that have the capability. The store still decides per site. + - **A one-time `entry_refs` check per site** (`rebuildEntryRefs`, new core-ts export): the admin Worker's new `refs.rebuild` system job (every five minutes, offset from `lists.backfill`, until every site is done; then two reads a run), and `openLocalStore` at start-up. Rows are written per entry, anchored on the hash each entry was read with, so a concurrent edit keeps its own rows; each chunk is anchored on the site node's hash, so no statement grows with the site's settings; it leaves a site alone while a text ↔ reference type change runs there; progress is in the new `entry_refs_state` table (storage migration `0034_entry_refs_state`), so a run stopped anywhere resumes. It is a safety net and should find nothing to change. +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/storage@0.10.0 + - @cloudhal/schedules@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/core-ts/package.json b/packages/core-ts/package.json index 43e68d68..3ad5769c 100644 --- a/packages/core-ts/package.json +++ b/packages/core-ts/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/core-ts", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal Site Graph core (TypeScript): load/save nodes with optimistic locking, snapshots, diff, publish and rollback; taxonomies, terms, redirects and menus", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/create-cloudhal/CHANGELOG.md b/packages/create-cloudhal/CHANGELOG.md index f4012703..e61c4d89 100644 --- a/packages/create-cloudhal/CHANGELOG.md +++ b/packages/create-cloudhal/CHANGELOG.md @@ -1,5 +1,15 @@ # create-cloudhal +## 0.10.0 + +### Patch Changes + +- Updated dependencies [f41802b] +- Updated dependencies [49720db] +- Updated dependencies [74d7098] +- Updated dependencies [9501d81] + - @cloudhal/cli@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/create-cloudhal/package.json b/packages/create-cloudhal/package.json index 90227101..0675ac4e 100644 --- a/packages/create-cloudhal/package.json +++ b/packages/create-cloudhal/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudhal", - "version": "0.9.0", + "version": "0.10.0", "description": "Create a Cloudhal site: npm create cloudhal@latest", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/mcp-server/CHANGELOG.md b/packages/mcp-server/CHANGELOG.md index 4d94540b..16045e88 100644 --- a/packages/mcp-server/CHANGELOG.md +++ b/packages/mcp-server/CHANGELOG.md @@ -1,5 +1,28 @@ # @cloudhal/mcp-server +## 0.10.0 + +### Patch Changes + +- 74d7098: RFC-0045 rollout step 7b: **reference and repeater fields are now enabled.** Sites can define `reference` fields (entries of one to five collections of the same site, one or several, with optional conditions) and `repeater` fields (ordered lists of items with up to ten flat sub-fields) wherever the renderer serving them reads the two types. See [docs/guides/fields.md](https://github.com/cloudhal-dev/cloudhal/blob/main/docs/guides/fields.md). + + - **Where.** On Cloudflare, once the site Worker serving the site answers `GET /__cloudhal/features` with `fields: 2` (0.9.0 and later): the admin Worker asks the Worker each site is routed to (`SITE`, or an attached `SITE_n`), as it asks for time gates, and remembers a yes for that Worker only. Time gates are now confirmed per site Worker too, so a site on an older attached Worker no longer inherits the installation Worker's answer. Deploy the site Worker first; until it reports `fields: 2`, the types stay refused with `fields_unsupported` on every path. On Node (`cloudhal dev`, `studio`, self-host, Docker) and in the playground, always, since the renderer runs in the same process (`openLocalStore` passes `FIELDS_SUPPORTED`). + - **Every write path follows the capability:** Studio, MCP, the API, field operations and their dry runs, and every bundle: `cloudhal push` (the admin route passes the store's capability), `pull`, `cloudhal import` (dry runs included), `--replace` and `--revert`. A bundle that defines either type is still refused whole where the capability does not hold, and a site's new snapshot cannot point at another site's held site body to bring the types in. + - **MCP and Studio.** `update_collection` and `change_field_type` list both types, and `/api/instance` answers `features.referenceFields: true`, on servers that have the capability. The store still decides per site. + - **A one-time `entry_refs` check per site** (`rebuildEntryRefs`, new core-ts export): the admin Worker's new `refs.rebuild` system job (every five minutes, offset from `lists.backfill`, until every site is done; then two reads a run), and `openLocalStore` at start-up. Rows are written per entry, anchored on the hash each entry was read with, so a concurrent edit keeps its own rows; each chunk is anchored on the site node's hash, so no statement grows with the site's settings; it leaves a site alone while a text ↔ reference type change runs there; progress is in the new `entry_refs_state` table (storage migration `0034_entry_refs_state`), so a run stopped anywhere resumes. It is a safety net and should find nothing to change. +- Updated dependencies [4cb3ac6] +- Updated dependencies [f41802b] +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/astro-renderer@0.10.0 + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/core-ts@0.10.0 + - @cloudhal/storage@0.10.0 + - @cloudhal/agent-runtime@0.10.0 + - @cloudhal/analytics@0.10.0 + - @cloudhal/comments@0.10.0 + - @cloudhal/schedules@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 7fd42966..ad12a093 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/mcp-server", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal MCP server: semantic site tools (pages, articles, snapshots, preview, publish) governed by the policy engine", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/release-verify/CHANGELOG.md b/packages/release-verify/CHANGELOG.md new file mode 100644 index 00000000..6f7bed33 --- /dev/null +++ b/packages/release-verify/CHANGELOG.md @@ -0,0 +1,49 @@ +# @cloudhal/release-verify + +## 0.10.0 + +### Patch Changes + +- f41802b: `cloudhal deploy --release` installs the signed release of the CLI's own version instead of building the project (RFC-0046 §11b, #227). + + - **Trust lists.** On every run it fetches the signed key list and yank list from cloudhal.dev and verifies them against the pinned root. It never falls back to an older copy. It keeps a yank memory in `~/.cloudhal/release-trust.json`, so a rolled-back list, a replayed key list or a revoked yank key is refused. + - **Before the root ceremony** no root is pinned, so the command refuses and names the ceremony. + - **The release.** The release must be published (not a draft) and carry a bundle; `v0.8.0` and older have none. The CLI verifies it with `@cloudhal/release-verify`: the keys reduced by both lists, yanked versions refused, and every file checked against its digest. + - **The attestation.** It checks the build-provenance attestation with `gh`. `--allow-single-factor` continues on the release key alone when `gh` is unavailable; a failed attestation is always refused. + - **The project.** Its theme files must equal the CLI's own starter, unless `--discard-local-theme` is given. Its `cloudhal.json` build keys must match the starter's, a key the CLI does not know is refused, and the installed wrangler must be at least the bundle's. + - **Refused projects.** Projects attached to another installation, multi-site projects and Workers Builds are refused. + - **Deploying.** The verified files are extracted into a fresh `.cloudhal/deploy/release//`. Both Workers are then deployed with `no_bundle` wrangler configs that upload exactly those bytes. + - **Offline and dry runs.** `--from ` installs offline from the assets and both lists, and `--release --dry-run` stops before wrangler. + + The CLI now depends on `@cloudhal/release-verify`. + + `@cloudhal/release-verify` now typechecks under every consumer's lib settings: WebCrypto inputs are `ArrayBuffer`-backed views, and the gzip pipe is typed through explicitly. `@cloudhal/astro-renderer` names the Site Worker's single-site choice `singleSiteId`, so a test holds that `CLOUDHAL_SITE_ID` overrides the built id. +- 5baacb4: `PINNED_ROOTS` now pins the offline root `cloudhal-root-2026a` (Ed25519, from the owner's root ceremony on 2026-11-15). `verifyKeys` verifies the published `keys.json` with it by default. The first `keys.json` lists the release key `cloudhal-release-2026a` and the yank key `cloudhal-yank-2026a`, and is committed as `security/keys.json`. A CLI built with this version can run `cloudhal deploy --release` once cloudhal.dev serves the lists. +- 61825b8: Signed key and yank lists for release bundles (RFC-0046 §9, #226). + + `@cloudhal/core-contracts` gains the `release-keys` root (`keys.json`, signed by an offline root) and the `release-yank-list` root (`yanked.json`, signed by a yank key and expiring 30 days after it is issued). + + `@cloudhal/release-verify` gains: + - `verifyKeys`, which checks a pinned root's signature and that the list is fresh (`expires` at most 13 months after `issuedAt`); + - `verifyYanked`, which checks a signature by an active yank key that `keys.json` lists, and refuses a stale list with `stale-yank-list`; + - `rememberYanks` and the `memory` option of `verifyKeys` and `verifyYanked`, for consumers that keep state: they refuse a rolled-back or pruned yank list, a replayed older `keys.json`, and a revoked or replaced yank key. A `keys.json` may list at most one active yank key; + - `mergeTrust`, which only reduces trust in the pinned keys: it revokes, marks retiring, and narrows a key's validity window, and it never adds a key. + + `verifyRelease` now enforces each key's validity window. A statement's `createdAt` must lie within its key's `[notBefore, notAfter]`. After `notAfter`, a key verifies only while a fresh `keys.json` lists it as retiring; otherwise the release is refused with `key-expired`. `verifyRelease` also refuses a yanked version (`yanked`). `PINNED_KEYS` now carries each key's window. +- 3ffdf29: New package `@cloudhal/release-verify` (RFC-0046 §11a). It is the one verifier of Cloudhal release bundles, and it is Worker-safe. + + `verifyRelease` runs these checks in order, and refuses on the first failure: + - the Ed25519 signature on `release-statement.json`, against the pinned release keys; + - that the statement is for the version and channel you asked for; + - both precompiled validators; + - every digest and §7 limit; + - the tarball, in two passes. + + The tarball is never held whole. The first pass checks its digest, and the second yields each entry only once it is verified. Unsafe entry paths (`..`, `.`, empty segments, backslashes, control characters, case-fold duplicates) are refused with `entry-path`. Every refusal carries a stable `code`. + + The package also exports: + - `missingScopes`, which applies §3's rule that `workers-scripts.admin` covers `workers-scripts.edit`; + - `releaseAssetUrls`; + - `PINNED_KEYS`, which can only be reduced. + + The Node-only subpath `@cloudhal/release-verify/attestation` checks the GitHub build attestation with `gh` 2.68.0 or newer. diff --git a/packages/release-verify/package.json b/packages/release-verify/package.json index 4449a626..e559dec1 100644 --- a/packages/release-verify/package.json +++ b/packages/release-verify/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/release-verify", - "version": "0.9.0", + "version": "0.10.0", "description": "Verifies a Cloudhal release bundle (RFC-0046 §2, §7, §11a): the Ed25519 release statement against pinned keys, the manifest, and every part of the tarball. Worker-safe; the attestation check is a Node-only subpath.", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/schedules/CHANGELOG.md b/packages/schedules/CHANGELOG.md index 149abaee..d42364d9 100644 --- a/packages/schedules/CHANGELOG.md +++ b/packages/schedules/CHANGELOG.md @@ -1,5 +1,14 @@ # @cloudhal/schedules +## 0.10.0 + +### Patch Changes + +- Updated dependencies [61825b8] +- Updated dependencies [74d7098] + - @cloudhal/core-contracts@0.10.0 + - @cloudhal/storage@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/schedules/package.json b/packages/schedules/package.json index 4a4c434e..62971487 100644 --- a/packages/schedules/package.json +++ b/packages/schedules/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/schedules", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal schedules (RFC-0008): the time model, the RRULE subset and its sentences, releases (pin, closure, rl1: hash, compose, conflicts, state machine), automation and run state, taint and budget accounting, the Scheduler and runDue, and the SQLite/D1 store. Worker-safe.", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/storage/CHANGELOG.md b/packages/storage/CHANGELOG.md index 0ddd211f..9294bd9b 100644 --- a/packages/storage/CHANGELOG.md +++ b/packages/storage/CHANGELOG.md @@ -1,5 +1,18 @@ # @cloudhal/storage +## 0.10.0 + +### Patch Changes + +- 74d7098: RFC-0045 rollout step 7b: **reference and repeater fields are now enabled.** Sites can define `reference` fields (entries of one to five collections of the same site, one or several, with optional conditions) and `repeater` fields (ordered lists of items with up to ten flat sub-fields) wherever the renderer serving them reads the two types. See [docs/guides/fields.md](https://github.com/cloudhal-dev/cloudhal/blob/main/docs/guides/fields.md). + + - **Where.** On Cloudflare, once the site Worker serving the site answers `GET /__cloudhal/features` with `fields: 2` (0.9.0 and later): the admin Worker asks the Worker each site is routed to (`SITE`, or an attached `SITE_n`), as it asks for time gates, and remembers a yes for that Worker only. Time gates are now confirmed per site Worker too, so a site on an older attached Worker no longer inherits the installation Worker's answer. Deploy the site Worker first; until it reports `fields: 2`, the types stay refused with `fields_unsupported` on every path. On Node (`cloudhal dev`, `studio`, self-host, Docker) and in the playground, always, since the renderer runs in the same process (`openLocalStore` passes `FIELDS_SUPPORTED`). + - **Every write path follows the capability:** Studio, MCP, the API, field operations and their dry runs, and every bundle: `cloudhal push` (the admin route passes the store's capability), `pull`, `cloudhal import` (dry runs included), `--replace` and `--revert`. A bundle that defines either type is still refused whole where the capability does not hold, and a site's new snapshot cannot point at another site's held site body to bring the types in. + - **MCP and Studio.** `update_collection` and `change_field_type` list both types, and `/api/instance` answers `features.referenceFields: true`, on servers that have the capability. The store still decides per site. + - **A one-time `entry_refs` check per site** (`rebuildEntryRefs`, new core-ts export): the admin Worker's new `refs.rebuild` system job (every five minutes, offset from `lists.backfill`, until every site is done; then two reads a run), and `openLocalStore` at start-up. Rows are written per entry, anchored on the hash each entry was read with, so a concurrent edit keeps its own rows; each chunk is anchored on the site node's hash, so no statement grows with the site's settings; it leaves a site alone while a text ↔ reference type change runs there; progress is in the new `entry_refs_state` table (storage migration `0034_entry_refs_state`), so a run stopped anywhere resumes. It is a safety net and should find nothing to change. +- Updated dependencies [61825b8] + - @cloudhal/core-contracts@0.10.0 + ## 0.9.0 ### Patch Changes diff --git a/packages/storage/package.json b/packages/storage/package.json index 434dfa0d..2b57b263 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/storage", - "version": "0.9.0", + "version": "0.10.0", "description": "Cloudhal storage interfaces (SQL driver, blob store) with Cloudflare D1/R2/Durable Object SQLite and local SQLite/filesystem adapters", "license": "Apache-2.0", "homepage": "https://cloudhal.dev",