wavemind 2.3.0__tar.gz → 2.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. {wavemind-2.3.0 → wavemind-2.3.1}/PKG-INFO +29 -17
  2. {wavemind-2.3.0 → wavemind-2.3.1}/README.md +28 -16
  3. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/BENCHMARK_LEADERBOARD.md +1 -1
  4. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/BENCHMARK_REPORT.md +1 -1
  5. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/benchmark_matrix_results.json +12 -10
  6. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/benchmark_registry.py +4 -2
  7. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/scale_readiness_benchmark.py +46 -3
  8. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/scale_readiness_results.json +13 -11
  9. {wavemind-2.3.0 → wavemind-2.3.1}/docker-compose.yml +1 -1
  10. {wavemind-2.3.0 → wavemind-2.3.1}/docs/BENCHMARK_BRIEF.md +1 -1
  11. {wavemind-2.3.0 → wavemind-2.3.1}/docs/ROADMAP.md +8 -5
  12. {wavemind-2.3.0 → wavemind-2.3.1}/pyproject.toml +1 -1
  13. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_cli_smoke.py +5 -0
  14. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_jobs.py +36 -0
  15. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_object_store.py +55 -0
  16. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_scale_readiness_benchmark.py +2 -0
  17. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/__init__.py +3 -1
  18. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/cli.py +74 -1
  19. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/jobs.py +12 -1
  20. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/object_store.py +147 -0
  21. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind.egg-info/PKG-INFO +29 -17
  22. {wavemind-2.3.0 → wavemind-2.3.1}/CONTRIBUTING.md +0 -0
  23. {wavemind-2.3.0 → wavemind-2.3.1}/Dockerfile +0 -0
  24. {wavemind-2.3.0 → wavemind-2.3.1}/LICENSE +0 -0
  25. {wavemind-2.3.0 → wavemind-2.3.1}/MANIFEST.in +0 -0
  26. {wavemind-2.3.0 → wavemind-2.3.1}/SECURITY.md +0 -0
  27. {wavemind-2.3.0 → wavemind-2.3.1}/SUPPORT.md +0 -0
  28. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/agent_memory_benchmark.py +0 -0
  29. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/agent_memory_results.json +0 -0
  30. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/ann_index_curve_benchmark.py +0 -0
  31. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/ann_index_curve_results.json +0 -0
  32. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/dynamic_memory_benchmark.py +0 -0
  33. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/dynamic_memory_results.json +0 -0
  34. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/field_memory_dynamics_benchmark.py +0 -0
  35. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/field_memory_dynamics_results.json +0 -0
  36. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/locomo_evidence_results.json +0 -0
  37. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/locomo_memory_benchmark.py +0 -0
  38. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/locomo_sentence_evidence_results.json +0 -0
  39. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/long_memory_evidence_benchmark.py +0 -0
  40. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/long_memory_evidence_results.json +0 -0
  41. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/longmemeval_answer_benchmark.py +0 -0
  42. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/longmemeval_answer_extractive_20_results.json +0 -0
  43. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/longmemeval_answer_qwen25_0_5b_50_results.json +0 -0
  44. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/longmemeval_answer_qwen25_1_5b_50_results.json +0 -0
  45. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/longmemeval_evidence_50_results.json +0 -0
  46. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/longmemeval_evidence_results.json +0 -0
  47. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/longmemeval_memory_benchmark.py +0 -0
  48. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/memory_competitor_benchmark.py +0 -0
  49. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/memory_competitor_results.json +0 -0
  50. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/nomiracl_russian_benchmark.py +0 -0
  51. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/nomiracl_russian_results.json +0 -0
  52. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/open_retrieval_benchmark.py +0 -0
  53. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/open_retrieval_scifact_results.json +0 -0
  54. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/production_index_profile_results.json +0 -0
  55. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/production_load_benchmark.py +0 -0
  56. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/production_load_qdrant_100k_tuned_results.json +0 -0
  57. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/production_load_qdrant_1m_ef_sweep_results.json +0 -0
  58. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/production_load_qdrant_1m_results.json +0 -0
  59. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/production_load_qdrant_1m_tuned_results.json +0 -0
  60. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/production_load_results.json +0 -0
  61. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/render_benchmark_charts.py +0 -0
  62. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/render_benchmark_leaderboard.py +0 -0
  63. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/render_benchmark_report.py +0 -0
  64. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/ru_sentences_benchmark.py +0 -0
  65. {wavemind-2.3.0 → wavemind-2.3.1}/benchmarks/wavemind_capacity_results.json +0 -0
  66. {wavemind-2.3.0 → wavemind-2.3.1}/docs/CHROMA_MIGRATION.md +0 -0
  67. {wavemind-2.3.0 → wavemind-2.3.1}/docs/DEMO_SCRIPT.md +0 -0
  68. {wavemind-2.3.0 → wavemind-2.3.1}/docs/LAUNCH_KIT.md +0 -0
  69. {wavemind-2.3.0 → wavemind-2.3.1}/docs/OBSERVABILITY.md +0 -0
  70. {wavemind-2.3.0 → wavemind-2.3.1}/docs/PROJECT_BOARD.md +0 -0
  71. {wavemind-2.3.0 → wavemind-2.3.1}/docs/RELEASE.md +0 -0
  72. {wavemind-2.3.0 → wavemind-2.3.1}/docs/RU_LAUNCH_POSTS.md +0 -0
  73. {wavemind-2.3.0 → wavemind-2.3.1}/docs/USE_CASES.md +0 -0
  74. {wavemind-2.3.0 → wavemind-2.3.1}/docs/assets/benchmark-summary.svg +0 -0
  75. {wavemind-2.3.0 → wavemind-2.3.1}/docs/assets/wavemind-demo.gif +0 -0
  76. {wavemind-2.3.0 → wavemind-2.3.1}/docs/assets/wavemind-social-card.svg +0 -0
  77. {wavemind-2.3.0 → wavemind-2.3.1}/examples/agent_with_memory.py +0 -0
  78. {wavemind-2.3.0 → wavemind-2.3.1}/examples/chroma_migration.py +0 -0
  79. {wavemind-2.3.0 → wavemind-2.3.1}/examples/customer_support_memory.py +0 -0
  80. {wavemind-2.3.0 → wavemind-2.3.1}/examples/demo.py +0 -0
  81. {wavemind-2.3.0 → wavemind-2.3.1}/examples/dynamic_memory_demo.py +0 -0
  82. {wavemind-2.3.0 → wavemind-2.3.1}/examples/framework_integrations.py +0 -0
  83. {wavemind-2.3.0 → wavemind-2.3.1}/examples/langchain_memory.py +0 -0
  84. {wavemind-2.3.0 → wavemind-2.3.1}/examples/llamaindex_retriever.py +0 -0
  85. {wavemind-2.3.0 → wavemind-2.3.1}/examples/observability/README.md +0 -0
  86. {wavemind-2.3.0 → wavemind-2.3.1}/examples/observability/docker-compose.yml +0 -0
  87. {wavemind-2.3.0 → wavemind-2.3.1}/examples/observability/otel-collector.yaml +0 -0
  88. {wavemind-2.3.0 → wavemind-2.3.1}/examples/observability/prometheus-alerts.yml +0 -0
  89. {wavemind-2.3.0 → wavemind-2.3.1}/examples/observability/prometheus.yml +0 -0
  90. {wavemind-2.3.0 → wavemind-2.3.1}/examples/production-index-profile/README.md +0 -0
  91. {wavemind-2.3.0 → wavemind-2.3.1}/examples/production-index-profile/docker-compose.yml +0 -0
  92. {wavemind-2.3.0 → wavemind-2.3.1}/examples/research_notebook_memory.py +0 -0
  93. {wavemind-2.3.0 → wavemind-2.3.1}/examples/sharded_memory.py +0 -0
  94. {wavemind-2.3.0 → wavemind-2.3.1}/install.bat +0 -0
  95. {wavemind-2.3.0 → wavemind-2.3.1}/install.sh +0 -0
  96. {wavemind-2.3.0 → wavemind-2.3.1}/requirements-optional.txt +0 -0
  97. {wavemind-2.3.0 → wavemind-2.3.1}/requirements.txt +0 -0
  98. {wavemind-2.3.0 → wavemind-2.3.1}/setup.cfg +0 -0
  99. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_agent_memory_benchmark.py +0 -0
  100. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_ann_index_curve_benchmark.py +0 -0
  101. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_api.py +0 -0
  102. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_api_process_persistence.py +0 -0
  103. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_benchmark_brief.py +0 -0
  104. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_benchmark_charts.py +0 -0
  105. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_benchmark_leaderboard.py +0 -0
  106. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_benchmark_registry.py +0 -0
  107. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_benchmark_report.py +0 -0
  108. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_chroma_migration_example.py +0 -0
  109. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_cluster.py +0 -0
  110. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_core_persistence.py +0 -0
  111. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_dynamic_memory_benchmark.py +0 -0
  112. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_examples.py +0 -0
  113. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_field_graph.py +0 -0
  114. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_field_graph_integration.py +0 -0
  115. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_field_memory_dynamics_benchmark.py +0 -0
  116. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_framework_adapters.py +0 -0
  117. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_import_benchmark.py +0 -0
  118. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_indexes_encoders.py +0 -0
  119. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_langchain_integration.py +0 -0
  120. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_locomo_memory_benchmark.py +0 -0
  121. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_long_memory_evidence_benchmark.py +0 -0
  122. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_longmemeval_answer_benchmark.py +0 -0
  123. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_longmemeval_memory_benchmark.py +0 -0
  124. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_memory_competitor_benchmark.py +0 -0
  125. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_multimodal.py +0 -0
  126. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_nomiracl_russian_benchmark.py +0 -0
  127. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_observability.py +0 -0
  128. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_observability_docs.py +0 -0
  129. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_open_retrieval_benchmark.py +0 -0
  130. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_packaging_files.py +0 -0
  131. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_postgres_storage.py +0 -0
  132. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_production_index_profile.py +0 -0
  133. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_production_load_benchmark.py +0 -0
  134. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_replication.py +0 -0
  135. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_scale_plan.py +0 -0
  136. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_semantic_and_latency.py +0 -0
  137. {wavemind-2.3.0 → wavemind-2.3.1}/tests/test_sharding.py +0 -0
  138. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/__main__.py +0 -0
  139. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/api.py +0 -0
  140. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/benchmark.py +0 -0
  141. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/cluster.py +0 -0
  142. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/core.py +0 -0
  143. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/encoders.py +0 -0
  144. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/field_graph.py +0 -0
  145. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/importers.py +0 -0
  146. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/indexes.py +0 -0
  147. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/integrations/__init__.py +0 -0
  148. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/integrations/autogen.py +0 -0
  149. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/integrations/crewai.py +0 -0
  150. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/integrations/langchain.py +0 -0
  151. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/integrations/langgraph.py +0 -0
  152. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/integrations/llamaindex.py +0 -0
  153. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/multimodal.py +0 -0
  154. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/observability.py +0 -0
  155. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/replication.py +0 -0
  156. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/scale.py +0 -0
  157. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/sharding.py +0 -0
  158. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/storage.py +0 -0
  159. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind/studio.py +0 -0
  160. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind.egg-info/SOURCES.txt +0 -0
  161. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind.egg-info/dependency_links.txt +0 -0
  162. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind.egg-info/entry_points.txt +0 -0
  163. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind.egg-info/requires.txt +0 -0
  164. {wavemind-2.3.0 → wavemind-2.3.1}/wavemind.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wavemind
3
- Version: 2.3.0
3
+ Version: 2.3.1
4
4
  Summary: Local-first dynamic memory field with vector search and wave-field re-ranking
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/CaspianG/wavemind
@@ -546,14 +546,15 @@ Checked-in result:
546
546
  |---|---:|
547
547
  | Cluster planner | 4096 namespaces, 4 nodes, replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, write quorum `2`. |
548
548
  | Hot cache | 2000 lookups, hit rate `0.920`, p99 lookup `0.003 ms`. |
549
- | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, tombstone repair deleted `1` stale record, p99 query-after-loss `1.31 ms`. |
550
- | Active-active delta sync | 2 regions, bidirectional convergence `true`, stale import suppressed after delete `true`, tombstone convergence `true`, sync `159.69 ms`. |
551
- | Replicated snapshot job | 3 replica files, manifest checksum validation `true`, offsite mirror validation `true`, portable archive validation `true`, S3-compatible upload validation `true`, archive restore `24.85 ms`. |
552
- | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.62 ms`. |
549
+ | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, tombstone repair deleted `1` stale record, p99 query-after-loss `1.47 ms`. |
550
+ | Active-active delta sync | 2 regions, bidirectional convergence `true`, stale import suppressed after delete `true`, tombstone convergence `true`, sync `135.90 ms`. |
551
+ | Replicated snapshot job | 3 replica files, manifest checksum validation `true`, offsite mirror validation `true`, portable archive validation `true`, S3-compatible upload validation `true`, latest remote archive metadata validation `true`, object-store retention pruned `2`, archive restore `32.92 ms`. |
552
+ | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.77 ms`. |
553
553
 
554
554
  This profile validates routing, quorum-replicated runtime behavior, cache
555
555
  behavior, active-active namespace delta sync, replicated snapshot/restore, and
556
- structured payload handling, including verified offsite and archive restore.
556
+ structured payload handling, including verified offsite, archive, object-store
557
+ latest lookup, object-store retention, and archive restore.
557
558
  It is not a 10M-vector load test. Real 100k, 1M, and 10M latency claims should
558
559
  come from service-backed FAISS/Qdrant/pgvector load tests on production-like
559
560
  hardware.
@@ -583,16 +584,16 @@ Maintenance workers:
583
584
 
584
585
  ```sh
585
586
  wavemind maintenance --namespace user:42 --consolidate-steps 10 --consolidate-concepts --json
586
- wavemind replicated-snapshot --root ./state/replicas --node node-a --node node-b --node node-c --out ./backups/replicated --offsite ./offsite/replicated --archive ./archives/replicated --s3 s3://my-bucket/wavemind/prod --keep-last 7 --json
587
+ wavemind replicated-snapshot --root ./state/replicas --node node-a --node node-b --node node-c --out ./backups/replicated --offsite ./offsite/replicated --archive ./archives/replicated --s3 s3://my-bucket/wavemind/prod --keep-last 7 --s3-keep-last 30 --json
587
588
  ```
588
589
 
589
590
  The first command runs one deterministic memory pass: expired-memory purge,
590
591
  optional field/concept consolidation, and index-health repair. The second
591
592
  command creates a verified replicated snapshot, mirrors it to an offsite path,
592
593
  writes a portable `.tar.gz` archive, verifies that archive, can upload it to an
593
- S3-compatible object store, and applies retention. Production deployments can
594
- call these commands from cron, systemd, Kubernetes CronJobs, Celery, RQ, or
595
- Temporal.
594
+ S3-compatible object store, verify newest-archive metadata, and apply local and
595
+ object-store retention. Production deployments can call these commands from
596
+ cron, systemd, Kubernetes CronJobs, Celery, RQ, or Temporal.
596
597
 
597
598
  Hot-cache options:
598
599
 
@@ -698,6 +699,7 @@ snapshot_job = ReplicatedSnapshotWorker(memory).run_once(
698
699
  archive_destination="./archives/replicated",
699
700
  object_store_destination="s3://my-bucket/wavemind/prod",
700
701
  keep_last=7,
702
+ object_store_keep_last=30,
701
703
  )
702
704
  assert snapshot_job.ok
703
705
 
@@ -713,7 +715,9 @@ The replicated snapshot job writes one SQLite backup per replica plus
713
715
  node definitions. It can mirror the snapshot to a second path for offsite
714
716
  backup, write a portable `.tar.gz` archive for object-store/offsite systems,
715
717
  verify that archive, upload it to any S3-compatible object store through
716
- `boto3`, and apply `keep_last` retention locally, offsite, and for archives.
718
+ `boto3`, list the newest remote archive, restore from the newest remote archive,
719
+ and apply `keep_last` retention locally, offsite, for archives, and explicitly
720
+ for object-store archives through `object_store_keep_last`.
717
721
  Restore refuses to overwrite a non-empty root unless `overwrite=True` is passed.
718
722
 
719
723
  Equivalent CLI:
@@ -727,6 +731,12 @@ wavemind replicated-snapshot \
727
731
  --archive ./archives/replicated \
728
732
  --s3 s3://my-bucket/wavemind/prod \
729
733
  --keep-last 7 \
734
+ --s3-keep-last 30 \
735
+ --json
736
+
737
+ wavemind replicated-s3-archives \
738
+ --s3 s3://my-bucket/wavemind/prod \
739
+ --latest \
730
740
  --json
731
741
 
732
742
  wavemind replicated-restore \
@@ -736,7 +746,8 @@ wavemind replicated-restore \
736
746
  --json
737
747
 
738
748
  wavemind replicated-restore \
739
- --from s3://my-bucket/wavemind/prod/wavemind-replicated-20260705-120000.tar.gz \
749
+ --from s3://my-bucket/wavemind/prod \
750
+ --latest \
740
751
  --to ./state/restored-replicas \
741
752
  --overwrite \
742
753
  --json
@@ -1119,7 +1130,7 @@ Current read:
1119
1130
  | LongMemEval 50-query smoke | On the first 50 non-abstention LongMemEval-S questions, WaveMind reaches `evidence_recall@5 0.920`, `precision@1 0.760`, and `MRR@5 0.827`; Chroma/Qdrant static reach `0.600`, `0.260`, and `0.385`. | This is the fast regression profile for checking current changes before rerunning the full LongMemEval profile. WaveMind wins on quality; latency still needs work. |
1120
1131
  | ANN/index curve | At 50000 generated 128-d vectors, NumPy exact keeps `recall@10 1.000` at `6.49 ms`; quantized int8 keeps `0.934` at `24.92 ms`; Annoy is faster at `4.92 ms` but drops to `0.730` recall; Qdrant local keeps `1.000` recall at `43.49 ms`. | Current local scale boundary is clear: quantized search needs kernel work, Annoy needs tuning/FAISS, and Qdrant should be tested in service mode for a fair production comparison. |
1121
1132
  | Production load | At 100000 generated 128-d vectors, service-mode Qdrant reaches `recall@10 1.000`, avg `10.28 ms`, p99 `21.26 ms`. At 1M, tuned Qdrant reaches `recall@10 0.984`, avg `116.80 ms`, p99 `209.28 ms`; an EF sweep finds `recall@10 0.977`, avg `64.76 ms`, p99 `103.77 ms` at `hnsw_ef=2048` on 30 queries. | 100k is production-grade on the tested machine. 1M recall is now strong, but p99 still needs tuning before claiming a stable sub-100 ms SLO. |
1122
- | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, missing-record repair, tombstone repair, active-active delta sync, checksummed replicated snapshot/restore, offsite mirror verification, portable archive verification, S3-compatible upload verification, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, replicated-runtime, namespace-delta, offsite/archive/object-store backup, and restore-drill foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
1133
+ | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, missing-record repair, tombstone repair, active-active delta sync, checksummed replicated snapshot/restore, offsite mirror verification, portable archive verification, S3-compatible upload/latest-metadata/retention verification, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, replicated-runtime, namespace-delta, offsite/archive/object-store backup lifecycle, and restore-drill foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
1123
1134
  | Memory competitor adapters | WaveMind reaches `precision@1 0.80`, `precision@3 1.00`, stale suppression `1.00` on the small adapter profile. Mem0, Zep, and LangGraph are listed as skipped unless their real packages/services are configured. | This prevents fake competitor claims. The adapter harness is ready; real Mem0/Zep/LangGraph results still need configured installs. |
1124
1135
  | LongMemEval local answer generation | With the same local Ollama `qwen2.5:1.5b`, WaveMind reaches `exact_match 0.240`, `contains_answer 0.380`, `token_f1 0.333`, and `evidence_recall@5 0.920`; Chroma and Qdrant static both reach `0.120`, `0.160`, `0.170`, and `0.600`. | This is the first checked-in end-to-end answer benchmark against Chroma/Qdrant. It is still a 50-question lightweight smoke run, not a full LongMemEval leaderboard score. |
1125
1136
 
@@ -1138,7 +1149,7 @@ Current read:
1138
1149
  | Production index profile | Docker-backed 50000-vector profile for persisted FAISS, Qdrant service, and PostgreSQL/pgvector HNSW. | implemented | FAISS / Qdrant service / pgvector | Keep service-mode candidate generation above `0.95` recall@10 and below 10 ms average query latency at 50000 vectors. |
1139
1150
  | Production load profile | 100k and 1M service-backed candidate-index checks with p95/p99 latency. | implemented | Qdrant service / pgvector HNSW / FAISS persisted | Keep 100k at recall@10 `1.000`; push 1M p99 below 100 ms with recall@10 >= 0.95. |
1140
1151
  | Qdrant 1M HNSW ef sweep | One 1M Qdrant collection queried with multiple `hnsw_ef` values. | implemented | Qdrant service | Repeat with 100+ queries and collection-level HNSW build parameters before claiming a stable 1M SLO. |
1141
- | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, active-active delta sync, replicated snapshot/restore with offsite, archive, and object-store verification, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication, namespace-delta sync, repair, offsite/archive/object-store backup, and restore drills green while adding larger service-backed 10M load tests. |
1152
+ | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, active-active delta sync, replicated snapshot/restore with offsite, archive, object-store latest-metadata/retention verification, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication, namespace-delta sync, repair, offsite/archive/object-store backup lifecycle, and restore drills green while adding larger service-backed 10M load tests. |
1142
1153
  | Memory competitor adapter profile | Dynamic-memory scenario wired for external memory frameworks. | implemented | Mem0 / Zep / LangGraph persistent memory | Report real competitor results only when their packages/services are explicitly configured. |
1143
1154
  | [BEIR](https://github.com/beir-cellar/beir) | Standard zero-shot information retrieval quality. | planned | Chroma / Qdrant / FAISS | Stay within 0.02 `nDCG@10` on identical embeddings. |
1144
1155
  | [MTEB Retrieval](https://github.com/embeddings-benchmark/mteb) | Separates encoder quality from retrieval-store quality. | planned | Chroma / Qdrant / FAISS | Prove WaveMind does not reduce same-embedding retrieval quality. |
@@ -1725,10 +1736,11 @@ Near-term priorities:
1725
1736
  - Faster dynamic re-ranking through smaller candidate windows, caching, and
1726
1737
  background updates.
1727
1738
  - Better production operations: OpenTelemetry and replicated offsite snapshot
1728
- jobs with verified portable archives and S3-compatible upload are
1739
+ jobs with verified portable archives, S3-compatible upload, latest-archive
1740
+ lookup, restore from latest, and object-store retention are
1729
1741
  implemented; richer latency histograms, index-health metrics, alerting
1730
- examples, object-store retention/download drills, and Postgres PITR runbooks
1731
- are next.
1742
+ examples, real cloud disaster-recovery drills, and Postgres PITR runbooks are
1743
+ next.
1732
1744
 
1733
1745
  Longer-term direction:
1734
1746
 
@@ -490,14 +490,15 @@ Checked-in result:
490
490
  |---|---:|
491
491
  | Cluster planner | 4096 namespaces, 4 nodes, replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, write quorum `2`. |
492
492
  | Hot cache | 2000 lookups, hit rate `0.920`, p99 lookup `0.003 ms`. |
493
- | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, tombstone repair deleted `1` stale record, p99 query-after-loss `1.31 ms`. |
494
- | Active-active delta sync | 2 regions, bidirectional convergence `true`, stale import suppressed after delete `true`, tombstone convergence `true`, sync `159.69 ms`. |
495
- | Replicated snapshot job | 3 replica files, manifest checksum validation `true`, offsite mirror validation `true`, portable archive validation `true`, S3-compatible upload validation `true`, archive restore `24.85 ms`. |
496
- | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.62 ms`. |
493
+ | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, tombstone repair deleted `1` stale record, p99 query-after-loss `1.47 ms`. |
494
+ | Active-active delta sync | 2 regions, bidirectional convergence `true`, stale import suppressed after delete `true`, tombstone convergence `true`, sync `135.90 ms`. |
495
+ | Replicated snapshot job | 3 replica files, manifest checksum validation `true`, offsite mirror validation `true`, portable archive validation `true`, S3-compatible upload validation `true`, latest remote archive metadata validation `true`, object-store retention pruned `2`, archive restore `32.92 ms`. |
496
+ | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.77 ms`. |
497
497
 
498
498
  This profile validates routing, quorum-replicated runtime behavior, cache
499
499
  behavior, active-active namespace delta sync, replicated snapshot/restore, and
500
- structured payload handling, including verified offsite and archive restore.
500
+ structured payload handling, including verified offsite, archive, object-store
501
+ latest lookup, object-store retention, and archive restore.
501
502
  It is not a 10M-vector load test. Real 100k, 1M, and 10M latency claims should
502
503
  come from service-backed FAISS/Qdrant/pgvector load tests on production-like
503
504
  hardware.
@@ -527,16 +528,16 @@ Maintenance workers:
527
528
 
528
529
  ```sh
529
530
  wavemind maintenance --namespace user:42 --consolidate-steps 10 --consolidate-concepts --json
530
- wavemind replicated-snapshot --root ./state/replicas --node node-a --node node-b --node node-c --out ./backups/replicated --offsite ./offsite/replicated --archive ./archives/replicated --s3 s3://my-bucket/wavemind/prod --keep-last 7 --json
531
+ wavemind replicated-snapshot --root ./state/replicas --node node-a --node node-b --node node-c --out ./backups/replicated --offsite ./offsite/replicated --archive ./archives/replicated --s3 s3://my-bucket/wavemind/prod --keep-last 7 --s3-keep-last 30 --json
531
532
  ```
532
533
 
533
534
  The first command runs one deterministic memory pass: expired-memory purge,
534
535
  optional field/concept consolidation, and index-health repair. The second
535
536
  command creates a verified replicated snapshot, mirrors it to an offsite path,
536
537
  writes a portable `.tar.gz` archive, verifies that archive, can upload it to an
537
- S3-compatible object store, and applies retention. Production deployments can
538
- call these commands from cron, systemd, Kubernetes CronJobs, Celery, RQ, or
539
- Temporal.
538
+ S3-compatible object store, verify newest-archive metadata, and apply local and
539
+ object-store retention. Production deployments can call these commands from
540
+ cron, systemd, Kubernetes CronJobs, Celery, RQ, or Temporal.
540
541
 
541
542
  Hot-cache options:
542
543
 
@@ -642,6 +643,7 @@ snapshot_job = ReplicatedSnapshotWorker(memory).run_once(
642
643
  archive_destination="./archives/replicated",
643
644
  object_store_destination="s3://my-bucket/wavemind/prod",
644
645
  keep_last=7,
646
+ object_store_keep_last=30,
645
647
  )
646
648
  assert snapshot_job.ok
647
649
 
@@ -657,7 +659,9 @@ The replicated snapshot job writes one SQLite backup per replica plus
657
659
  node definitions. It can mirror the snapshot to a second path for offsite
658
660
  backup, write a portable `.tar.gz` archive for object-store/offsite systems,
659
661
  verify that archive, upload it to any S3-compatible object store through
660
- `boto3`, and apply `keep_last` retention locally, offsite, and for archives.
662
+ `boto3`, list the newest remote archive, restore from the newest remote archive,
663
+ and apply `keep_last` retention locally, offsite, for archives, and explicitly
664
+ for object-store archives through `object_store_keep_last`.
661
665
  Restore refuses to overwrite a non-empty root unless `overwrite=True` is passed.
662
666
 
663
667
  Equivalent CLI:
@@ -671,6 +675,12 @@ wavemind replicated-snapshot \
671
675
  --archive ./archives/replicated \
672
676
  --s3 s3://my-bucket/wavemind/prod \
673
677
  --keep-last 7 \
678
+ --s3-keep-last 30 \
679
+ --json
680
+
681
+ wavemind replicated-s3-archives \
682
+ --s3 s3://my-bucket/wavemind/prod \
683
+ --latest \
674
684
  --json
675
685
 
676
686
  wavemind replicated-restore \
@@ -680,7 +690,8 @@ wavemind replicated-restore \
680
690
  --json
681
691
 
682
692
  wavemind replicated-restore \
683
- --from s3://my-bucket/wavemind/prod/wavemind-replicated-20260705-120000.tar.gz \
693
+ --from s3://my-bucket/wavemind/prod \
694
+ --latest \
684
695
  --to ./state/restored-replicas \
685
696
  --overwrite \
686
697
  --json
@@ -1063,7 +1074,7 @@ Current read:
1063
1074
  | LongMemEval 50-query smoke | On the first 50 non-abstention LongMemEval-S questions, WaveMind reaches `evidence_recall@5 0.920`, `precision@1 0.760`, and `MRR@5 0.827`; Chroma/Qdrant static reach `0.600`, `0.260`, and `0.385`. | This is the fast regression profile for checking current changes before rerunning the full LongMemEval profile. WaveMind wins on quality; latency still needs work. |
1064
1075
  | ANN/index curve | At 50000 generated 128-d vectors, NumPy exact keeps `recall@10 1.000` at `6.49 ms`; quantized int8 keeps `0.934` at `24.92 ms`; Annoy is faster at `4.92 ms` but drops to `0.730` recall; Qdrant local keeps `1.000` recall at `43.49 ms`. | Current local scale boundary is clear: quantized search needs kernel work, Annoy needs tuning/FAISS, and Qdrant should be tested in service mode for a fair production comparison. |
1065
1076
  | Production load | At 100000 generated 128-d vectors, service-mode Qdrant reaches `recall@10 1.000`, avg `10.28 ms`, p99 `21.26 ms`. At 1M, tuned Qdrant reaches `recall@10 0.984`, avg `116.80 ms`, p99 `209.28 ms`; an EF sweep finds `recall@10 0.977`, avg `64.76 ms`, p99 `103.77 ms` at `hnsw_ef=2048` on 30 queries. | 100k is production-grade on the tested machine. 1M recall is now strong, but p99 still needs tuning before claiming a stable sub-100 ms SLO. |
1066
- | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, missing-record repair, tombstone repair, active-active delta sync, checksummed replicated snapshot/restore, offsite mirror verification, portable archive verification, S3-compatible upload verification, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, replicated-runtime, namespace-delta, offsite/archive/object-store backup, and restore-drill foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
1077
+ | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, missing-record repair, tombstone repair, active-active delta sync, checksummed replicated snapshot/restore, offsite mirror verification, portable archive verification, S3-compatible upload/latest-metadata/retention verification, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, replicated-runtime, namespace-delta, offsite/archive/object-store backup lifecycle, and restore-drill foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
1067
1078
  | Memory competitor adapters | WaveMind reaches `precision@1 0.80`, `precision@3 1.00`, stale suppression `1.00` on the small adapter profile. Mem0, Zep, and LangGraph are listed as skipped unless their real packages/services are configured. | This prevents fake competitor claims. The adapter harness is ready; real Mem0/Zep/LangGraph results still need configured installs. |
1068
1079
  | LongMemEval local answer generation | With the same local Ollama `qwen2.5:1.5b`, WaveMind reaches `exact_match 0.240`, `contains_answer 0.380`, `token_f1 0.333`, and `evidence_recall@5 0.920`; Chroma and Qdrant static both reach `0.120`, `0.160`, `0.170`, and `0.600`. | This is the first checked-in end-to-end answer benchmark against Chroma/Qdrant. It is still a 50-question lightweight smoke run, not a full LongMemEval leaderboard score. |
1069
1080
 
@@ -1082,7 +1093,7 @@ Current read:
1082
1093
  | Production index profile | Docker-backed 50000-vector profile for persisted FAISS, Qdrant service, and PostgreSQL/pgvector HNSW. | implemented | FAISS / Qdrant service / pgvector | Keep service-mode candidate generation above `0.95` recall@10 and below 10 ms average query latency at 50000 vectors. |
1083
1094
  | Production load profile | 100k and 1M service-backed candidate-index checks with p95/p99 latency. | implemented | Qdrant service / pgvector HNSW / FAISS persisted | Keep 100k at recall@10 `1.000`; push 1M p99 below 100 ms with recall@10 >= 0.95. |
1084
1095
  | Qdrant 1M HNSW ef sweep | One 1M Qdrant collection queried with multiple `hnsw_ef` values. | implemented | Qdrant service | Repeat with 100+ queries and collection-level HNSW build parameters before claiming a stable 1M SLO. |
1085
- | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, active-active delta sync, replicated snapshot/restore with offsite, archive, and object-store verification, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication, namespace-delta sync, repair, offsite/archive/object-store backup, and restore drills green while adding larger service-backed 10M load tests. |
1096
+ | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, active-active delta sync, replicated snapshot/restore with offsite, archive, object-store latest-metadata/retention verification, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication, namespace-delta sync, repair, offsite/archive/object-store backup lifecycle, and restore drills green while adding larger service-backed 10M load tests. |
1086
1097
  | Memory competitor adapter profile | Dynamic-memory scenario wired for external memory frameworks. | implemented | Mem0 / Zep / LangGraph persistent memory | Report real competitor results only when their packages/services are explicitly configured. |
1087
1098
  | [BEIR](https://github.com/beir-cellar/beir) | Standard zero-shot information retrieval quality. | planned | Chroma / Qdrant / FAISS | Stay within 0.02 `nDCG@10` on identical embeddings. |
1088
1099
  | [MTEB Retrieval](https://github.com/embeddings-benchmark/mteb) | Separates encoder quality from retrieval-store quality. | planned | Chroma / Qdrant / FAISS | Prove WaveMind does not reduce same-embedding retrieval quality. |
@@ -1669,10 +1680,11 @@ Near-term priorities:
1669
1680
  - Faster dynamic re-ranking through smaller candidate windows, caching, and
1670
1681
  background updates.
1671
1682
  - Better production operations: OpenTelemetry and replicated offsite snapshot
1672
- jobs with verified portable archives and S3-compatible upload are
1683
+ jobs with verified portable archives, S3-compatible upload, latest-archive
1684
+ lookup, restore from latest, and object-store retention are
1673
1685
  implemented; richer latency histograms, index-health metrics, alerting
1674
- examples, object-store retention/download drills, and Postgres PITR runbooks
1675
- are next.
1686
+ examples, real cloud disaster-recovery drills, and Postgres PITR runbooks are
1687
+ next.
1676
1688
 
1677
1689
  Longer-term direction:
1678
1690
 
@@ -21,7 +21,7 @@ This is a compact reader-facing view of checked-in benchmark results. It is not
21
21
  | Production load profile 100k | production-scale | Recall@k | WaveMind pgvector: 0.736 / 17.8 ms | Qdrant service: 1 / 10.3 ms | Baseline leads on quality |
22
22
  | Production load profile 1M | production-scale | Recall@k | - | Qdrant service: 0.984 / 116.8 ms | No WaveMind result |
23
23
  | Qdrant 1M HNSW ef sweep | production-scale | Recall@k | - | hnsw_ef=2048: 0.977 / 64.8 ms | No WaveMind result |
24
- | Scale readiness profile | production-scale | precision@1 | WaveMind structured payloads: 1 / 0.41 ms | - | WaveMind-only check |
24
+ | Scale readiness profile | production-scale | precision@1 | WaveMind structured payloads: 1 / 0.592 ms | - | WaveMind-only check |
25
25
  | Memory competitor adapter profile | agent-memory | precision@1 | WaveMind: 0.8 / 0.554 ms | - | WaveMind-only check |
26
26
  | [LongMemEval answer generation](https://github.com/xiaowu0162/LongMemEval) | long-term-agent-memory | token F1 | WaveMind + qwen2.5:1.5b: 0.333 / - | Chroma static + qwen2.5:1.5b: 0.17 / - | WaveMind leads on quality |
27
27
 
@@ -24,7 +24,7 @@ Planned rows are not claimed wins. They are the public proof path WaveMind must
24
24
  | Production load profile 100k | production-scale | implemented | Qdrant service: Recall@k 1.00, avg latency 10.3, p95 latency 19.0, p99 latency ms 21.3, build ms 27439.3<br>WaveMind pgvector: Recall@k 0.74, avg latency 17.8, p95 latency 23.5, build ms 455703.7<br>WaveMind faiss-persisted: skipped - Set WAVEMIND_FAISS_PATH to use the persisted FAISS backend | Tune pgvector HNSW build/search parameters and add persisted FAISS from the Linux benchmark container. |
25
25
  | Production load profile 1M | production-scale | implemented | Qdrant service: Recall@k 0.98, avg latency 116.8, p95 latency 153.8, p99 latency ms 209.3, build ms 450674.6 | Tune Qdrant indexing/search params further, then add FAISS IVF/HNSW and pgvector 1M profiles on a larger disk. |
26
26
  | Qdrant 1M HNSW ef sweep | production-scale | implemented | hnsw_ef=512: Recall@k 0.75, avg latency 47.2, p95 latency 68.5, p99 latency ms 68.5, max latency ms 68.5<br>hnsw_ef=768: Recall@k 0.85, avg latency 44.0, p95 latency 69.1, p99 latency ms 69.8, max latency ms 69.8<br>hnsw_ef=1024: Recall@k 0.88, avg latency 62.9, p95 latency 81.1, p99 latency ms 85.5, max latency ms 85.5<br>hnsw_ef=1536: Recall@k 0.94, avg latency 65.6, p95 latency 111.2, p99 latency ms 119.7, max latency ms 119.7<br>hnsw_ef=2048: Recall@k 0.98, avg latency 64.8, p95 latency 91.2, p99 latency ms 103.8, max latency ms 103.8 | Repeat with 100+ queries and collection-level HNSW build parameters before claiming a stable production SLO. |
27
- | Scale readiness profile | production-scale | implemented | WaveMind cluster planner: simulated memories 1000000, namespaces 4096, nodes 4, replication factor 2, node loss min availability 1.00, zone loss min availability 1.00, read quorum 1, write quorum 2, placement ms 62.6<br>WaveMind hot cache: queries 2000, capacity 512, hit rate 0.92, evictions 0, p99 lookup ms 0.00<br>WaveMind replicated runtime: nodes 3, replication factor 3, write quorum 2, read quorum 1, recalled after node loss True, repair copied records 1, tombstone repair deleted records 1, p99 query after loss ms 1.31<br>WaveMind active-active delta sync: regions 2, replication factor per region 3, records imported 6, converged after bidirectional sync True, suppressed stale import after delete True, tombstone converged True, sync ms 159.7<br>WaveMind replicated snapshot: nodes 3, manifest healthy True, offsite verified True, archive verified True, object store verified True, restored files 3, recalled after restore node loss True, snapshot ms 186.2, restore ms 24.9<br>WaveMind structured payloads: queries 4, precision@1 1.00, avg latency 0.41, p99 latency ms 0.62 | Move from local replicated runtime to service-backed replicated runs, object-store retention/download drills, and larger 10M candidate-index load tests. |
27
+ | Scale readiness profile | production-scale | implemented | WaveMind cluster planner: simulated memories 1000000, namespaces 4096, nodes 4, replication factor 2, node loss min availability 1.00, zone loss min availability 1.00, read quorum 1, write quorum 2, placement ms 72.2<br>WaveMind hot cache: queries 2000, capacity 512, hit rate 0.92, evictions 0, p99 lookup ms 0.01<br>WaveMind replicated runtime: nodes 3, replication factor 3, write quorum 2, read quorum 1, recalled after node loss True, repair copied records 1, tombstone repair deleted records 1, p99 query after loss ms 1.47<br>WaveMind active-active delta sync: regions 2, replication factor per region 3, records imported 6, converged after bidirectional sync True, suppressed stale import after delete True, tombstone converged True, sync ms 135.9<br>WaveMind replicated snapshot: nodes 3, manifest healthy True, offsite verified True, archive verified True, object store verified True, object store latest verified True, object store pruned 2, restored files 3, recalled after restore node loss True, snapshot ms 186.0, restore ms 32.9<br>WaveMind structured payloads: queries 4, precision@1 1.00, avg latency 0.59, p99 latency ms 0.77 | Move from local replicated runtime to service-backed replicated runs, real cloud object-store disaster-recovery drills, and larger 10M candidate-index load tests. |
28
28
  | Memory competitor adapter profile | agent-memory | implemented | WaveMind: precision@1 0.80, precision@3 1.00, stale suppression 1.00, avg latency 0.55, p95 latency 0.83<br>Mem0: skipped - Install Mem0 to run this adapter profile: pip install "mem0ai"<br>Zep: skipped - Install the Zep client package and set ZEP_API_KEY or ZEP_API_URL.<br>LangGraph persistent memory: skipped - Install LangGraph to run this adapter profile: pip install "langgraph" | Add documented setup commands for each competitor adapter and store checked-in results only when those real adapters run. |
29
29
  | [LongMemEval answer generation](https://github.com/xiaowu0162/LongMemEval) | long-term-agent-memory | implemented | extractive smoke: queries 20, evidence recall@k 1.00, exact match 0.00, contains answer 0.05, token f1 0.02, avg retrieval ms 3.79, avg generation ms 0.77<br>WaveMind + qwen2.5:0.5b: queries 50, evidence recall@k 0.92, exact match 0.12, contains answer 0.18, token f1 0.18, avg retrieval ms 2.98, avg generation ms 1428.2<br>Chroma static + qwen2.5:0.5b: queries 50, evidence recall@k 0.60, exact match 0.10, contains answer 0.12, token f1 0.13, avg retrieval ms 4.10, avg generation ms 1234.7<br>Qdrant static + qwen2.5:0.5b: queries 50, evidence recall@k 0.60, exact match 0.10, contains answer 0.12, token f1 0.13, avg retrieval ms 63.8, avg generation ms 893.5<br>WaveMind + qwen2.5:1.5b: queries 50, evidence recall@k 0.92, exact match 0.24, contains answer 0.38, token f1 0.33, avg retrieval ms 2.00, avg generation ms 2153.0<br>Chroma static + qwen2.5:1.5b: queries 50, evidence recall@k 0.60, exact match 0.12, contains answer 0.16, token f1 0.17, avg retrieval ms 7.05, avg generation ms 2082.4<br>Qdrant static + qwen2.5:1.5b: queries 50, evidence recall@k 0.60, exact match 0.12, contains answer 0.16, token f1 0.17, avg retrieval ms 100.2, avg generation ms 758.1 | Run all 470 non-abstention questions with a stronger local/API model and add faithfulness/abstention scoring. |
30
30
 
@@ -764,14 +764,14 @@
764
764
  "zone_loss_min_availability": 1.0,
765
765
  "read_quorum": 1,
766
766
  "write_quorum": 2,
767
- "placement_ms": 62.552399991545826
767
+ "placement_ms": 72.24250002764165
768
768
  },
769
769
  "WaveMind hot cache": {
770
770
  "queries": 2000,
771
771
  "capacity": 512,
772
772
  "hit_rate": 0.92,
773
773
  "evictions": 0,
774
- "p99_lookup_ms": 0.0026999623514711857
774
+ "p99_lookup_ms": 0.005199981387704611
775
775
  },
776
776
  "WaveMind replicated runtime": {
777
777
  "nodes": 3,
@@ -781,7 +781,7 @@
781
781
  "recalled_after_node_loss": true,
782
782
  "repair_copied_records": 1,
783
783
  "tombstone_repair_deleted_records": 1,
784
- "p99_query_after_loss_ms": 1.3142999960109591
784
+ "p99_query_after_loss_ms": 1.469200011342764
785
785
  },
786
786
  "WaveMind active-active delta sync": {
787
787
  "regions": 2,
@@ -790,7 +790,7 @@
790
790
  "converged_after_bidirectional_sync": true,
791
791
  "suppressed_stale_import_after_delete": true,
792
792
  "tombstone_converged": true,
793
- "sync_ms": 159.69160001259297
793
+ "sync_ms": 135.9029000159353
794
794
  },
795
795
  "WaveMind replicated snapshot": {
796
796
  "nodes": 3,
@@ -798,20 +798,22 @@
798
798
  "offsite_verified": true,
799
799
  "archive_verified": true,
800
800
  "object_store_verified": true,
801
+ "object_store_latest_verified": true,
802
+ "object_store_pruned": 2,
801
803
  "restored_files": 3,
802
804
  "recalled_after_restore_node_loss": true,
803
- "snapshot_ms": 186.24169996473938,
804
- "restore_ms": 24.853000009898096
805
+ "snapshot_ms": 185.95519999507815,
806
+ "restore_ms": 32.917500007897615
805
807
  },
806
808
  "WaveMind structured payloads": {
807
809
  "queries": 4,
808
810
  "precision_at_1": 1.0,
809
- "avg_latency_ms": 0.4099500220036134,
810
- "p99_latency_ms": 0.6203000084497035
811
+ "avg_latency_ms": 0.5916499794693664,
812
+ "p99_latency_ms": 0.7669999613426626
811
813
  }
812
814
  },
813
- "target": "Prove the production foundation before heavier 100k, 1M, and 10M vector load tests: deterministic placement, survivable replicas, active-active sync, offsite/archive/object-store-verified restore drills, hot-cache behavior, and structured payload recall.",
814
- "next_step": "Move from local replicated runtime to service-backed replicated runs, object-store retention/download drills, and larger 10M candidate-index load tests."
815
+ "target": "Prove the production foundation before heavier 100k, 1M, and 10M vector load tests: deterministic placement, survivable replicas, active-active sync, offsite/archive/object-store upload/latest-metadata/retention restore drills, hot-cache behavior, and structured payload recall.",
816
+ "next_step": "Move from local replicated runtime to service-backed replicated runs, real cloud object-store disaster-recovery drills, and larger 10M candidate-index load tests."
815
817
  },
816
818
  {
817
819
  "id": "memory_competitor_adapter_profile",
@@ -768,6 +768,8 @@ def _implemented_entries(root: Path) -> list[dict[str, Any]]:
768
768
  "offsite_verified",
769
769
  "archive_verified",
770
770
  "object_store_verified",
771
+ "object_store_latest_verified",
772
+ "object_store_pruned",
771
773
  "restored_files",
772
774
  "recalled_after_restore_node_loss",
773
775
  "snapshot_ms",
@@ -784,8 +786,8 @@ def _implemented_entries(root: Path) -> list[dict[str, Any]]:
784
786
  ),
785
787
  ),
786
788
  },
787
- "target": "Prove the production foundation before heavier 100k, 1M, and 10M vector load tests: deterministic placement, survivable replicas, active-active sync, offsite/archive/object-store-verified restore drills, hot-cache behavior, and structured payload recall.",
788
- "next_step": "Move from local replicated runtime to service-backed replicated runs, object-store retention/download drills, and larger 10M candidate-index load tests.",
789
+ "target": "Prove the production foundation before heavier 100k, 1M, and 10M vector load tests: deterministic placement, survivable replicas, active-active sync, offsite/archive/object-store upload/latest-metadata/retention restore drills, hot-cache behavior, and structured payload recall.",
790
+ "next_step": "Move from local replicated runtime to service-backed replicated runs, real cloud object-store disaster-recovery drills, and larger 10M candidate-index load tests.",
789
791
  },
790
792
  {
791
793
  "id": "memory_competitor_adapter_profile",
@@ -35,11 +35,14 @@ from wavemind import (
35
35
  class InMemoryS3Client:
36
36
  def __init__(self):
37
37
  self.objects: dict[tuple[str, str], dict[str, object]] = {}
38
+ self.counter = 0
38
39
 
39
40
  def upload_file(self, filename: str, bucket: str, key: str, ExtraArgs=None):
41
+ self.counter += 1
40
42
  self.objects[(bucket, key)] = {
41
43
  "Body": Path(filename).read_bytes(),
42
44
  "Metadata": dict((ExtraArgs or {}).get("Metadata") or {}),
45
+ "LastModified": f"2026-01-01T00:00:{self.counter:02d}Z",
43
46
  }
44
47
 
45
48
  def head_object(self, Bucket: str, Key: str) -> dict[str, object]:
@@ -51,6 +54,34 @@ class InMemoryS3Client:
51
54
  "ETag": '"benchmark-etag"',
52
55
  }
53
56
 
57
+ def list_objects_v2(
58
+ self,
59
+ Bucket: str,
60
+ Prefix: str = "",
61
+ ContinuationToken: str | None = None,
62
+ ) -> dict[str, object]:
63
+ contents = []
64
+ for (bucket, key), payload in self.objects.items():
65
+ if bucket == Bucket and key.startswith(Prefix):
66
+ body = payload["Body"]
67
+ contents.append(
68
+ {
69
+ "Key": key,
70
+ "Size": len(body),
71
+ "LastModified": payload["LastModified"],
72
+ "ETag": '"benchmark-etag"',
73
+ }
74
+ )
75
+ return {"Contents": sorted(contents, key=lambda item: item["Key"])}
76
+
77
+ def delete_objects(self, Bucket: str, Delete: dict[str, object]) -> dict[str, object]:
78
+ deleted = []
79
+ for item in Delete["Objects"]:
80
+ key = item["Key"]
81
+ self.objects.pop((Bucket, key), None)
82
+ deleted.append({"Key": key})
83
+ return {"Deleted": deleted}
84
+
54
85
 
55
86
  def percentile(values: list[float], pct: float) -> float:
56
87
  if not values:
@@ -361,6 +392,10 @@ def run_replicated_snapshot_profile() -> dict[str, object]:
361
392
  "s3://wavemind-benchmark/replicated",
362
393
  client=InMemoryS3Client(),
363
394
  )
395
+ for index in range(2):
396
+ old_archive = root / f"old-object-archive-{index}.tar.gz"
397
+ old_archive.write_bytes(f"old-object-archive-{index}".encode("utf-8"))
398
+ object_store.upload_archive(old_archive)
364
399
  snapshot_job = ReplicatedSnapshotWorker(memory).run_once(
365
400
  destination=root / "snapshots",
366
401
  offsite_destination=root / "offsite",
@@ -368,9 +403,11 @@ def run_replicated_snapshot_profile() -> dict[str, object]:
368
403
  object_store_destination="s3://wavemind-benchmark/replicated",
369
404
  object_store=object_store,
370
405
  keep_last=2,
406
+ object_store_keep_last=1,
371
407
  )
372
408
  snapshot_ms = (time.perf_counter() - snapshot_started) * 1000.0
373
409
  health = ReplicatedWaveMind.verify_snapshot(snapshot_job.snapshot_path)
410
+ latest_object_archive = object_store.latest_archive()
374
411
 
375
412
  restore_started = time.perf_counter()
376
413
  restored, restore = ReplicatedWaveMind.restore_snapshot_archive(
@@ -397,6 +434,10 @@ def run_replicated_snapshot_profile() -> dict[str, object]:
397
434
  snapshot_job.object_store_upload
398
435
  and snapshot_job.object_store_upload.verified
399
436
  ),
437
+ "object_store_latest_verified": bool(
438
+ latest_object_archive and latest_object_archive.verified
439
+ ),
440
+ "object_store_pruned": len(snapshot_job.pruned_object_store),
400
441
  "total_bytes": snapshot_job.total_bytes,
401
442
  "snapshot_ms": snapshot_ms,
402
443
  "restore_ms": restore_ms,
@@ -511,9 +552,9 @@ def run_benchmark(
511
552
  "Deterministic scale-readiness profile for cluster placement, "
512
553
  "node/zone loss simulation, quorum-replicated runtime behavior, "
513
554
  "active-active delta sync, replicated snapshot/offsite/archive "
514
- "restore, S3-compatible object-store upload verification, hot-cache "
515
- "behavior, and structured payload retrieval. This is not a 10M-vector "
516
- "database load test."
555
+ "restore, S3-compatible object-store upload/latest-metadata/"
556
+ "retention verification, hot-cache behavior, and structured payload retrieval. "
557
+ "This is not a 10M-vector database load test."
517
558
  ),
518
559
  },
519
560
  "results": results,
@@ -562,6 +603,8 @@ def main() -> int:
562
603
  print(f"| replicated snapshot | offsite_verified | {result['offsite_verified']} |")
563
604
  print(f"| replicated snapshot | archive_verified | {result['archive_verified']} |")
564
605
  print(f"| replicated snapshot | object_store_verified | {result['object_store_verified']} |")
606
+ print(f"| replicated snapshot | object_store_latest_verified | {result['object_store_latest_verified']} |")
607
+ print(f"| replicated snapshot | object_store_pruned | {result['object_store_pruned']} |")
565
608
  print(f"| replicated snapshot | recalled_after_restore_node_loss | {result['recalled_after_restore_node_loss']} |")
566
609
  else:
567
610
  print(f"| structured payloads | precision@1 | {result['precision_at_1']:.3f} |")
@@ -5,7 +5,7 @@
5
5
  "namespace_count": 4096,
6
6
  "node_count": 4,
7
7
  "replication_factor": 2,
8
- "description": "Deterministic scale-readiness profile for cluster placement, node/zone loss simulation, quorum-replicated runtime behavior, active-active delta sync, replicated snapshot/offsite/archive restore, S3-compatible object-store upload verification, hot-cache behavior, and structured payload retrieval. This is not a 10M-vector database load test."
8
+ "description": "Deterministic scale-readiness profile for cluster placement, node/zone loss simulation, quorum-replicated runtime behavior, active-active delta sync, replicated snapshot/offsite/archive restore, S3-compatible object-store upload/latest-metadata/retention verification, hot-cache behavior, and structured payload retrieval. This is not a 10M-vector database load test."
9
9
  },
10
10
  "results": [
11
11
  {
@@ -14,7 +14,7 @@
14
14
  "namespaces": 4096,
15
15
  "nodes": 4,
16
16
  "replication_factor": 2,
17
- "placement_ms": 62.552399991545826,
17
+ "placement_ms": 72.24250002764165,
18
18
  "max_replica_load": 2413,
19
19
  "min_replica_load": 1728,
20
20
  "replica_load_stdev": 316.54462560593254,
@@ -32,8 +32,8 @@
32
32
  "capacity": 512,
33
33
  "hit_rate": 0.92,
34
34
  "evictions": 0,
35
- "avg_lookup_ms": 0.0013917501782998443,
36
- "p99_lookup_ms": 0.0026999623514711857
35
+ "avg_lookup_ms": 0.0017484501586295664,
36
+ "p99_lookup_ms": 0.005199981387704611
37
37
  },
38
38
  {
39
39
  "engine": "WaveMind replicated runtime",
@@ -47,8 +47,8 @@
47
47
  "tombstone_suppressed_before_repair": true,
48
48
  "tombstone_suppressed_after_repair": true,
49
49
  "tombstone_repair_deleted_records": 1,
50
- "avg_query_after_loss_ms": 1.3142999960109591,
51
- "p99_query_after_loss_ms": 1.3142999960109591
50
+ "avg_query_after_loss_ms": 1.469200011342764,
51
+ "p99_query_after_loss_ms": 1.469200011342764
52
52
  },
53
53
  {
54
54
  "engine": "WaveMind active-active delta sync",
@@ -56,7 +56,7 @@
56
56
  "replication_factor_per_region": 3,
57
57
  "records_imported": 6,
58
58
  "converged_after_bidirectional_sync": true,
59
- "sync_ms": 159.69160001259297,
59
+ "sync_ms": 135.9029000159353,
60
60
  "suppressed_stale_import_after_delete": true,
61
61
  "tombstone_deleted_records": 3,
62
62
  "tombstone_converged": true
@@ -68,9 +68,11 @@
68
68
  "offsite_verified": true,
69
69
  "archive_verified": true,
70
70
  "object_store_verified": true,
71
+ "object_store_latest_verified": true,
72
+ "object_store_pruned": 2,
71
73
  "total_bytes": 110592,
72
- "snapshot_ms": 186.24169996473938,
73
- "restore_ms": 24.853000009898096,
74
+ "snapshot_ms": 185.95519999507815,
75
+ "restore_ms": 32.917500007897615,
74
76
  "restored_files": 3,
75
77
  "recalled_after_restore_node_loss": true
76
78
  },
@@ -84,8 +86,8 @@
84
86
  ],
85
87
  "queries": 4,
86
88
  "precision_at_1": 1.0,
87
- "avg_latency_ms": 0.4099500220036134,
88
- "p99_latency_ms": 0.6203000084497035
89
+ "avg_latency_ms": 0.5916499794693664,
90
+ "p99_latency_ms": 0.7669999613426626
89
91
  }
90
92
  ]
91
93
  }
@@ -4,7 +4,7 @@ services:
4
4
  context: .
5
5
  args:
6
6
  INSTALL_OPTIONAL: "false"
7
- image: wavemind:2.3.0
7
+ image: wavemind:2.3.1
8
8
  restart: unless-stopped
9
9
  environment:
10
10
  WAVEMIND_DB: /data/wavemind.sqlite3
@@ -31,7 +31,7 @@ purpose-built vector databases.
31
31
  | NoMIRACL Russian retrieval | WaveMind reaches `nDCG@10 0.434`; Chroma reaches `0.435`; Qdrant reaches `0.433`. Chroma is faster. | `benchmarks/nomiracl_russian_results.json` | `python benchmarks/nomiracl_russian_benchmark.py --engines wavemind chroma qdrant --output benchmarks/nomiracl_russian_results.json` |
32
32
  | Production index profile | At 50000 vectors, persisted FAISS and Qdrant service both reach `recall@10 1.000`; pgvector with `ef_search=400` reaches `0.811`. | `benchmarks/production_index_profile_results.json` | `docker compose -f examples/production-index-profile/docker-compose.yml run --rm benchmark` |
33
33
  | Production load profile | At 100000 vectors, Qdrant service reaches `recall@10 1.000`, avg `10.28 ms`, p99 `21.26 ms`. At 1M vectors, tuned Qdrant reaches `0.984`, avg `116.80 ms`, p99 `209.28 ms`; the best EF-sweep point reaches `0.977`, avg `64.76 ms`, p99 `103.77 ms`. | `benchmarks/production_load_qdrant_100k_tuned_results.json`, `benchmarks/production_load_qdrant_1m_tuned_results.json`, `benchmarks/production_load_qdrant_1m_ef_sweep_results.json` | `python benchmarks/production_load_benchmark.py --sizes 100000 --engines qdrant-service` |
34
- | Scale readiness profile | Deterministic 1M-memory simulation: namespace placement survives node loss and zone loss at `1.000`, hot-cache hit rate is `0.920`, replicated runtime survives node loss, active-active delta sync converges, replicated snapshot restore survives primary loss, offsite mirror verification is `true`, portable archive verification is `true`, S3-compatible upload verification is `true`, structured payload precision@1 is `1.000`. | `benchmarks/scale_readiness_results.json` | `python benchmarks/scale_readiness_benchmark.py --simulated-memories 1000000 --output benchmarks/scale_readiness_results.json` |
34
+ | Scale readiness profile | Deterministic 1M-memory simulation: namespace placement survives node loss and zone loss at `1.000`, hot-cache hit rate is `0.920`, replicated runtime survives node loss, active-active delta sync converges, replicated snapshot restore survives primary loss, offsite mirror verification is `true`, portable archive verification is `true`, S3-compatible upload verification is `true`, latest remote archive metadata verification is `true`, object-store retention prunes `2` stale archives, structured payload precision@1 is `1.000`. | `benchmarks/scale_readiness_results.json` | `python benchmarks/scale_readiness_benchmark.py --simulated-memories 1000000 --output benchmarks/scale_readiness_results.json` |
35
35
  | Memory competitor adapter profile | WaveMind reaches `precision@1 0.80`, `precision@3 1.00`, stale suppression `1.00`; Mem0, Zep, and LangGraph are skipped until real packages/services are configured. | `benchmarks/memory_competitor_results.json` | `python benchmarks/memory_competitor_benchmark.py --engines wavemind mem0 zep langgraph` |
36
36
 
37
37
  The generated matrix view is in `benchmarks/BENCHMARK_REPORT.md`; the compact
@@ -52,8 +52,9 @@ policy matters more than raw vector-database scale:
52
52
  - `benchmarks/scale_readiness_benchmark.py` now checks 1M-memory simulated
53
53
  namespace placement, quorum-replicated runtime behavior, active-active
54
54
  namespace delta sync, checksummed replicated snapshot/restore with offsite
55
- and portable-archive verification, S3-compatible object-store upload
56
- verification, hot-cache behavior, and structured-payload retrieval.
55
+ and portable-archive verification, S3-compatible object-store upload,
56
+ latest-archive, and retention verification, hot-cache behavior, and
57
+ structured-payload retrieval.
57
58
  - Dynamic policy already covers hot memory, stale suppression, corrections,
58
59
  TTL, and namespace isolation.
59
60
  - Field self-consolidation is available through `WaveMind.consolidate_concepts()`,
@@ -66,7 +67,8 @@ policy matters more than raw vector-database scale:
66
67
  - API key roles and opt-in rate limiting are available for FastAPI deployments.
67
68
  - SQLite backup, timestamped retention, restore, admin-only HTTP backup,
68
69
  replicated snapshot/restore, offsite-mirrored snapshot jobs, and verified
69
- `.tar.gz` snapshot archives with S3-compatible upload are available as the
70
+ `.tar.gz` snapshot archives with S3-compatible upload, latest-archive lookup,
71
+ restore-from-latest support, and object-store retention are available as the
70
72
  first durability layer.
71
73
  - Public retrieval evidence exists for LoCoMo, LongMemEval, and BEIR/SciFact,
72
74
  but full answer-quality evaluation is still the next proof step.
@@ -246,8 +248,9 @@ Enterprise requirements:
246
248
  - audit logs for remember, query, recall feedback, and forget;
247
249
  - backup, restore, and point-in-time recovery. SQLite backup/restore and
248
250
  replicated snapshot/restore, offsite-mirrored snapshot jobs, and portable
249
- snapshot archives with S3-compatible upload are implemented; point-in-time
250
- recovery, object-store retention/download drills in real cloud storage, and
251
+ snapshot archives with S3-compatible upload, latest-archive lookup, and
252
+ retention are implemented; point-in-time recovery, real cloud
253
+ disaster-recovery drills, and
251
254
  network-service consensus remain future work;
252
255
  - data residency controls;
253
256
  - SSO/OAuth integration;
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wavemind"
7
- version = "2.3.0"
7
+ version = "2.3.1"
8
8
  description = "Local-first dynamic memory field with vector search and wave-field re-ranking"
9
9
  readme = "README.md"
10
10
  license = "MIT"