mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
306e562281
Signed-off-by: phernandez <paul@basicmachines.co>
16 KiB
16 KiB
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
- Stabilize all feature-level acceptance criteria in automated tests first.
- Add black-box MCP integration tests for semantic search + schema (real server startup).
- Run manual MCP tool-call verification to confirm real UX and routing behavior.
- 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, andschema_diffproduce 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.pytest-int/test_schema/*
Gaps to close — DONE
MCP schema tool branches (— 18 tests insrc/basic_memory/mcp/tools/schema.py)tests/mcp/test_tool_schema.pyMCP schema client behavior (—src/basic_memory/mcp/clients/schema.py)tests/mcp/test_client_schema.pySchema 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 forDONEschema_validatestrict + non-strict result shapes.Add MCP tool tests forDONEschema_inferwith explicitentity_typeand inferred type fallback.Add MCP tool tests forDONEschema_diffempty-diff and non-empty-diff paths.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|hybridreturns 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.pytests/repository/test_postgres_search_repository.pytests/services/test_semantic_search.pytests/mcp/test_tool_search.pytest-int/test_search_performance_benchmark.py
Gaps to close — DONE
Uncovered Postgres vector/hybrid branches— 20 tests intests/repository/test_postgres_search_repository_unit.py+ 5 integration tests intest-int/semantic/test_semantic_coverage.pyMCP search semantic/output branches— expandedtests/mcp/test_tool_search.py
Planned additions — DONE
Expand Postgres repository tests for vector query composition edge cases.DONEExpand Postgres repository tests for hybrid fusion ranking and pagination branches.DONEExpand Postgres repository tests for embedding/provider error handling branches.DONEExpand MCP search tool tests for vector/hybrid output formatting branches.DONEExpand MCP search tool tests for semantic-disabled and missing-dependency failures.DONE- Add MCP integration tests that start server and execute semantic
search_notestool 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.pytests/cli/test_project_set_cloud_local.pytests/mcp/test_project_context.pytests/test_project_resolver.pytests/sync/test_watch_service_reload.py
Gaps to close — DONE
Cloud routing branch gaps in— expandedsrc/basic_memory/mcp/async_client.pytests/mcp/test_async_client_modes.py
Planned additions — DONE
Add branch-focused tests for all unresolved routing branches inDONEget_client().- Add MCP integration scenario with mixed local/cloud project config — deferred to backlog item 4.
4) Project-Prefixed Permalinks + Memory URL Routing (545804f) — DONE
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.pytests/mcp/test_tool_read_note.pytests/mcp/test_tool_search.pytests/services/test_context_service.pytest-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.DONE —test-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_notesandread_noteexpose expected resource metadata for UI hosts.ascii/ansioutputs are deterministic and stable for terminal clients.
Existing coverage anchor points
tests/mcp/test_tool_contracts.pytest-int/mcp/test_output_format_json_integration.pytest-int/mcp/test_ui_sdk_integration.py
Gaps to close — DONE
—src/basic_memory/mcp/tools/ui_sdk.pybranch coveragetests/mcp/test_ui_sdk.py—src/basic_memory/mcp/ui/sdk.pyandsrc/basic_memory/mcp/ui/templates.pybranch 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 testsAdd integration assertion for variant-specific resource URIs and metadata payload shape.DONE
6) Watch Command (8df88e4) — DONE
Acceptance criteria
basic-memory watchstarts 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.pytests/sync/test_coordinator.pytests/sync/test_watch_service_reload.py
Planned additions — DONE
Add one stress-style integration test for rapid file changes and watcher stability.DONE —tests/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 jsonreturns 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.pytest-int/cli/test_cli_tool_json_integration.py
Planned additions — DONE
Add one failure-path integration test per high-use tool command.DONE —test-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_idand metadata integrity.
Existing coverage anchor points
tests/repository/test_metadata_filters.pytests/repository/test_search_repository.pytests/services/test_search_service.py
Planned additions — DONE
Add Postgres-specific metadata filter edge-case tests to mirror SQLite assertions exactly.DONE —tests/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_activityprompt defaults are correct.- No spurious
metadata: {}in serialized frontmatter. - Tigris/rclone uses global consistency headers for all transaction types.
bm --versionfast 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 (DONEc46d7a6,344e651,f6e0a5b) need explicit regression tests.
Planned additions — DONE
Add API compat test covering all legacy endpoint methods and payloads.DONE —test_legacy_v1_add_project_endpoint,test_legacy_v1_sync_config_endpointAdd CLI fast-path test forDONE —--versionimport behavior/performance guard.test_bm_version_does_not_import_heavy_modulesAdd empty metadata serialization regression test.DONE —test_schema_to_markdown_empty_metadata_no_metadata_key- Add migration safety test for SQLite generated columns (
VIRTUALexpectation) — 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, andschema_diffon known fixtures. - Schema: verify error and success payloads match acceptance criteria.
- Semantic search: call
search_noteswithsearch_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_notesandread_notewith UI variants andoutput_format=text|json. - UI/TUI: verify payload/resource format and metadata completeness.
Implementation Backlog (Ordered)
Fill schema MCP/client/router coverage gaps.DONE — 18 tests intest_tool_schema.py+test_client_schema.pyFill semantic search MCP + Postgres repository gaps.DONE — 20 tests intest_postgres_search_repository_unit.py+test_tool_search.pyAdd compatibility regression tests (legacy endpoints, migration, version fast path).DONE — 5 tests across 3 files (see below)Add feature-level integration tests (permalinks, watch, CLI JSON, metadata filters).DONE — 15 tests across 4 files (see items 4, 6, 7, 8 above)Expand UI SDK and template branch tests.DONE — 31 tests intest_ui_templates.py+test_ui_sdk.py+test_ui_resources.pyRun 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.