diff --git a/content/docs/(reference)/changelog.mdx b/content/docs/(reference)/changelog.mdx index ab73a136..ce99ca2d 100644 --- a/content/docs/(reference)/changelog.mdx +++ b/content/docs/(reference)/changelog.mdx @@ -7,6 +7,28 @@ Each release of Marfa ships the server and its container image, the CLI for macO **Marfa doesn't upgrade a database in place.** A build refuses a database whose schema differs from its own, or that holds retired tables or settings, and leaves the file unchanged; a version change alone doesn't cause a refusal. [Upgrade](/guides/upgrade) shows how to test an export and restore on fresh storage before switching builds. +## v0.0.33 + +Released October 24, 2026. [v0.0.33 on GitHub](https://github.com/withmarfa/marfa/releases/tag/v0.0.33) + +**Upgrade the server to repair folders that still hold `search`.** A folder made in v0.0.29 or earlier can keep that setting on the instance, where changing the local YAML alone cannot remove it. Read its version with `marfa items get `, then run `marfa folders change --version --file settings.json`, naming the intended `query` in the JSON file and leaving out `search`. The accepted change removes the stored `search`; it does not translate it. The server's database, the HTTP API and the working copy keep the shapes they had in v0.0.32, so an instance needs no export to upgrade. See [Change a folder's settings](/guides/sync-a-folder#change-a-folders-settings). + +For folders: + +- **An accepted settings change removes stored settings the folder type no longer declares.** Each setting you send replaces its value whole, and omitted declared settings stay, whether you use flags, `--file` or `--body`. The version rules still apply: changes to different settings can merge, and a collision is refused without removing anything. The old `search` key remains refused in a request, with no alias for `query`. See [Update a folder](/api-reference/folders/updateFolder). + +## v0.0.32 + +Released October 24, 2026. [v0.0.32 on GitHub](https://github.com/withmarfa/marfa/releases/tag/v0.0.32) + +**Upgrade the CLI or the core embedded in your app to keep using a copy whose cursor aged out.** The server's database, the HTTP API and the working copy keep the shapes they had in v0.0.31, so an instance needs no export to upgrade and a working copy keeps its queue. The CLI and the core's Node and Swift bindings add `stale` to hydration and read completeness, and the hydration report adds `in_place`; apps must handle the added state. + +For devices and apps: + +- **An aged-out copy keeps answering reads while it fills again.** After `catchup_too_old`, status reports `stale`, item lists and searches mark their answers `stale`, and reads by ID return held rows. Run `marfa device hydrate` with the same instance, reach and slice to refill in place. It updates rows as pages arrive and, only after the fill and replay finish, removes rows and edges it did not bring back, keeping pinned rows and those needed by waiting writes. An interrupted refill removes nothing and can resume. A changed instance, reach or slice, or a server restored behind the held cursor, requires a clearing fill. See [The working copy](/devices#the-working-copy). +- **Queue creates and edits while a copy fills.** A first fill or a stale copy takes new items, files and writes to rows it holds, keeping each write's base version when a later page brings a newer row. A drain sends them once the copy is whole. Writes to unheld rows and direct edge writes are refused with `hydration_incomplete`; body links wait until the server answers the body write. See [The working copy](/devices#the-working-copy). +- **Operations that need a whole copy still wait.** A folder pull, a view's items, search or groups, and edge reads refuse a partial or stale copy with `hydration_incomplete`. A stale copy's drain and catch-up return `copy_expired` with `catchup_too_old` until its refill finishes. A follow waits for a refill already under way, but refuses a stale copy whose refill has not started. See [Troubleshooting](/guides/troubleshooting#staying-in-step). + ## v0.0.31 Released October 24, 2026. [v0.0.31 on GitHub](https://github.com/withmarfa/marfa/releases/tag/v0.0.31) @@ -24,7 +46,7 @@ For devices and apps: Released October 24, 2026. [v0.0.30 on GitHub](https://github.com/withmarfa/marfa/releases/tag/v0.0.30) -**A folder's `search` setting is now `query`, and the old key is refused.** When you upgrade the CLI, change any `.marfa/folder.yaml` or script that says `search` to use `query`, and use the query option in place of the old search option. The API changes the folder setting's shape and adds view operations. The server's database keeps the schema it had in v0.0.29, so an instance needs no export to upgrade. The working copy changes shape: send its waiting writes with the earlier build before upgrading, then follow [Troubleshooting](/guides/troubleshooting#staying-in-step) if it is refused with `wrong_schema`. +**A folder's `search` setting is now `query`, and the old key is refused.** Change scripts that say `search` to use `query`, and use the query option in place of the old search option. A folder made before this release can still hold `search` on the instance: editing `.marfa/folder.yaml` alone cannot repair it, and v0.0.30's folder changes leave the old setting stored. Upgrade the server to v0.0.33 or later and follow [Change a folder's settings](/guides/sync-a-folder#change-a-folders-settings). The API changes the folder setting's shape and adds view operations. The server's database keeps the schema it had in v0.0.29, so an instance needs no export to upgrade. The working copy changes shape: send its waiting writes with the earlier build before upgrading, then follow [Troubleshooting](/guides/troubleshooting#staying-in-step) if it is refused with `wrong_schema`. For folders: diff --git a/content/docs/(reference)/cli.mdx b/content/docs/(reference)/cli.mdx index 731524b0..091e2393 100644 --- a/content/docs/(reference)/cli.mdx +++ b/content/docs/(reference)/cli.mdx @@ -224,6 +224,12 @@ That's how the owner makes the first key in the [Quickstart](/quickstart). These **The socket carries no key.** `--socket` can't be combined with `--url`, `--key`, `--profile`, `MARFA_API_URL`, `MARFA_API_KEY` or `MARFA_PROFILE`. An operation that needs a key, such as `marfa events` or `marfa export`, ends with exit code 5, so run it with a key instead. `marfa login`, `logout`, `device`, `docs`, `types scaffold` and local folder commands refuse `--socket`. `marfa folders inventory` is the exception: it reads the owner’s reported folder copies through the socket. +## Change a folder's settings + +`marfa folders change --version --file settings.json` changes the folder's settings on the instance without opening its local directory. Read the version with `marfa items get `. Use `--body` for inline JSON, or name settings with flags such as `--query`. + +**Each named setting replaces its value whole.** Omitted declared settings stay, and every accepted change removes stored settings the folder type does not declare. To repair a folder that holds `search`, use a server at v0.0.33 or later and supply the intended `query`, leaving out `search`; the server does not translate it. [Change a folder's settings](/guides/sync-a-folder#change-a-folders-settings) shows the file, version rules and read-back. + ## Read a view from a working copy The `marfa device views` commands read saved views from the database named by `--db`. **They need no server connection.** [Read a view offline](/guides/read-a-view) shows how to fill the copy and read a layout. diff --git a/content/docs/guides/sync-a-folder.mdx b/content/docs/guides/sync-a-folder.mdx index 0b6f2d12..81ce4d1c 100644 --- a/content/docs/guides/sync-a-folder.mdx +++ b/content/docs/guides/sync-a-folder.mdx @@ -177,7 +177,9 @@ query: - core.note ``` -Edit the file and the next sync sends your change to the instance through [Update a folder](/api-reference/folders/updateFolder), so **it reaches every computer that follows the folder**. `marfa folders change` changes the settings without the file. `folder` and `version` are Marfa's to write. [Folder](/catalog/folder) lists every other setting. +Edit the file and the next sync sends your change to the instance through [Update a folder](/api-reference/folders/updateFolder), so **it reaches every computer that follows the folder**. `folder` and `version` in this file are Marfa's to write. [Folder](/catalog/folder) lists every other setting. + +**Each setting you send replaces its value whole.** Omitted settings the folder type declares stay, and every accepted change removes stored settings the type does not declare. A change names the version it starts from: changes to different settings can merge, but a collision is refused without changing the folder ([folder change rules](https://github.com/withmarfa/marfa/blob/main/conformance/spec/items.md#itemsfolder-change-declared)). This edit leaves a `drafts` directory alone and tags every new note: @@ -189,6 +191,26 @@ defaults: - from-folder ``` +To change settings without opening the local folder, read the `system.folder` item with `marfa items get ` and note its `version`. Put the settings you want to change in a JSON file, then send it: + +```json title="settings.json" +{"query":{"types":["core.note"]}} +``` + +```bash tab="CLI" tab-group="client" +marfa folders change --version --file settings.json +``` + +```http tab="HTTP" +PATCH /folders/ +Authorization: Bearer +Content-Type: application/json + +{"version":1,"query":{"types":["core.note"]}} +``` + +Use the version you read in place of `` or `1`. The CLI also takes the JSON directly through `--body`. **To repair a folder that still stores `search`, use a server at v0.0.33 or later** and send the intended `query`, leaving out `search`. Copy every part of the old selection you want to keep: the server removes `search` but never translates it into `query`. Read the item again to check the accepted settings, then sync the folder. Editing `.marfa/folder.yaml` alone cannot remove a stored setting that prevents the folder from opening. + ## Replace a folder's key A new key with the same `--source` is refused `409 conflict` while the old key is live. [Revoke the old key](/guides/manage-keys#revoke-a-key), run the `keys create` command from the first step again, then run `marfa keys keep` so the folder reads the new key from the keychain. diff --git a/content/docs/guides/troubleshooting.mdx b/content/docs/guides/troubleshooting.mdx index d5a8881e..522b5ab1 100644 --- a/content/docs/guides/troubleshooting.mdx +++ b/content/docs/guides/troubleshooting.mdx @@ -226,6 +226,13 @@ Read the type's fields with `marfa types get `, or `GET /types/`, an ## Staying in step + + +The folder's `system.folder` item still holds `search`, which its type does not declare. **Repair the settings on the instance**, using a server at v0.0.33 or later. Read the item and its version with `marfa items get `, then run `marfa folders change --version --file settings.json` with the intended `query` and no `search` in the file. + +Each supplied setting replaces its value whole, omitted declared settings stay, and the accepted change removes stored undeclared settings. There is no translation from `search` to `query`. [Change a folder's settings](/guides/sync-a-folder#change-a-folders-settings) shows the file and how to check the result before syncing again; editing local YAML alone cannot repair the stored item. + + You asked to resume from a cursor older than anything the instance's event log still holds, so the stream can't fill the gap. The frame names the oldest event the log holds in `min_retained_id` and your cursor in `requested`, then the stream closes. diff --git a/openapi.json b/openapi.json index f720335a..9c8a3262 100644 --- a/openapi.json +++ b/openapi.json @@ -35417,7 +35417,7 @@ "Folders" ], "summary": "Update a folder", - "description": "Updates a folder's title and settings. Each one you send replaces the current value whole, and those you leave out stay as they are. Send the `version` you read.", + "description": "Updates a folder's title and settings at the version you read. Each setting you send replaces its value whole; omitted settings stay. Removes stored properties the folder type does not declare.", "security": [ { "bearerAuth": [] diff --git a/src/generated/cli-download.md b/src/generated/cli-download.md index 0c96f891..4b431ffa 100644 --- a/src/generated/cli-download.md +++ b/src/generated/cli-download.md @@ -1,5 +1,5 @@ ```bash -curl -fsSL https://github.com/withmarfa/marfa/releases/download/v0.0.31/marfa-0.0.31-darwin-arm64.tar.gz | tar -xz +curl -fsSL https://github.com/withmarfa/marfa/releases/download/v0.0.33/marfa-0.0.33-darwin-arm64.tar.gz | tar -xz sudo mkdir -p /usr/local/bin sudo mv marfa /usr/local/bin/ marfa --version diff --git a/src/generated/contract-index.json b/src/generated/contract-index.json index 67ac63b6..8a747213 100644 --- a/src/generated/contract-index.json +++ b/src/generated/contract-index.json @@ -3653,6 +3653,8 @@ "items/folder-read-hidden": "50d3b62613ca98eb", "items/folder-grant": "ab8bb45a9d2754c5", "items/folder-change": "b75b3f8b7335135b", + "items/folder-change-declared": "ce4f8aecf762c7b9", + "items/folder-change-omitted": "f87e58a2447ff30b", "items/folder-change-stale": "4c2a3879bb4b1044", "items/folder-change-conflict": "5e5d2055d36cd70d", "items/folder-change-refused": "34774846e66d5760", diff --git a/src/generated/marfa-release.json b/src/generated/marfa-release.json index a9fd3c64..7bdf227b 100644 --- a/src/generated/marfa-release.json +++ b/src/generated/marfa-release.json @@ -1 +1 @@ -{"version":"v0.0.31"} +{"version":"v0.0.33"} diff --git a/src/generated/server-image.md b/src/generated/server-image.md index 83416d42..68f37f85 100644 --- a/src/generated/server-image.md +++ b/src/generated/server-image.md @@ -1,5 +1,5 @@ ```bash -docker pull ghcr.io/withmarfa/marfa-server:0.0.31 +docker pull ghcr.io/withmarfa/marfa-server:0.0.33 docker run --name marfa -d --restart unless-stopped -p 127.0.0.1:8600:8600 \ - -v marfa-data:/data --env-file marfa.env ghcr.io/withmarfa/marfa-server:0.0.31 + -v marfa-data:/data --env-file marfa.env ghcr.io/withmarfa/marfa-server:0.0.33 ```