diff --git a/content/0.welcome.md b/content/0.welcome.md index 2bb7275..5863e70 100644 --- a/content/0.welcome.md +++ b/content/0.welcome.md @@ -11,7 +11,7 @@ seo: **Basic Memory** is real memory for your AI — a knowledge base you own. Built-in AI memory is small, vendor-owned, and usually invisible. Basic Memory is large, structured, and inspectable: a knowledge graph written in plain Markdown. Open it in any editor, hand it to any AI tool, and keep it forever. ::note{icon="i-lucide-megaphone"} -**New in v0.23:** the search release — reranking, Milvus, and a deadlock-free indexing core. See [What's New in v0.23](/whats-new/v0-23). Also new in Basic Memory Cloud: [Comments and Suggestions](/whats-new/comments-and-suggestions) and the [Interactive MCP App](/whats-new/interactive-mcp-app) for ChatGPT and Claude. +**New in v0.23:** the search release — reranking, Milvus, and a deadlock-free indexing core. The latest patch, v0.23.2, adds complete PostgreSQL full-text search and prevents case-duplicate folders. See [What's New in v0.23](/whats-new/v0-23). Also new in Basic Memory Cloud: [Comments and Suggestions](/whats-new/comments-and-suggestions) and the [Interactive MCP App](/whats-new/interactive-mcp-app) for ChatGPT and Claude. :: ## Pick your path diff --git a/content/02.whats-new/01.v0-23.md b/content/02.whats-new/01.v0-23.md index 3c591b0..4e3bb9a 100644 --- a/content/02.whats-new/01.v0-23.md +++ b/content/02.whats-new/01.v0-23.md @@ -87,4 +87,4 @@ Five database migrations run automatically on first start, including a one-time Before upgrading an integration or automation, read [Upgrade to v0.23](/whats-new/v0-23-upgrade) for the breaking changes, required actions, and known issues. :: -For the complete list of changes, see the [Changelog](/whats-new/changelog) and the [v0.23.0 release on GitHub](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.0). +For the complete list of changes, see the [Changelog](/whats-new/changelog) and the GitHub release notes for [v0.23.0](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.0), [v0.23.1](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.1), and [v0.23.2](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.2). diff --git a/content/02.whats-new/02.comments-and-suggestions.md b/content/02.whats-new/02.comments-and-suggestions.md index 2c07c25..62a7b8f 100644 --- a/content/02.whats-new/02.comments-and-suggestions.md +++ b/content/02.whats-new/02.comments-and-suggestions.md @@ -28,7 +28,9 @@ The note toolbar shows the number of unresolved comments and suggestions. Open i ## Review with an AI assistant -Comments and suggestions are stored with the Markdown using portable CriticMarkup. That means a connected assistant can review a note without immediately rewriting it, and the same open items remain available in the Cloud editor and the interactive MCP App. +Connected assistants now use the Cloud `review_note` MCP tool to add comments or insertion, deletion, and replacement suggestions without immediately rewriting the note. The same attributed threads appear in the Cloud editor and the interactive MCP App, where people and assistants can reply, resolve comments, and accept or reject suggestions. + +Cloud's `read_note`, `edit_note`, and `search_notes` tools are review-aware too: reads return clean prose and structured threads by default, ordinary edits preserve active review work and reject overlapping changes, and search hides CriticMarkup while reporting review-attention counts. Try asking: @@ -36,6 +38,8 @@ Try asking: Review this note with comments and suggestions. Keep the original prose in place so I can accept each change individually. ``` +The assistant reads the current note first, anchors each item to exact prose, and uses revision checksums before accepting or rejecting a proposal. It should use `review_note` rather than writing CriticMarkup directly. + ## Learn more :::card-group diff --git a/content/02.whats-new/05.changelog.md b/content/02.whats-new/05.changelog.md index fbb9711..d58bf8f 100644 --- a/content/02.whats-new/05.changelog.md +++ b/content/02.whats-new/05.changelog.md @@ -9,7 +9,7 @@ Notable changes in each Basic Memory release, most recent first. For complete pa ## v0.23 — Search that ranks and scales -*[v0.23.0](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.0)* +*[v0.23.0](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.0) · [v0.23.1](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.1) · [v0.23.2](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.23.2)* Semantic search takes a major step forward in v0.23. Opt-in cross-encoder reranking can rescore vector and hybrid candidates locally with FastEmbed or through LiteLLM, while Postgres deployments can move vector storage from pgvector to Milvus, Milvus Lite, or Zilliz Cloud. File-watcher writes now receive embeddings, non-BGE FastEmbed models are normalized correctly, SQLite full-text search covers complete long notes and relaxes non-Latin queries (CJK, Cyrillic, and other scripts), and reindex failures are reported honestly. @@ -21,6 +21,8 @@ The reliability tail is substantial too: incremental full-text reindexing clears Underneath those features, the indexing and persistence core moves to generation-versioned relations and observations, compare-and-swap materialization, consistent lock ordering, and batched resolution. Observations and relations now land with accepted writes, eliminating the deadlock and stale-projection failures that appeared under concurrent agent workloads. +**The v0.23.1 patch** brings PostgreSQL full-text search to parity with SQLite by indexing complete note bodies, scopes search reindexing to the selected project, adds `#bm:links_to` for forcing an ambiguous prose wikilink to use the generic relation type, and hardens `bm doctor` and in-place `bm update` runs. **v0.23.2** prevents `write_note` and `move_note` from creating case-duplicate folders when a requested path uniquely matches an existing folder case-insensitively. + This release also removes MCP tools and legacy API routes and changes several CLI, config, sync, edit, and pagination contracts. Read [What's New in v0.23](/whats-new/v0-23) for the highlights and [Upgrade to v0.23](/whats-new/v0-23-upgrade) before upgrading an integration or automation. --- @@ -31,7 +33,7 @@ This release also removes MCP tools and legacy API routes and changes several CL Two new Cloud collaboration surfaces make it easier to work with people and AI assistants without leaving your notes or conversation: -- **[Comments and Suggestions](/whats-new/comments-and-suggestions)** — add attributed comments or propose insertions, deletions, and replacements. Reviewers can reply, resolve comments, and accept or reject each suggestion individually. +- **[Comments and Suggestions](/whats-new/comments-and-suggestions)** — add attributed comments or propose insertions, deletions, and replacements. The Cloud `review_note` MCP tool gives connected assistants the same reply, resolve, accept, and reject workflow with checksum conflict protection. - **[Interactive MCP App](/whats-new/interactive-mcp-app)** — browse, search, graph, read, edit, and review Basic Memory inside ChatGPT and Claude on web or desktop. Set an active writing folder or add a specific note to the conversation as context. These are Basic Memory Cloud product updates. The versioned Core release notes continue under [All releases](#all-releases). diff --git a/content/02.whats-new/06.v0-23-upgrade.md b/content/02.whats-new/06.v0-23-upgrade.md index 5f775b1..ed03e1e 100644 --- a/content/02.whats-new/06.v0-23-upgrade.md +++ b/content/02.whats-new/06.v0-23-upgrade.md @@ -5,6 +5,10 @@ description: Breaking changes, migrations, and required actions when upgrading B v0.23 applies database migrations automatically, but integrations and operator scripts need review. Complete the actions below before relying on existing automation. +::note{icon="i-lucide-package-check"} +Install **v0.23.2 or later** rather than stopping on v0.23.0. The two patch releases fix PostgreSQL search coverage and reindex safety, `bm doctor` and `bm update` reliability, and case-duplicate folder creation. +:: + ## Rebuild vectors after changing indexes If you change `semantic_vector_index` between `pgvector` and `milvus`, rebuild the configured vector store: @@ -74,15 +78,16 @@ Several v0.23 fixes require no migration or configuration change but affect oper ## Let migrations finish -Five revisions run automatically on first start: +Six revisions run automatically when upgrading from v0.22.1 to the latest v0.23 patch: 1. A durable note-file vacate record distinguishes moves from byte-identical copies. 2. The semantic manifest gains vector-index identity and readiness state. 3. Relation-derived search refreshes become durable, retryable work items. 4. Relations and their search refreshes gain generation ownership. 5. A one-time repair removes duplicate observations and orphaned observation rows from full-text search. +6. On PostgreSQL, a child full-text index stores bounded, overlapping chunks of complete note bodies and backfills existing notes. SQLite needs no equivalent schema change because it already indexes full content. -The final repair is not reversible through a downgrade. Markdown files remain the source of truth and the index is rebuildable, but back up `memory.db` before the upgrade if you want a pre-migration database snapshot. +The observation repair is not reversible through a downgrade. Markdown files remain the source of truth and the index is rebuildable, but back up `memory.db` before the upgrade if you want a pre-migration database snapshot. Let the PostgreSQL migration and index build finish before testing deep full-text matches. ## Configure custom FastEmbed model prompts @@ -99,7 +104,17 @@ bm reindex --embeddings The trailing spaces are meaningful and preserved. Rebuild embeddings after changing the model, dimensions, or either prefix so stored document vectors and new query vectors use the same contract. The symmetric default model (`bge-small-en-v1.5`) needs no prefixes. -## Known issues in v0.23.0 +## Review the v0.23.1 and v0.23.2 fixes + +The patch releases do not add breaking API changes, but they correct several behaviors worth knowing about: + +- **PostgreSQL searches complete note bodies.** v0.23.1 backfills the new full-text chunks automatically. Boolean queries and punctuated terms work across the complete text, not only titles and capped content stems. +- **Reindexing is project-scoped.** Rebuilding search for one project no longer drops search rows belonging to sibling projects in the same database. The migration also repairs a missing shared search table if the old destructive path removed it. +- **Use `#bm:links_to` to disambiguate prose.** End a list item with the directive when a single word before a wikilink is prose rather than a relation type: `- Mother [[Alice]] #bm:links_to`. The directive remains readable in Markdown but is removed from indexed content. +- **`bm doctor` and `bm update` are safer.** Doctor waits for deferred materialization and can create its disposable project under `BASIC_MEMORY_PROJECT_ROOT`; update status output survives an in-place package replacement. +- **Folder casing resolves consistently.** In v0.23.2, `write_note(directory="schemas")` and note moves land in an existing unique `Schemas/` folder instead of creating a case-duplicate sibling. Resolution happens segment by segment for nested folders and behaves the same locally and in Cloud. + +## Known issues in v0.23 ### macOS file-identity edge cases @@ -110,6 +125,8 @@ Two open issues can produce duplicate entities for a single file on macOS: Workarounds: avoid case-only and normalization-only renames from MCP tools (rename through an intermediate name instead), and run `bm reindex --full -p ` to collapse duplicates if they appear. +The v0.23.2 folder-casing fix applies to the destination folders used by normal note writes and moves. It does not rename existing folders, merge existing case-variant siblings, or fix case-only and Unicode-normalization-only renames. + ## Continue setup - [Semantic Search](/concepts/semantic-search) — enable and tune reranking. diff --git a/content/03.cloud/04.ai-collaboration.md b/content/03.cloud/04.ai-collaboration.md index c7168b2..7a7da51 100644 --- a/content/03.cloud/04.ai-collaboration.md +++ b/content/03.cloud/04.ai-collaboration.md @@ -15,7 +15,7 @@ Click **Connect Agent** in the editor to start or resume an agent session for th Select text in the editor and it appears in the agent pane, where you can send a request about it — a rewrite, a summary, or a next step. The agent's changes stream into the note as it works. -If you want to review changes before applying them, ask the agent to leave **CriticMarkup comments and suggestions** instead of rewriting the passage. Basic Memory renders that feedback in the review rail, where you can reply to comments, resolve threads, and accept or reject each proposed edit. See [Comments and Suggestions](/cloud/comments-and-suggestions). +If you want to review changes before applying them, ask the agent to leave **comments and suggestions** instead of rewriting the passage. Cloud-connected assistants use the `review_note` MCP tool to create attributed threads; Basic Memory renders them in the review rail, where you can reply to comments, resolve threads, and accept or reject each proposed edit. See [Comments and Suggestions](/cloud/comments-and-suggestions). ## The agent pane diff --git a/content/03.cloud/14.comments-and-suggestions.md b/content/03.cloud/14.comments-and-suggestions.md index df1da91..4170c84 100644 --- a/content/03.cloud/14.comments-and-suggestions.md +++ b/content/03.cloud/14.comments-and-suggestions.md @@ -88,12 +88,37 @@ The review rail keeps every unresolved item beside its highlighted passage. Sugg ## Review with an AI assistant -Because review feedback is stored as Markdown, a connected assistant can comment on a note without directly rewriting it. Ask it to: +Cloud-connected assistants use the `review_note` MCP tool to create and manage the same attributed threads you see in the editor. Ask one to: ```text Review this note with comments and suggestions. Keep the original prose in place so I can accept each change individually. ``` +The supported workflow is: + +1. Call `read_note` with `review_mode="structured"` (the Cloud default) to get clean note prose, typed review items, and a `revision_checksum`. +2. Call `review_note(command="comment")` or `review_note(command="suggest")` with an exact, single-line prose anchor copied from that read. +3. Use the returned review IDs to `reply` or `resolve` a comment, or to `accept` or `reject` a suggestion. +4. Pass the latest checksum when accepting or rejecting. If the note changed, read it again instead of applying a decision to stale text. + +For example: + +```text +review_note( + identifier="Launch plan", + command="suggest", + anchor={"exact": "Ship the beta on Friday."}, + suggestion_kind="replacement", + replacement="Ship the beta after the security review." +) +``` + +Anchors can include exact `prefix` or `suffix` context, or a one-based `occurrence`, when the same sentence appears more than once. New threads are attributed to the detected MCP client. + +::warning +Do not ask an assistant to write CriticMarkup directly. Raw markup does not create the structured thread records used for attribution, replies, resolution, and accept/reject controls. Use `review_note`; reserve `read_note(review_mode="raw")` for inspecting exact persisted Markdown. +:: + The common CriticMarkup forms are: ```markdown @@ -103,7 +128,13 @@ The common CriticMarkup forms are: {~~original text~>replacement text~~} ``` -Basic Memory adds stable IDs and attributed review records when it creates a thread. Let the editor manage that metadata rather than changing it by hand. The metadata stays out of the editor body and is removed from public shared-note output. +Basic Memory adds stable IDs and attributed review records when it creates a thread. Let the editor and `review_note` manage that metadata rather than changing it by hand. The metadata stays out of the editor body and is removed from public shared-note output. + +### Edit prose while review work is open + +Cloud's normal `edit_note` tool preserves active review records. When a note contains review work, first read it in structured mode and pass that read's `revision_checksum` as `expected_checksum`. An edit that intersects reviewed prose is rejected with the blocking review ID; resolve the comment or accept/reject the suggestion before changing that passage. `write_note(overwrite=true)` remains an intentional full replacement and can remove review state. + +Search results also hide CriticMarkup storage bytes. JSON results include `review_summary` counts so an assistant can see that a matching note still needs review without loading every thread. --- diff --git a/content/03.cloud/15.mcp-app.md b/content/03.cloud/15.mcp-app.md index 83e0830..3fe2c09 100644 --- a/content/03.cloud/15.mcp-app.md +++ b/content/03.cloud/15.mcp-app.md @@ -111,6 +111,8 @@ Choose **Edit** from the note reader to open the rich editor. It includes headin The same editor supports shared review markup. You can add attributed comments, suggest insertions, deletions, or replacements, and open any unresolved thread. Suggestions remain inline with the note until someone **Accepts** or **Rejects** them; comments can be resolved or deleted without changing the note text. +Notes and search results show pending comment and suggestion counts, so review work is visible before you open the editor. Excerpts remain clean prose and never expose the underlying CriticMarkup storage. + ::theme-image{light="/screenshots/mcp-app/mcp-app-review-light.png" dark="/screenshots/mcp-app/mcp-app-review-dark.png" alt="A replacement suggestion with Accept and Reject actions in the MCP App editor"} :: @@ -133,6 +135,7 @@ The interactive app is for something you want to **see or operate**. Normal MCP | Read note content for an answer or summary | `read_note` | | Search for information the assistant will use | `search_notes` | | Get a directory listing as data | `list_directory` | +| Add, reply to, resolve, accept, or reject review work | `review_note` | For example, “What did we decide about authentication?” should use search and read tools. “Open my authentication notes so I can browse them” should use the interactive app. diff --git a/content/07.concepts/1.knowledge-format.md b/content/07.concepts/1.knowledge-format.md index 4952815..55be069 100644 --- a/content/07.concepts/1.knowledge-format.md +++ b/content/07.concepts/1.knowledge-format.md @@ -125,7 +125,9 @@ Relations can link to notes that don't exist yet. When those notes are created l Basic Memory tries exact identities first: permalink, title, and file path. At the project root, a filename-stem link such as `[[alpha_note]]` can resolve `alpha_note.md` even when the note's frontmatter title is different. -If no exact identity matches, Basic Memory can try a Unicode case-insensitive file-path alias that treats underscores and hyphens as equivalent. The fallback must identify exactly one note; `[[alpha-note]]` remains unresolved when multiple files collapse to the same alias. This forgiving lookup applies only to link resolution—writes and updates keep their exact identity rules and never use the alias to choose a file to overwrite or move. +If no exact identity matches, Basic Memory can try a Unicode case-insensitive file-path alias that treats underscores and hyphens as equivalent. The fallback must identify exactly one note; `[[alpha-note]]` remains unresolved when multiple files collapse to the same alias. This forgiving lookup applies only to link resolution—writes and updates keep their exact note identity rules and never use the alias to choose a file to overwrite or move. + +Directory casing is handled separately. Since v0.23.2, each destination-folder segment on a note write or move resolves to an existing folder when there is exactly one case-insensitive match, so `schemas/drafts` can land in `Schemas/Drafts`. Unknown folders are created with the requested spelling, existing case-variant siblings remain ambiguous, and the note's basename is never case-corrected by this folder rule. For relation-type conventions and how inline references index, see [Observations and Relations](/concepts/observations-and-relations). diff --git a/content/07.concepts/3.observations-and-relations.md b/content/07.concepts/3.observations-and-relations.md index b262979..47d9ac2 100644 --- a/content/07.concepts/3.observations-and-relations.md +++ b/content/07.concepts/3.observations-and-relations.md @@ -94,6 +94,16 @@ Relations are directional. `System Design - depends_on -> Caching Layer` creates **Quote multi-word relation types.** A relation type is a single token (`depends_on`, `relates_to`). If you want a multi-word type, **quote it** — `"depends on" [[Caching Layer]]`. Unquoted prose before a wikilink is no longer treated as a relation type: a bare or prose list item like `- [[Caching Layer]]` or `- see also [[Caching Layer]]` is indexed as a generic `links_to` connection. (Changed in [v0.21.0](https://github.com/basicmachines-co/basic-memory/releases/tag/v0.21.0).) :: +### Force a generic relation from single-word prose + +A single token before a wikilink normally looks like an explicit relation type. When that token is prose instead, end the list item with `#bm:links_to`: + +```markdown +- Mother [[Alice]] #bm:links_to +``` + +This creates the generic `links_to` relation instead of a `Mother` relation. The directive stays in the Markdown source so the intent is visible, but Basic Memory removes it from the indexed observation and relation text. This syntax was added in v0.23.1. + ### Inline references You can also link to other notes anywhere in a note's body text using `[[wiki links]]`: diff --git a/content/07.concepts/7.semantic-search.md b/content/07.concepts/7.semantic-search.md index 38f84b8..a7902a8 100644 --- a/content/07.concepts/7.semantic-search.md +++ b/content/07.concepts/7.semantic-search.md @@ -293,6 +293,8 @@ Results found by both keyword and meaning match rank highest. The dominant signa Question-form queries rarely match every keyword, so when the strict all-words text query comes back empty, hybrid search retries it as a relaxed any-word query rather than letting the text half go silent. As of v0.23 this relaxation works for queries in any script — CJK, Cyrillic, Greek, Arabic, and other non-Latin alphabets included. +SQLite and PostgreSQL both search complete note bodies. Since v0.23.1, PostgreSQL stores long bodies in bounded, overlapping full-text chunks, allowing deep matches and preserving Boolean query behavior across chunk boundaries. The upgrade migration backfills existing notes automatically. A later `bm reindex --search` replaces rows only for the selected project; it does not clear sibling projects that share the same database. + ### Deduplication Each chunk has a content hash. When notes are re-synced or reindexed, unchanged chunks skip re-indexing. Only modified content triggers new embeddings. Editing one note in a thousand-note knowledge base only re-indexes the chunks that changed. diff --git a/content/10.reference/2.mcp-tools-reference.md b/content/10.reference/2.mcp-tools-reference.md index 055c1fb..3a606e0 100644 --- a/content/10.reference/2.mcp-tools-reference.md +++ b/content/10.reference/2.mcp-tools-reference.md @@ -37,7 +37,7 @@ Create or update a markdown note. |---|---|---|---| | `title` | string | Yes | Note title | | `content` | string | Yes | Markdown body | -| `directory` | string | Yes | Relative folder path | +| `directory` | string | Yes | Relative folder path. Since v0.23.2, each segment resolves to a unique existing case-insensitive folder match | | `tags` | list[string] or string | No | Comma-separated string accepted | | `note_type` | string | No | Default `note`. Sets the `type` frontmatter field (e.g., `person`, `meeting`, `decision`) | | `metadata` | object or JSON string | No | Extra frontmatter fields merged into the note's YAML header | @@ -48,6 +48,8 @@ The `note_type` parameter controls the `type` field in frontmatter, which is use Aliases accepted for `directory`: `folder`, `dir`, and `path`. +Folder casing resolution uses known indexed directories, so local and Cloud writes behave identically. Exact matches win; a unique case-insensitive match reuses the existing spelling; no match creates the folder as requested; and existing case-variant siblings keep exact-match behavior. + ### `read_note` Read note content by title/permalink/memory URL. @@ -58,6 +60,9 @@ Read note content by title/permalink/memory URL. | `page` | integer | No | Pagination page number | | `page_size` | integer | No | Results per page | | `include_frontmatter` | boolean | No | Default `false`. When `true`, includes YAML frontmatter in output | +| `review_mode` | `structured` or `raw` | No | Cloud only; default `structured`. Returns clean prose and typed review threads, or exact persisted CriticMarkup in `raw` mode | + +On Cloud, structured JSON also returns `revision_checksum` and a `review` object containing summary counts and typed comment/suggestion items. Use that checksum for review decisions and for ordinary edits while review work is open. Raw mode is an inspection escape hatch; agents should not author or mutate CriticMarkup directly. ### `edit_note` @@ -74,11 +79,52 @@ Edit an existing note incrementally. | `replace_subsections` | boolean | No | For `replace_section`; default `true` replaces nested subsections. Set `false` to preserve them | | `metadata` | object | No | Merge frontmatter fields independently of the body operation; provided keys overwrite or add values | | `workspace` | string | No | Cloud workspace containing the note (name or tenant ID) | +| `expected_checksum` | string | No | Cloud reviewed notes require the checksum from structured `read_note`; stale or intersecting edits are rejected | `replace_section` now follows Markdown heading levels. By default, a selected section extends through the next heading of the same or higher level, so replacing an `##` section also replaces its nested `###` subsections. Set `replace_subsections=false` to stop at the next heading of any level and keep nested subsections. `metadata` preserves unrelated frontmatter and the note body. It ignores `title`, `type`, and `permalink`, which have dedicated handling, and does not support deleting keys. +On Cloud, `edit_note` preserves active review markers byte-for-byte. If an edit would change an anchored review range, it fails with the blocking review ID; use `review_note` to resolve or decide that item first. `write_note(overwrite=true)` is a full replacement and may remove review state. + +### `review_note` (Cloud) + +Manage comments and suggestions on an existing Markdown note. Always begin with `read_note(review_mode="structured", output_format="json")`, and do not write CriticMarkup directly. + +| Parameter | Type | Required | Notes | +|---|---|---|---| +| `identifier` | string | Yes | Exact title, permalink, file path, external ID, or `memory://` URL | +| `command` | `comment`, `suggest`, `reply`, `resolve`, `accept`, or `reject` | Yes | One review lifecycle action | +| `anchor` | object | Conditional | Required for `comment` and `suggest`. `exact` is a single-line prose selection; optional `prefix`, `suffix`, or one-based `occurrence` disambiguates repeated text | +| `body` | string | Conditional | Required for `comment` and `reply`; optional final reply when resolving a comment | +| `suggestion_kind` | `addition`, `deletion`, or `replacement` | Conditional | Required for `suggest` | +| `replacement` | string | Conditional | Required for addition and replacement suggestions; omit for deletion | +| `review_id` | string | Conditional | Required for `reply`, `resolve`, `accept`, and `reject`; obtain it from structured `read_note` or a prior mutation response | +| `expected_checksum` | string | Conditional | Required for `accept` and `reject`; optional stale-write guard for other commands | + +`comment` and `suggest` create attributed review records and return their IDs. `reply` works on comments or suggestions. `resolve` closes a comment without changing its anchored prose and can include a final reply. `accept` applies a pending suggestion; `reject` keeps the original prose. Every mutation is atomic and returns the new `revision_checksum`. + +```text +# Create a replacement suggestion +review_note( + identifier="Launch plan", + command="suggest", + anchor={"exact": "Ship the beta on Friday."}, + suggestion_kind="replacement", + replacement="Ship the beta after the security review." +) + +# After a fresh structured read, accept it +review_note( + identifier="Launch plan", + command="accept", + review_id="suggestion-id", + expected_checksum="checksum-from-read-note" +) +``` + +See [Comments and Suggestions](/cloud/comments-and-suggestions) for the complete human-and-agent workflow. + ### `move_note` Move a note or directory. @@ -86,10 +132,12 @@ Move a note or directory. | Parameter | Type | Required | Notes | |---|---|---|---| | `identifier` | string | Yes | Note or directory identifier | -| `destination_path` | string | Conditional | Target path. Mutually exclusive with `destination_folder` | -| `destination_folder` | string | Conditional | Target folder — moves note into folder preserving filename. Mutually exclusive with `destination_path` | +| `destination_path` | string | Conditional | Target path. Mutually exclusive with `destination_folder`; parent folders receive v0.23.2 casing resolution | +| `destination_folder` | string | Conditional | Target folder — moves note into folder preserving filename. Mutually exclusive with `destination_path`; each segment can reuse a unique case-insensitive folder match | | `is_directory` | boolean | No | Default `false`. Set to `true` to move an entire directory | +Folder casing resolution applies to note destinations, not directory renames. The response reports the actual landing path after a case-corrected move. Case-only folder renames and merging already duplicated case variants remain separate operations. + ### `delete_note` Delete a note or directory. @@ -173,6 +221,8 @@ The `search_type` parameter controls the search strategy. `hybrid` is the defaul Search results expose each note's stable `external_id` in JSON and Markdown output. Use it for web-app deep links or exact follow-up operations instead of parsing a title or permalink. +Cloud search projects reviewed notes as clean prose rather than CriticMarkup. JSON note results include `review_summary` counts (`open_comments`, `resolved_comments`, `pending_suggestions`, and `total_pending`). If a stale search fragment splits or exposes review markup during asynchronous index reconciliation, Cloud omits that hit instead of returning ambiguous storage bytes. + Use `categories` for observation categories such as `[decision]`, `[rule]`, or `[follow-up]`. `metadata_filters` only checks note frontmatter, so `metadata_filters={"category": "decision"}` matches a frontmatter field named `category`, not observation categories. The singular `category` is accepted as an alias, and comma-separated strings work (`categories="decision,rule"`). Matching is exact, and categories only exist on observations — explicitly passing `entity_types=["entity"]` alongside `categories` returns nothing. ::note diff --git a/content/10.reference/5.troubleshooting.md b/content/10.reference/5.troubleshooting.md index fcd9e58..1e142c1 100644 --- a/content/10.reference/5.troubleshooting.md +++ b/content/10.reference/5.troubleshooting.md @@ -138,13 +138,13 @@ bm cloud login **Problem:** The same file appears twice — duplicate search results, `-1`-suffixed permalinks, or `edit_note` failing on an affected note. Typically triggered by cross-platform sync tools that rewrite Unicode filename forms ([#1275](https://github.com/basicmachines-co/basic-memory/issues/1275)) or by case-only renames on case-insensitive APFS ([#1281](https://github.com/basicmachines-co/basic-memory/issues/1281)). -**Solution:** Collapse the duplicates with a full rebuild, and avoid case-only or normalization-only renames until the fixes land: +**Solution:** Collapse the duplicates with a full rebuild, and avoid case-only or normalization-only renames. These rename edge cases remain open in v0.23.2: ```bash basic-memory reindex --full -p ``` -See [Known issues in v0.23.0](/whats-new/v0-23-upgrade#known-issues-in-v0230) for details. +Ordinary `write_note` and note-move destinations are different: v0.23.2 reuses a uniquely matching existing folder regardless of case, preventing a new `schemas/` folder beside `Schemas/`. It does not repair existing duplicates or perform case-only folder renames. See [Known issues in v0.23](/whats-new/v0-23-upgrade#known-issues-in-v023) for details. ### Cloud Sync Issues