Add #634 (stale schema metadata) to bug fixes section. Apply ruff formatting to schema.py, write_note.py, test files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: phernandez <paul@basicmachines.co>
14 KiB
v0.19.0 Release Notes
Overview
v0.19.0 is a major release that introduces semantic vector search, a schema validation system, project-prefixed permalinks, per-project cloud routing, and a significant upgrade to FastMCP 3.0. It includes 90+ commits since v0.18.0 spanning new features, architectural improvements, and stability fixes across both SQLite and Postgres backends.
Major Features
Semantic Vector Search
Full vector and hybrid search for SQLite (via sqlite-vec) and Postgres (via pgvector).
- Hybrid search mode combines full-text search (FTS) with vector similarity for best results
- Score-based fusion replaces RRF for hybrid ranking —
max(vec, fts) + 0.3 * min(vec, fts)preserves dominant signals and rewards dual-source agreement (#577) - Default search mode is now
hybridwhen semantic search is enabled,textwhen disabled - Embedding providers: FastEmbed (local, default) or OpenAI API
- Configurable similarity threshold via
semantic_min_similarity(default 0.55) - Per-query
min_similarityoverride onsearch_notestool - Auto-backfill: existing entities get embeddings generated on first startup
- Backend-specific distance-to-similarity conversion (cosine for SQLite, inner product for Postgres)
- FTS fallback: if semantic dependencies are missing, search gracefully degrades to text-only
- sqlite-vec knn
kparameter capped at 4096 to prevent backend errors
Configuration:
{
"semantic_search_enabled": true,
"semantic_embedding_provider": "fastembed",
"semantic_embedding_model": "bge-small-en-v1.5",
"semantic_min_similarity": 0.55
}
Usage:
search_notes("machine learning concepts", search_type="hybrid")
search_notes("similar to my notes on coffee", search_type="vector")
search_notes("exact phrase match", search_type="text")
search_notes("broad search", min_similarity=0.3) # lower threshold for more results
Schema System
Validate note structure against user-defined schemas with frontmatter-based rules.
- Define schemas as YAML in note frontmatter with field types, required fields, and constraints
- Frontmatter validation during sync — malformed notes get clear error messages
- Schema inference from existing notes to bootstrap schemas from your content
- Schema diff to compare two schemas and see changes
- Available via MCP tools and CLI
Project-Prefixed Permalinks
Permalinks now include the project name for unambiguous cross-project references.
- Memory URLs like
memory://project-name/folder/noteroute to the correct project - Existing non-prefixed permalinks continue to work (backwards compatible)
- Controlled by
permalinks_include_projectconfig (default: true) build_contextandsearch_notesauto-detect project from URL prefix
Per-Project Cloud Routing
Individual projects can be routed through the cloud while others stay local.
- Set a project to cloud mode:
bm project set-cloud research - Revert to local:
bm project set-local research - Uses API key authentication:
bm cloud set-key bmc_abc123... - MCP tools automatically route based on each project's mode
- Local MCP server (
bm mcp) still uses local routing for all projects by default --localand--cloudCLI flags override per-command
Workspace Selection
Cloud projects can target specific workspaces for multi-tenant environments.
workspaceparameter on MCP tools for explicit workspace targeting- CLI workspace-aware project listing with
bm project list - Spinner feedback while fetching cloud projects
New Tools and Capabilities
Dashboard (bm project info)
bm project info now displays an htop-inspired compact dashboard with:
- Horizontal bar charts for note types (top 5)
- Embedding coverage bar with Unicode block characters
- Colored status dots for at-a-glance health
EmbeddingStatusschema andget_embedding_status()service method for programmatic access
Unified Metadata Search
search_by_metadata has been merged into search_notes — one tool for all searches.
query is now optional, so you can search purely by frontmatter metadata.
search_notes(metadata_filters={"status": "in-progress"})
search_notes(metadata_filters={"tags": ["security", "oauth"]})
search_notes(metadata_filters={"priority": {"$in": ["high", "critical"]}})
search_notes(metadata_filters={"schema.confidence": {"$gt": 0.7}})
search_notes(tags=["security"]) # convenience shorthand
search_notes(status="draft") # convenience shorthand
JSON Output Mode
All MCP tools now support output_format="json" for machine-readable responses.
- Default remains
"text"for human-readable output (no breaking changes) build_contextdefaults to"json"with slimmed payloads (redundant fields stripped)- CLI tool commands support
--format jsonflag
tag: Search Shorthand
Search by tag using convenient shorthand syntax.
search_notes("tag:security")
search_notes("tag:coffee AND tag:brewing")
Entity User Tracking
Entities now track created_by and last_updated_by fields for attribution.
Improved Search Result Content (#609)
Search results now surface more relevant context:
matched_chunk_textpopulated for FTS-only hybrid results (no more fallback to truncated content)TOP_CHUNKS_PER_RESULTincreased from 3 to 5, catching answers deeper in large notes (~2700 → ~4500 chars)CONTENT_DISPLAY_LIMITdoubled from 2000 to 4000 chars for results without matched chunks
write_note Overwrite Guard (#632)
write_note is now non-idempotent by default. If a note already exists, the tool returns an
error instead of silently overwriting. Pass overwrite=True to replace, or use edit_note
for incremental updates. Config option write_note_overwrite_default restores the old upsert
behavior.
Architecture Changes
Score-Based Hybrid Fusion (#577)
RRF (Reciprocal Rank Fusion) compressed all fused scores to ~0.016, destroying ranking
differentiation. The new formula max(vec, fts) + FUSION_BONUS * min(vec, fts) preserves
dominant signals and rewards dual-source agreement. Zero-score results now produce zero
fused score instead of receiving a 0.1 weight floor.
FastMCP 3.0 Upgrade
Upgraded from FastMCP 2.12.3 to 3.0.1.
- Tool annotations (
readOnlyHint,openWorldHint) for better client integration - Improved MCP protocol compliance
- Better error handling and context management
Prompts Call MCP Tools Directly
MCP prompts (search, continue_conversation) now call MCP tools directly instead of
going through API endpoints. This fixes empty results in discovery mode and ensures prompts
use the same resolution logic as tools (including LinkResolver fallback).
build_context LinkResolver Fallback
build_context now falls back to LinkResolver when an exact permalink lookup returns empty.
This uses the same 7-strategy resolution pipeline as read_note, so callers no longer get
empty results for valid note identifiers that don't match exact permalinks.
Sync Handles Semantic Dependency Errors Gracefully
When sqlite-vec or another embedding provider is unavailable, sync_file now catches
SemanticDependenciesMissingError separately. The entity is created and FTS-indexed
successfully — only vector embeddings are skipped, with a clear warning:
WARNING: Semantic search dependencies missing — vector embeddings skipped for path=note.md.
Run 'bm reindex --embeddings' after resolving the dependency issue.
Unified Project Path
Cloud projects with bisync now store the local filesystem path in path (not the Docker
container path). Config migration automatically promotes local_sync_path → path for
existing configs.
CLI Improvements
Status and Doctor Default to Local Routing
bm status and bm doctor now default to local routing since they scan the local filesystem.
Previously, cloud-mode projects would route these commands to the cloud API, which returned
Docker-internal paths that don't exist locally.
--format json for CLI Tool Commands
All bm tool subcommands support --format json for machine-readable output, enabling
integration with scripts and plugins.
--json for Top-Level CLI Commands
Five additional CLI commands now support --json for machine-readable output:
bm status --json— sync report with new/modified/deleted/moved files and skipped filesbm project list --json— structured project list with name, paths, routing mode, and defaultsbm schema validate --json— validation report with per-note pass/fail, warnings, and errorsbm schema infer --json— field frequency analysis and suggested schema definitionbm schema diff --json— drift report with new fields, dropped fields, and cardinality changes
This complements the existing bm project info --json and bm tool --format json support,
making all major CLI commands scriptable for CI pipelines and automation.
Cloud Promo and Analytics
- Cloud promo panel shown on first run or version bump with OSS discount code
- Anonymous usage telemetry via Umami Cloud (promo/login funnel events only)
- Opt out with
BASIC_MEMORY_NO_PROMOS=1 - No PII, no file contents, no per-command tracking
- See Telemetry in README
Bug Fixes
- #577: RRF fusion compressed all hybrid scores to ~0.016, destroying ranking differentiation
- #582: build_context returns empty results on valid note identifiers
- #575: Remove hardcoded "main" default from default_project
- #595: recent_activity dedup and pagination across MCP tools
- #593: Backend-specific distance-to-similarity conversion
- #592: Strip NUL bytes from content before PostgreSQL search indexing
- #562: Use VIRTUAL instead of STORED columns in SQLite migration
- #558: Add X-Tigris-Consistent headers to all rclone commands
- #541: Handle EntityCreationError as conflict
- #536: Stabilize metadata filters on Postgres
- #533: Fix recent_activity prompt defaults
- #530: Prevent spurious
metadata: {}in frontmatter output - #601: Return matched chunk text in search results
- #606: Accept
nullforexpected_replacementsinedit_note - #579, #607: Guard against closed streams in promo panel and missing vector tables on shutdown
- #609: FTS-only hybrid results missing
matched_chunk_text; content limits too conservative - #631:
build_contextrelated_results schema validation failure — replaced fragile_slim_context()stripping with Pydanticexclude=Truefield config - #630: Skip workspace resolution when client factory is active — prevents 401 errors in cloud MCP server mode
- #30:
tag:prefix query fails with hybrid search — moved tag prefix parsing to MCP tool level so it works with all search modes - #31:
search_notesreturns cluttered observation/relation-level results — now defaults to entity-level results - #28:
schema_inferandschema_diffreturn raw Pydantic models as "undefined" in LLM output — added markdown formatters - Fix
schema_validateidentifier resolution (now uses LinkResolver) and text rendering (markdown formatter) - #634:
schema_validateandschema_diffuse stale database metadata instead of reading schema definitions from file — now reads frontmatter directly from the file with fallback to database metadata - Fix
Post(**metadata)crash when frontmatter containscontentorhandlerkeys - Fix list-valued frontmatter fields (
title,type) crashing on.strip()— now coerced to strings - Cap sqlite-vec knn
kparameter at 4096 to prevent backend errors - Parameterize SQL queries in search repository type filters
- Double-default display in project list
ensure_frontmatter_on_syncdefault changed toTrue- Status/doctor commands fail with cloud-mode projects (Docker path error)
- Prompts return "0 projects" in discovery mode
Security
- Upgrade
cryptographyfor CVE advisory - Upgrade
python-multipartfor security advisory
Internal / Developer
- #598: Upgrade FastMCP 2.12.3 → 3.0.1 with tool annotations
- #594: Add
tyas supplemental type checker - #538: Add fast feedback loop tooling (
just fast-check,just doctor,just testmon) - #600: Rename
entity_typetonote_typefor consistency - #596: Fix CLI runtime defects and audit regressions
- CLI refactoring and workspace-aware cloud project listing
- Split and speed up PR test matrix in CI
- Fix CI: collect coverage from test jobs instead of re-running all tests
- Create
search_vector_chunksin test fixtures for Postgres compatibility
Configuration Changes
| Setting | Old Default | New Default | Notes |
|---|---|---|---|
semantic_search_enabled |
false |
true |
Semantic search on by default |
ensure_frontmatter_on_sync |
false |
true |
Frontmatter added during sync |
permalinks_include_project |
false |
true |
Project prefix in permalinks |
Upgrade Notes
- Semantic search dependencies are now included by default. If sqlite-vec fails to load,
search gracefully falls back to FTS. Run
bm reindex --embeddingsto generate embeddings for existing content. - Hybrid search scoring has changed from RRF to score-based fusion. Search result ordering may differ — results should be more accurate with better score differentiation.
search_by_metadatais removed as a standalone tool. Usesearch_noteswithmetadata_filtersinstead (same parameters, same behavior).- Project-prefixed permalinks are enabled by default. Existing notes keep their current
permalinks until modified. Set
permalinks_include_project: falseto disable. - Frontmatter on sync is now enabled by default. Files without frontmatter will have it
added on next sync. Set
ensure_frontmatter_on_sync: falseto preserve old behavior. - Config migration runs automatically for cloud projects with bisync —
local_sync_pathis promoted topathso filesystem operations work correctly. write_noteis no longer idempotent — calls towrite_notefor existing notes now return an error unlessoverwrite=Trueis passed. Useedit_notefor incremental changes, or setwrite_note_overwrite_default: truein config to restore the old behavior.