Files
basicmachines-co-basic-memory/docs/post-v0.18.0-test-plan.md

16 KiB
Raw Permalink Blame History

Post-v0.18.0 Test Plan and Acceptance Criteria

Goal

Define a complete validation plan for all major features merged after v0.18.0, combining:

  • Coverage-gap-driven automated tests
  • Real MCP server integration tests (no mocks for target flows)
  • Manual MCP verification via LLM-driven tool calls

This plan is based on commits in v0.18.0..HEAD and the latest just check coverage output.

Scope Window

  • Start tag: v0.18.0 (2026-01-28)
  • End: current main
  • Change volume: 12 feature commits + 14 bug-fix commits (+ release chores/hotfixes)

Execution Strategy

  1. Stabilize all feature-level acceptance criteria in automated tests first.
  2. Add black-box MCP integration tests for semantic search + schema (real server startup).
  3. Run manual MCP tool-call verification to confirm real UX and routing behavior.
  4. Re-run full gate: just check + targeted integration packs.

Global Quality Gates

  • Feature criteria below must all pass.
  • No regressions in existing suites.
  • Coverage improves in targeted low-coverage feature modules.
  • SQLite and Postgres parity for search/semantic features.

Priority Coverage Gaps (from latest run)

These are the most important post-v0.18.0 feature modules currently under-covered:

  • src/basic_memory/mcp/tools/schema.py (27%)
  • src/basic_memory/mcp/clients/schema.py (36%)
  • src/basic_memory/mcp/tools/ui_sdk.py (43%)
  • src/basic_memory/mcp/tools/search.py (73%)
  • src/basic_memory/repository/postgres_search_repository.py (63%)
  • src/basic_memory/mcp/async_client.py (82%)
  • src/basic_memory/api/v2/routers/schema_router.py (80%)

Feature Acceptance Criteria and Test Plan

1) Schema System (c97733d) — DONE

Acceptance criteria

  • schema_validate, schema_infer, and schema_diff produce consistent outcomes across CLI/API/MCP for the same fixture set.
  • Strict validation fails deterministically on required-field/type violations.
  • Validation warnings are stable and machine-readable in non-strict mode.
  • Inference output is deterministic for unchanged input corpus.
  • Drift diff output is deterministic and identifies missing/extra/type-mismatch fields correctly.

Existing coverage anchor points

  • tests/schema/*
  • tests/api/v2/test_schema_router.py
  • test-int/test_schema/*

Gaps to close — DONE

  • MCP schema tool branches (src/basic_memory/mcp/tools/schema.py) — 18 tests in tests/mcp/test_tool_schema.py
  • MCP schema client behavior (src/basic_memory/mcp/clients/schema.py)tests/mcp/test_client_schema.py
  • Schema router error-path branches (src/basic_memory/api/v2/routers/schema_router.py)tests/api/v2/test_schema_router.py

Planned additions — DONE

  • Add MCP tool tests for schema_validate strict + non-strict result shapes. DONE
  • Add MCP tool tests for schema_infer with explicit entity_type and inferred type fallback. DONE
  • Add MCP tool tests for schema_diff empty-diff and non-empty-diff paths. DONE
  • Add API tests for schema router invalid payload/edge error handling. DONE
  • Add integration test that starts MCP server and calls schema tools end-to-end on fixture notes. — deferred to backlog item 4.

2) Semantic Search (0777879, 1428d18, 344e651) — DONE

Acceptance criteria

  • search_type=text|vector|hybrid returns expected ranked results on canonical semantic corpus.
  • Missing semantic dependencies fail fast with actionable install guidance.
  • Reindex and provider/model changes produce valid vectors without dimension mismatch.
  • SQLite and Postgres produce equivalent behavior for semantic modes on the same dataset.
  • Generated-column migration path is valid on SQLite environments in use.

Existing coverage anchor points

  • tests/repository/test_sqlite_vector_search_repository.py
  • tests/repository/test_postgres_search_repository.py
  • tests/services/test_semantic_search.py
  • tests/mcp/test_tool_search.py
  • test-int/test_search_performance_benchmark.py

Gaps to close — DONE

  • Uncovered Postgres vector/hybrid branches — 20 tests in tests/repository/test_postgres_search_repository_unit.py + 5 integration tests in test-int/semantic/test_semantic_coverage.py
  • MCP search semantic/output branches — expanded tests/mcp/test_tool_search.py

Planned additions — DONE

  • Expand Postgres repository tests for vector query composition edge cases. DONE
  • Expand Postgres repository tests for hybrid fusion ranking and pagination branches. DONE
  • Expand Postgres repository tests for embedding/provider error handling branches. DONE
  • Expand MCP search tool tests for vector/hybrid output formatting branches. DONE
  • Expand MCP search tool tests for semantic-disabled and missing-dependency failures. DONE
  • Add MCP integration tests that start server and execute semantic search_notes tool calls. — deferred to backlog item 4.

Semantic search quality benchmarks (NEW)

Full benchmark suite in test-int/semantic/ covering 5 backend×provider combinations:

  • sqlite-fts, sqlite-fastembed, postgres-fts, postgres-fastembed, postgres-openai
  • Quality metrics: hit@1, recall@5, MRR@10 with per-query timing
  • Realistic corpus with cross-topic vocabulary overlap (240 notes, 4 topics)
  • Rich CLI viewer: just semantic-report
  • JSON artifact output: just test-semantic-report

Key finding: FastEmbed (384-d local ONNX) matches or exceeds OpenAI (1536-d) quality at 30x lower latency. Recommending FastEmbed as default for both local and cloud deployments.

3) Per-Project Local/Cloud Routing + API Key Auth (d84708c, ed94877, 312662f) — DONE

Acceptance criteria

  • Project mode (local/cloud) persists and displays correctly.
  • Routing selects ASGI for local projects and HTTP+Bearer for cloud projects.
  • Cloud project without key fails with explicit remediation (cloud set-key/cloud create-key).
  • Resolution precedence is correct (factory > force-local > per-project cloud > global fallback > local).
  • Watch/sync only run for local projects.

Existing coverage anchor points

  • tests/mcp/test_async_client_modes.py
  • tests/cli/test_project_set_cloud_local.py
  • tests/mcp/test_project_context.py
  • tests/test_project_resolver.py
  • tests/sync/test_watch_service_reload.py

Gaps to close — DONE

  • Cloud routing branch gaps in src/basic_memory/mcp/async_client.py — expanded tests/mcp/test_async_client_modes.py

Planned additions — DONE

  • Add branch-focused tests for all unresolved routing branches in get_client(). DONE
  • Add MCP integration scenario with mixed local/cloud project config — deferred to backlog item 4.

Acceptance criteria

  • Project-prefixed permalinks are generated consistently on create/update/import flows.
  • Memory URLs resolve to the correct project/entity even with duplicate note titles.
  • read_note, search, build_context, write/edit/move flows preserve project identity correctly.
  • Link resolution remains correct for context-aware wikilinks.

Existing coverage anchor points

  • tests/utils/test_permalink_formatting.py
  • tests/mcp/test_tool_read_note.py
  • tests/mcp/test_tool_search.py
  • tests/services/test_context_service.py
  • test-int/mcp/test_read_note_integration.py

Gaps to close

  • No major coverage alarm in report, but keep as regression-critical due broad impact surface.

Planned additions — DONE

  • Add one integration test with colliding titles across two projects and assert URL routing invariants. DONEtest-int/mcp/test_permalink_collision_integration.py (2 tests: collision across projects + memory:// URL routing with project prefix)

5) MCP UI Variants + TUI Output (8bc03d1) — DONE

Acceptance criteria

  • UI resource variant selection (tool-ui, vanilla, mcp-ui) follows env configuration.
  • search_notes and read_note expose expected resource metadata for UI hosts.
  • ascii/ansi outputs are deterministic and stable for terminal clients.

Existing coverage anchor points

  • tests/mcp/test_tool_contracts.py
  • test-int/mcp/test_output_format_json_integration.py
  • test-int/mcp/test_ui_sdk_integration.py

Gaps to close — DONE

  • src/basic_memory/mcp/tools/ui_sdk.py branch coveragetests/mcp/test_ui_sdk.py
  • src/basic_memory/mcp/ui/sdk.py and src/basic_memory/mcp/ui/templates.py branch coveragetests/mcp/test_ui_templates.py + tests/mcp/test_ui_resources.py

Planned additions — DONE

  • Add unit tests for UI SDK metadata generation and template selection branches. DONE — 31 tests
  • Add integration assertion for variant-specific resource URIs and metadata payload shape. DONE

6) Watch Command (8df88e4) — DONE

Acceptance criteria

  • basic-memory watch starts and processes create/update/delete events.
  • Watch restart/reload path does not duplicate watchers.
  • Cloud-mode projects are excluded from active watcher set.

Existing coverage anchor points

  • tests/cli/test_watch.py
  • tests/sync/test_coordinator.py
  • tests/sync/test_watch_service_reload.py

Planned additions — DONE

  • Add one stress-style integration test for rapid file changes and watcher stability. DONEtests/sync/test_watch_service_stress.py (3 tests: 50-file batch, mixed add/modify/delete batch, rapid modifications to same file)

7) CLI JSON Output (a47c9c0) — DONE

Acceptance criteria

  • --format json returns valid JSON with stable keys for success paths.
  • Error paths also return JSON-shaped output with correct non-zero exits.
  • Default human output remains unchanged.

Existing coverage anchor points

  • tests/cli/test_cli_tool_json_output.py
  • test-int/cli/test_cli_tool_json_integration.py

Planned additions — DONE

  • Add one failure-path integration test per high-use tool command. DONEtest-int/cli/test_cli_tool_json_failure_integration.py (4 tests: read-note not found, write-note missing content, write→read roundtrip, recent-activity empty project)

8) Search/Edit and Metadata Fixes (530cbac, f1d50c2, 8838571, 009e849) — DONE

Acceptance criteria

  • Metadata filters produce consistent results on SQLite and Postgres.
  • tag: shorthand works alone and with mixed query terms.
  • Fast write/edit paths preserve external_id and metadata integrity.

Existing coverage anchor points

  • tests/repository/test_metadata_filters.py
  • tests/repository/test_search_repository.py
  • tests/services/test_search_service.py

Planned additions — DONE

  • Add Postgres-specific metadata filter edge-case tests to mirror SQLite assertions exactly. DONEtests/repository/test_metadata_filters_edge_cases.py (6 tests: missing field, AND logic, contains single-element array, nested path missing intermediate, $gte/$lte boundaries, $between inclusive — all pass on both SQLite and Postgres)

9) Compatibility and Hotfix Regression Pack (c46d7a6, a0e754b, 343a6e1, 24ca5f6, e3ced49, 8489a3d, b609c4e, f6e0a5b, 7624a20)

Acceptance criteria

  • Legacy endpoints required by older CLI versions function without 405 (GET /projects/projects, POST /projects/projects, POST /projects/config/sync).
  • Entity creation conflicts map to conflict status (not 500).
  • recent_activity prompt defaults are correct.
  • No spurious metadata: {} in serialized frontmatter.
  • Tigris/rclone uses global consistency headers for all transaction types.
  • bm --version fast path avoids heavy import path and remains responsive.
  • Default SQLite DB path is isolated by config dir.

Gaps to close

  • Commits with no direct tests added (c46d7a6, 344e651, f6e0a5b) need explicit regression tests. DONE

Planned additions — DONE

  • Add API compat test covering all legacy endpoint methods and payloads. DONEtest_legacy_v1_add_project_endpoint, test_legacy_v1_sync_config_endpoint
  • Add CLI fast-path test for --version import behavior/performance guard. DONEtest_bm_version_does_not_import_heavy_modules
  • Add empty metadata serialization regression test. DONEtest_schema_to_markdown_empty_metadata_no_metadata_key
  • Add migration safety test for SQLite generated columns (VIRTUAL expectation) — deferred, low risk.

MCP Manual Verification Plan (LLM Tool Calls)

Run after automated tests pass.

Setup

  • Start MCP server: basic-memory mcp --transport stdio
  • Use an MCP-capable client and issue tool calls directly.

Manual scenarios

  • Schema: call schema_validate, schema_infer, and schema_diff on known fixtures.
  • Schema: verify error and success payloads match acceptance criteria.
  • Semantic search: call search_notes with search_type=text|vector|hybrid.
  • Semantic search: verify ranking relevance on semantic fixture queries.
  • Routing: call tools with explicit project on mixed local/cloud setup.
  • Routing: verify success/failure paths with and without API key.
  • Permalink routing: read/write/search notes across projects with colliding titles.
  • Permalink routing: verify memory URL routing correctness.
  • UI/TUI: call search_notes and read_note with UI variants and output_format=text|json.
  • UI/TUI: verify payload/resource format and metadata completeness.

Implementation Backlog (Ordered)

  1. Fill schema MCP/client/router coverage gaps. DONE — 18 tests in test_tool_schema.py + test_client_schema.py
  2. Fill semantic search MCP + Postgres repository gaps. DONE — 20 tests in test_postgres_search_repository_unit.py + test_tool_search.py
  3. Add compatibility regression tests (legacy endpoints, migration, version fast path). DONE — 5 tests across 3 files (see below)
  4. Add feature-level integration tests (permalinks, watch, CLI JSON, metadata filters). DONE — 15 tests across 4 files (see items 4, 6, 7, 8 above)
  5. Expand UI SDK and template branch tests. DONE — 31 tests in test_ui_templates.py + test_ui_sdk.py + test_ui_resources.py
  6. Run full gate and capture results in a short release readiness summary. DONE — see results below

Full Gate Results (just check)

Phase Result
lint PASS
format PASS
typecheck PASS
Unit tests (SQLite) 1788 passed, 15 skipped
Integration tests (SQLite) 243 passed, 4 skipped, 10 deselected
Unit tests (Postgres) 1760 passed, 28 skipped
Integration tests (Postgres) 234 passed, 13 skipped, 10 deselected

0 failures. 10 deselected = semantic benchmark tests (run separately via just test-semantic).

Item 3 Details — Compatibility Regression Tests

Test File What it covers
test_legacy_v1_add_project_endpoint tests/api/v2/test_project_router.py POST /projects/projects legacy route reachable (idempotent path)
test_legacy_v1_sync_config_endpoint tests/api/v2/test_project_router.py POST /projects/config/sync legacy route reachable
test_bm_version_does_not_import_heavy_modules tests/cli/test_cli_exit.py bm --version fast path does not load basic_memory.mcp
test_schema_to_markdown_empty_metadata_no_metadata_key tests/markdown/test_entity_parser_error_handling.py schema_to_markdown() with entity_metadata={} emits no metadata: key
test_legacy_v1_list_projects_endpoint tests/api/v2/test_project_router.py (pre-existing) GET /projects/projects legacy route

Suite totals after item 3: 1764 passed, 15 skipped, 0 failures.

Suggested Commands

  • Full suite: just check
  • Fast loop: just fast-check
  • E2E consistency: just doctor
  • SQLite focused: just test-sqlite
  • Postgres focused: just test-postgres
  • Schema integration: pytest test-int/test_schema -q
  • Semantic + repo focus: pytest tests/repository/test_postgres_search_repository.py tests/mcp/test_tool_search.py tests/services/test_semantic_search.py -q
  • MCP integration focus: pytest test-int/mcp -q

Exit Criteria for This Plan

  • All feature acceptance criteria above are validated.
  • All identified high-priority coverage gaps are addressed or explicitly documented as intentional.
  • Manual MCP verification scenarios complete with no P0/P1 findings.