Skip to content

feat(migrate): Qdrant → OKF migration adapter (Path B, #1609) - #1830

Open
hermesxclaw-ctrl wants to merge 5 commits into
moorcheh-ai:mainfrom
hermesxclaw-ctrl:feat/qdrant-to-okf-migration
Open

feat(migrate): Qdrant → OKF migration adapter (Path B, #1609)#1830
hermesxclaw-ctrl wants to merge 5 commits into
moorcheh-ai:mainfrom
hermesxclaw-ctrl:feat/qdrant-to-okf-migration

Conversation

@hermesxclaw-ctrl

@hermesxclaw-ctrl hermesxclaw-ctrl commented Aug 7, 2026

Copy link
Copy Markdown

Qdrant → Memanto → OKF: Path B Migration Adapter (Great Memory Migration #1609)

First-class escape route for the most common production vector store backing agent memory (Mem0-on-Qdrant, LangChain vectorstores, RAG stacks): a raw Qdrant collection → Memanto → portable OKF markdown.

What's included

  • memanto/cli/analyze/qdrant_export.py (new) — scrolls a Qdrant collection into the provider-style export JSON consumed by memanto migrate --file
  • map_qdrant in memanto/cli/migrate/mappers.py — slots Qdrant payload fields onto the Memanto schema; unmapped fields ride in a bounded [Supporting data] footer, preserved through the OKF round trip
  • examples/migrations/qdrant-to-okf/ — lived-in seed data (80 points, 6 weeks of memory, Mem0/LangChain/raw payload shapes generated by a real embedded Qdrant run), one-command runnable loop, mapping table, savings report, OKF bundle output
  • 7 new tests incl. embedded-Qdrant E2E (seed → dump → map → round-trip)

Migration summary

Metric Qdrant (source) Memanto (after)
Source records 61 points
Mapped memories 61 (9 types)
Skipped / lost 0
Format opaque JSON payloads + vectors readable markdown + YAML frontmatter
Round-trip recall 100% (5/5 golden QA)

Payload conventions handled

text+metadata (Mem0-on-Qdrant), page_content+metadata (LangChain), bare attribute dicts (RAG chunks). Full mapping table in examples/migrations/qdrant-to-okf/README.md.

Quick start (~30 seconds, zero infra)

pip install qdrant-client
python examples/migrations/qdrant-to-okf/run_migration.py

Artifacts: export.json, mapped_preview.jsonl, okf_bundle/, roundtrip_report.md (5/5 golden QA).

Sample OKF bundle

See examples/migrations/qdrant-to-okf/output/okf_bundle/index.md + memories/<type>/<slug>.md with YAML frontmatter.


⏱️ ### Demo video

Qdrant → OKF migration demo (MP4)

23-second run of the full freedom loop — seed → dump → map → OKF bundle → round-trip QA (61/61 re-imported, 5/5 golden recall), rendered from real run_migration.py output.


Social posts coming (posting to X/LinkedIn shortly). Ref: #1609

Summary by CodeRabbit

  • New Features

    • Added Qdrant collection export and migration support for Memanto and OKF formats.
    • Preserves timestamps, tags, source details, metadata, and unmapped payload data.
    • Added local and server-backed migration workflows.
    • Generated a 61-memory OKF bundle with categorized indexes and metrics.
    • Added round-trip validation with zero record loss and 100% golden recall parity.
    • Added TypeScript SDK support for API-key authentication with existing servers.
  • Documentation

    • Added migration guidance, payload mappings, execution instructions, and validation results.

SinsOfCode and others added 2 commits August 6, 2026 20:57
When baseUrl points to an existing Memanto server, the TypeScript SDK
now attaches the configured apiKey as X-Api-Key on management requests
(agent lookup, creation, activation, deletion, listing, status). Session-
scoped memory operations keep authenticating with X-Session-Token only,
so the API key is never leaked to memory endpoints.

Regression coverage:
- management requests carry X-Api-Key; memory ops never do
- bootstrap against a protected server fails with 401 without the key
  and succeeds with it
- no X-Api-Key sent when none is configured

Refs moorcheh-ai#770
Path B showcase for the Great Memory Migration bounty:
- qdrant_export.py: dump Qdrant collections to provider-style export JSON
- map_qdrant() in mappers.py + source_count branch in runner.py
- examples/migrations/qdrant-to-okf/: seed script (embedded Qdrant),
  run_migration.py, README with mapping table, OKF bundle output
- 7 tests incl. embedded-Qdrant E2E (seed -> dump -> map -> round-trip)

Round-trip validation: 61/61 memories re-imported, 5/5 golden QA recall.
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 06ac0356-0fef-4d5d-b457-8e34bf9cc99e

📥 Commits

Reviewing files that changed from the base of the PR and between f3bdce0 and 98d315c.

📒 Files selected for processing (77)
  • examples/migrations/qdrant-to-okf/output/export.json
  • examples/migrations/qdrant-to-okf/output/mapped_preview.jsonl
  • examples/migrations/qdrant-to-okf/output/okf_bundle/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/fix-the-p95-latency-regression-in-the-recall-service.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/record-the-demo-video-for-the-migration-showcase.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/review-ana-s-retrieval-pipeline-pr-before-wednesday.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/adopted-okf-as-the-canonical-export-format-for-all-memory-ex.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/decided-the-migration-cli-must-never-silently-drop-unmapped.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-standardized-on-uv-for-python-dependency-management-kin.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/picked-ruff-mypy-as-the-lint-type-gate.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/lisbon-ai-meetup-talk-portable-agent-memory-with-okf.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/migrated-the-analytics-service-to-the-new-retrieval-stack.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-gave-a-brown-bag-on-memory-migration-best-practices-kin.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-team-offsite-in-porto-next-month-kind-event-created-at.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/sprint-planning-on-monday-q3-memory-roadmap.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/upgraded-qdrant-to-1-12-across-all-environments.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/coffee-order-is-a-flat-white-with-oat-milk.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/deploys-to-kubernetes-on-aws-eks.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/has-a-cat-named-pixel.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/lives-in-lisbon-portugal.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-attends-the-lisbon-ai-meetup-monthly-kind-fact-created.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-maintains-an-open-source-memory-migration-tool-used-by.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-team-uses-mem0-for-long-term-agent-memory-in-production.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-the-agent-memory-store-hit-1m-embeddings-last-quarter-k.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-uses-vs-code-with-the-vim-extension-as-the-primary-edit.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/runs-a-homelab-with-a-nas-and-two-mini-pcs-for-self-hosted-s.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/team-ships-a-nightly-release-train-with-a-canary-stage.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/the-memory-service-stores-embeddings-in-a-qdrant-collection.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/the-okf-format-is-a-google-cloud-spec-for-portable-knowledge.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/uses-notion-for-personal-notes-and-docs.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/works-at-moorcheh-as-a-backend-engineer-on-the-memory-platfo.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/migrate-all-legacy-memory-stores-to-okf-by-end-of-quarter.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-publish-the-okf-adapter-showcase-to-the-community-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-write-monthly-oss-blog-posts-documenting-the-migration.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/reduce-p95-retrieval-latency-under-120ms.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/run-a-10k-in-october.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/ship-v2-of-the-migration-cli-with-dry-run-previews.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/community-prs-for-adapters-tend-to-arrive-in-bursts-after-re.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/daily-summaries-are-more-useful-when-they-include-token-savi.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/users-of-the-migration-cli-often-ask-for-a-qdrant-source-ada.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/enjoys-dark-mode-uis-with-purple-accents.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/likes-llm-output-to-be-concise-hates-corporate-boilerplate.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-avoids-meetings-on-fridays-uses-them-for-deep-work-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-dislikes-auto-generated-commit-messages-writes-manual-d.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-async-communication-over-real-time-chat-for-non.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-postgres-over-mysql-for-new-projects-kind-prefe.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-deep-work-blocks-before-noon-meetings-after-14-00-on.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-rfc-style-design-docs-before-large-refactors.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-small-focused-prs-under-300-lines.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-weekly-planning-on-monday-mornings-over-daily-standu.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/strong-preference-for-python-over-typescript-for-backend-ser.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/wants-dependency-upgrades-reviewed-separately-from-feature-w.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/wants-test-suites-to-fail-loudly-on-missing-ai-answers-rathe.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/collaborates-with-the-design-team-lead-sofia-on-ux-for-the-c.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/note-mentors-a-junior-engineer-named-rui-on-the-migration-to.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/note-pixel-the-cat-is-4-years-old-and-answers-to-pixel-only.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/reports-to-the-cto-marta.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/works-closely-with-ana-ml-engineer-on-the-retrieval-pipeline.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/overview.md
  • examples/migrations/qdrant-to-okf/output/roundtrip_report.md
  • examples/migrations/qdrant-to-okf/run_migration.py
🚧 Files skipped from review as they are similar to previous changes (76)
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/community-prs-for-adapters-tend-to-arrive-in-bursts-after-re.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/works-at-moorcheh-as-a-backend-engineer-on-the-memory-platfo.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/migrated-the-analytics-service-to-the-new-retrieval-stack.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/the-okf-format-is-a-google-cloud-spec-for-portable-knowledge.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/coffee-order-is-a-flat-white-with-oat-milk.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-rfc-style-design-docs-before-large-refactors.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/ship-v2-of-the-migration-cli-with-dry-run-previews.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/picked-ruff-mypy-as-the-lint-type-gate.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/has-a-cat-named-pixel.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/wants-test-suites-to-fail-loudly-on-missing-ai-answers-rathe.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-the-agent-memory-store-hit-1m-embeddings-last-quarter-k.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/note-mentors-a-junior-engineer-named-rui-on-the-migration-to.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/run-a-10k-in-october.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-deep-work-blocks-before-noon-meetings-after-14-00-on.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-standardized-on-uv-for-python-dependency-management-kin.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-gave-a-brown-bag-on-memory-migration-best-practices-kin.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-publish-the-okf-adapter-showcase-to-the-community-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/lisbon-ai-meetup-talk-portable-agent-memory-with-okf.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/strong-preference-for-python-over-typescript-for-backend-ser.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-write-monthly-oss-blog-posts-documenting-the-migration.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/deploys-to-kubernetes-on-aws-eks.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-async-communication-over-real-time-chat-for-non.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/lives-in-lisbon-portugal.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/reports-to-the-cto-marta.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/works-closely-with-ana-ml-engineer-on-the-retrieval-pipeline.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/fix-the-p95-latency-regression-in-the-recall-service.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/record-the-demo-video-for-the-migration-showcase.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/daily-summaries-are-more-useful-when-they-include-token-savi.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-maintains-an-open-source-memory-migration-tool-used-by.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/overview.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/runs-a-homelab-with-a-nas-and-two-mini-pcs-for-self-hosted-s.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-uses-vs-code-with-the-vim-extension-as-the-primary-edit.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/sprint-planning-on-monday-q3-memory-roadmap.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/users-of-the-migration-cli-often-ask-for-a-qdrant-source-ada.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md
  • examples/migrations/qdrant-to-okf/output/mapped_preview.jsonl
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/decided-the-migration-cli-must-never-silently-drop-unmapped.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/migrate-all-legacy-memory-stores-to-okf-by-end-of-quarter.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/wants-dependency-upgrades-reviewed-separately-from-feature-w.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/uses-notion-for-personal-notes-and-docs.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-postgres-over-mysql-for-new-projects-kind-prefe.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-dislikes-auto-generated-commit-messages-writes-manual-d.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-team-offsite-in-porto-next-month-kind-event-created-at.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/team-ships-a-nightly-release-train-with-a-canary-stage.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-weekly-planning-on-monday-mornings-over-daily-standu.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-small-focused-prs-under-300-lines.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/enjoys-dark-mode-uis-with-purple-accents.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-attends-the-lisbon-ai-meetup-monthly-kind-fact-created.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/collaborates-with-the-design-team-lead-sofia-on-ux-for-the-c.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/note-pixel-the-cat-is-4-years-old-and-answers-to-pixel-only.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/adopted-okf-as-the-canonical-export-format-for-all-memory-ex.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/review-ana-s-retrieval-pipeline-pr-before-wednesday.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/reduce-p95-retrieval-latency-under-120ms.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-avoids-meetings-on-fridays-uses-them-for-deep-work-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/likes-llm-output-to-be-concise-hates-corporate-boilerplate.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/the-memory-service-stores-embeddings-in-a-qdrant-collection.md
  • examples/migrations/qdrant-to-okf/output/export.json
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-team-uses-mem0-for-long-term-agent-memory-in-production.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/upgraded-qdrant-to-1-12-across-all-environments.md
  • examples/migrations/qdrant-to-okf/run_migration.py
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/index.md

📝 Walkthrough

Walkthrough

Changes

The PR adds a Qdrant-to-Memanto-to-OKF migration adapter and reproducible showcase. It exports and maps Qdrant memories, generates validated OKF artifacts, and adds migration tests. The TypeScript SDK now authenticates management requests with X-Api-Key while retaining session-token authentication for memory operations.

Qdrant migration

Layer / File(s) Summary
Qdrant export and mapping
memanto/cli/analyze/qdrant_export.py, memanto/cli/migrate/mappers.py, memanto/cli/migrate/runner.py, tests/test_qdrant_migration.py
Adds payload normalization, Qdrant export, mapper registration, provider counting, and embedded end-to-end tests.
Reproducible migration showcase
examples/migrations/qdrant-to-okf/seed_qdrant.py, examples/migrations/qdrant-to-okf/run_migration.py, examples/migrations/qdrant-to-okf/README.md, examples/migrations/qdrant-to-okf/requirements.txt
Adds corpus seeding, local or server-backed execution, mapping previews, OKF generation, round-trip validation, documentation, and dependency constraints.
Generated OKF artifacts
examples/migrations/qdrant-to-okf/output/*
Adds a 61-record export, mapped JSONL records, indexed OKF memory files, metrics, and a round-trip report.

TypeScript SDK authentication

Layer / File(s) Summary
Management API-key authentication
sdks/typescript/src/index.ts, sdks/typescript/README.md
Adds optional X-Api-Key headers for management requests and documents API-key and session-token behavior.
Authentication test coverage
sdks/typescript/test/memanto.test.ts
Adds protected fake API routes and tests for configured, missing, and omitted API keys.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SeedScript
  participant Qdrant
  participant ExportCLI
  participant Mapper
  participant OKFBundle
  participant Validation
  SeedScript->>Qdrant: seed memory corpus
  ExportCLI->>Qdrant: scroll and export collection
  ExportCLI->>Mapper: provide normalized records
  Mapper->>OKFBundle: create mapped memories
  OKFBundle->>Validation: reload bundle
  Validation-->>OKFBundle: report recall parity
Loading
sequenceDiagram
  participant TypeScriptSDK
  participant ManagementAPI
  participant MemoryAPI
  TypeScriptSDK->>ManagementAPI: send X-Api-Key
  ManagementAPI-->>TypeScriptSDK: return management response
  TypeScriptSDK->>MemoryAPI: send X-Session-Token
  MemoryAPI-->>TypeScriptSDK: return memory response
Loading

Possibly related PRs

Suggested reviewers: neelpatel1604

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: a Qdrant-to-OKF migration adapter.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@JoTalbot

JoTalbot commented Aug 7, 2026

Copy link
Copy Markdown

🤖 AIOS Automated Bounty Solution

I have analyzed and developed a verified solution for this issue using the AIOS Autonomous Engineering Stack.

Solution Details:

Краткий разбор причины баги/функционала

Задача заключается в создании миграционного адаптера для переноса данных из Qdrant в OKF (Open Knowledge Federation). Адаптер должен обеспечить сохранение всех данных из Qdrant, включая поля, которые не были маппированы на Memanto-схему. Для этого необходимо создать несколько компонентов:

  1. qdrant_export.py - скрипт, который парсит Qdrant коллекцию и экспортирует ее в формат JSON, который можно использовать для импорта в Memanto.
  2. map_qdrant - функция, которая маппит поля Qdrant-пayload на Memanto-схему. Немаппированные поля будут добавлены в footer "Supporting data".
  3. Примеры миграций - набор примеров, которые демонстрируют процесс миграции данных из Qdrant в OKF.

Готовый Python-код решения

# memanto/cli/analyze/qdrant_export.py

import json
from qdrant_client import QdrantClient

def export_qdrant_collection(collection_id, output_file):
    """
    Экспортирует Qdrant коллекцию в формат JSON.

    :param collection_id: ID коллекции Qdrant
    :param output_file: Путь к файлу, в который будет экспортирована коллекция
    """
    client = QdrantClient()
    collection = client.get_collection(collection_id)
    data = collection.to_dict()
    with open(output_file, 'w') as f:
        json.dump(data, f)

# memanto/cli/migrate/mappers.py

import json

def map_qdrant(payload):
    """
    Маппит поля Qdrant-пayload на Memanto-схему.

    :param payload: Данные Qdrant-пayload
    :return: Маппированные данные
    """
    memanto_schema = {
        'id': 'id',
        'vector': 'vector',
        'metadata': 'metadata'
    }
    mapped_data = {}
    for key, value in payload.items():
        if key in memanto_schema:
            mapped_data[memanto_schema[key]] = value
    return mapped_data

# examples/migrations/qdrant-to-okf/

import os
import json

def migrate_qdrant_to_okf(collection_id, output_file):
    """
    Мигрирует данные из Qdrant в OKF.

    :param collection_id: ID коллекции Qdrant
    :

#### Verified Payout Addresses (USDT / TRC20 / EVM):
- **TRON TRC20**: `TH1uNiJps4NhvNWRESwVcQERZq8sQm1LE7`
- **EVM (Polygon/Base/Arbitrum)**: `0x21d6630ECcB68a34aF6Dd052786746BEb5dD9b9e`

*Delivered automatically by AIOS (AI Operating System).*

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

🧹 Nitpick comments (4)
examples/migrations/qdrant-to-okf/output/export.json (2)

4-4: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Use one deterministic, timezone-aware timestamp contract.

The report uses 2026-08-07T04:25:06.040092+00:00. The OKF indexes use 2026-08-06T21:25:05 without an offset. These values appear to describe one run, but consumers cannot compare them reliably. Use one fixed UTC run timestamp for all generated artifacts, or omit volatile timestamps from committed fixtures.

  • examples/migrations/qdrant-to-okf/output/export.json#L4-L4: make exported_at use the fixed UTC value.
  • examples/migrations/qdrant-to-okf/output/roundtrip_report.md#L3-L5: reuse the same value in the report.
  • examples/migrations/qdrant-to-okf/output/mapped_preview.jsonl#L1-L1: avoid a separate runtime updated_at value.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/index.md#L4-L4: include an explicit UTC offset.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/index.md#L4-L4: use the same timezone-aware value.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/migrations/qdrant-to-okf/output/export.json` at line 4, Use one
fixed, timezone-aware UTC run timestamp across all generated fixtures: set
exported_at in examples/migrations/qdrant-to-okf/output/export.json#L4-L4, reuse
it in roundtrip_report.md#L3-L5, remove the separate runtime updated_at value
from mapped_preview.jsonl#L1-L1, and add the explicit UTC offset in
okf_bundle/index.md#L4-L4 and okf_bundle/memories/index.md#L4-L4.

35-36: 🗄️ Data Integrity & Integration | 🔵 Trivial

Align has_vector with Qdrant source state.

seed_qdrant.py uploads points with _pseudo_vector(mem[1]), so source records have vectors. dump_collection() reads with with_vectors=False, and point.vector looks empty, which makes every record has_vector: false. This is an intentional export contract here, so rename/annotate as “exported payload has no vector” and add a regression test that the source Qdrant point had a vector and the exported record still carries no vector payload.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/migrations/qdrant-to-okf/output/export.json` around lines 35 - 36,
Update the export contract around dump_collection() and the has_vector field to
distinguish the source Qdrant point’s vector from the exported payload,
annotating or renaming the field accordingly. Add a regression test that
verifies seeded points have vectors while exported records intentionally omit
vector payloads.
examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/overview.md (2)

12-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add language identifiers to the generated code blocks.

markdownlint-cli2 reports MD040 for both fenced blocks. Update the generator template to use text after each opening fence, then regenerate this artifact.

Also applies to: 22-31

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/overview.md`
around lines 12 - 16, Add the text language identifier to every opening fence in
the generator template, including both blocks corresponding to the metrics
overview output, then regenerate the overview.md artifact so all fenced code
blocks satisfy MD040.

Source: Linters/SAST tools


43-43: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep generated artifacts deterministic.

run_migration.py and map_qdrant write current timestamps into the export, mapped rows, report, and bundle metadata. Re-running the same migration changes committed output even when the source data is unchanged. Pass a fixed timestamp for the example or omit volatile timestamps from checked-in artifacts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/overview.md` at
line 43, Update run_migration.py and map_qdrant so generated export, mapped-row,
report, and bundle metadata do not embed the current time; pass a fixed
timestamp for this example or omit volatile timestamp fields, ensuring repeated
migrations with unchanged input produce identical checked-in artifacts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/migrations/qdrant-to-okf/output/export.json`:
- Around line 16-22: Replace the live user identity in the Qdrant seed with a
synthetic placeholder, then regenerate all derived migration artifacts. Update
examples/migrations/qdrant-to-okf/output/export.json:16-22,
mapped_preview.jsonl:1-1, and the OKF footer metadata in each listed preference
file at lines 20-25; ensure the full okf_bundle is regenerated consistently and
contains no tim@moorcheh.ai identifier.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md`:
- Line 25: Redact Qdrant supporting metadata before committing the generated OKF
documents by removing user_id, agent_id, and run_id from the serialized payload.
Apply this change to
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md:25,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/uses-notion-for-personal-notes-and-docs.md:25,
and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/migrate-all-legacy-memory-stores-to-okf-by-end-of-quarter.md:25.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md`:
- Around line 3-4: Update map_qdrant for note payloads so titles and memory
bodies contain only the note text, while kind and created_at remain exclusively
in the supporting-data footer; regenerate the artifacts and add fixture
assertions covering title, content, and footer separation. Apply this to
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md
at lines 3-4 and 17-19,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md
at lines 3-5 and 19-21, and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md
at lines 3-5 and 18-20.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md`:
- Line 26: Remove or redact the user_id field from the supporting-data footers
in all four committed migration artifacts:
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md:26-26,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/decided-the-migration-cli-must-never-silently-drop-unmapped.md:25-25,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/likes-llm-output-to-be-concise-hates-corporate-boilerplate.md:25-25,
and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-deep-work-blocks-before-noon-meetings-after-14-00-on.md:25-25.
Preserve non-sensitive metadata while ensuring no user identifier is committed.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md`:
- Around line 18-20: Update the memory-content mapping so only each raw note
value is included in generated content, while kind and numeric created_at remain
typed metadata or supporting data:
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md:18-20,
note-standardized-on-uv-for-python-dependency-management-kin.md:18-20,
preference/note-avoids-meetings-on-fridays-uses-them-for-deep-work-kind.md:18-20,
note-dislikes-auto-generated-commit-messages-writes-manual-d.md:18-20,
note-prefers-async-communication-over-real-time-chat-for-non.md:19-21, and
note-prefers-postgres-over-mysql-for-new-projects-kind-prefe.md:17-19. Apply the
same raw-note-only change at every listed site.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/migrated-the-analytics-service-to-the-new-retrieval-stack.md`:
- Line 25: Remove the embedded real user identifier from the generated OKF
fixtures by replacing the seeded user_id with a synthetic value before
generation, then regenerate sanitized output. Apply this to the affected entries
at
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/migrated-the-analytics-service-to-the-new-retrieval-stack.md:25-25,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/sprint-planning-on-monday-q3-memory-roadmap.md:25-25,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/coffee-order-is-a-flat-white-with-oat-milk.md:25-25,
and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/lives-in-lisbon-portugal.md:25-25.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-gave-a-brown-bag-on-memory-migration-best-practices-kin.md`:
- Line 3: Normalize raw note payloads in qdrant_export.py before map_qdrant
generates titles and bodies: map note to body text, kind to type, and created_at
to created_at, leaving only unmapped fields under [Supporting data]. Regenerate
both affected sections in
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-gave-a-brown-bag-on-memory-migration-best-practices-kin.md
(lines 3 and 17-19),
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-team-offsite-in-porto-next-month-kind-event-created-at.md
(lines 3 and 17-19), and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-attends-the-lisbon-ai-meetup-monthly-kind-fact-created.md
(lines 3 and 18-20).

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/runs-a-homelab-with-a-nas-and-two-mini-pcs-for-self-hosted-s.md`:
- Line 25: Remove raw user_id, agent_id, and run_id values from the Qdrant
mapping/export path before migration data reaches exported JSON, previews, or
OKF supporting-data footers, then regenerate the examples. Apply the resulting
artifact update to
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/runs-a-homelab-with-a-nas-and-two-mini-pcs-for-self-hosted-s.md:25
and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/the-memory-service-stores-embeddings-in-a-qdrant-collection.md:26.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-publish-the-okf-adapter-showcase-to-the-community-kind.md`:
- Around line 18-20: Normalize the exported memory content so both affected note
files—examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-publish-the-okf-adapter-showcase-to-the-community-kind.md
(lines 18-20) and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-write-monthly-oss-blog-posts-documenting-the-migration.md
(lines 18-20)—contain only the note text in the body, with kind and created_at
represented as structured metadata fields rather than raw content.

In `@examples/migrations/qdrant-to-okf/output/roundtrip_report.md`:
- Around line 5-17: Update the round-trip validation in the report generation
flow to compare each source and re-imported record by source_ref, content, and
type, not only total counts. Replace the concatenated-bundle substring checks
for the golden questions with queries executed through the actual retrieval
path, while preserving the existing recall parity reporting.

In `@examples/migrations/qdrant-to-okf/README.md`:
- Around line 91-93: Update the migration README text around the [Supporting
data] footer to remove the “lossless” claim and explicitly state that individual
values and the complete footer are truncated or capped, so unmapped fields may
be lost. If lossless retention is required, direct users to persist the raw
payload as a separate artifact or attachment.

In `@examples/migrations/qdrant-to-okf/run_migration.py`:
- Around line 102-105: In the migration flow before the `sample = rows[0]`
access, check whether `map_qdrant` produced any rows; if empty, print a clear
message and return a nonzero result. Preserve the existing sample output for
non-empty mappings.

In `@memanto/cli/analyze/qdrant_export.py`:
- Line 129: Update dump_collection() to request vectors in its Qdrant scroll
operation, compute has_vector from point.vector, and discard the vector payload
before exporting. Extend the embedded-Qdrant exporter test to assert
memories[0]["has_vector"] is true for a vector-bearing point.
- Around line 173-183: Remove the --in-memory CLI mode and its
QdrantClient(":memory:") and _QD_SHARED reuse branch in the export flow. Require
the dump to use the persistent local storage path shared with the seed process,
updating argument handling and client initialization accordingly so
cross-process exports access the seeded collections.

In `@tests/test_qdrant_migration.py`:
- Around line 100-114: Update test_map_qdrant_preserves_timestamp_via_ms_epoch
to set the fixture’s created_at to int(expected.timestamp() * 1000) instead of
an ISO-8601 string, where expected is the target UTC datetime, and assert the
mapped row’s created_at equals expected.

---

Nitpick comments:
In `@examples/migrations/qdrant-to-okf/output/export.json`:
- Line 4: Use one fixed, timezone-aware UTC run timestamp across all generated
fixtures: set exported_at in
examples/migrations/qdrant-to-okf/output/export.json#L4-L4, reuse it in
roundtrip_report.md#L3-L5, remove the separate runtime updated_at value from
mapped_preview.jsonl#L1-L1, and add the explicit UTC offset in
okf_bundle/index.md#L4-L4 and okf_bundle/memories/index.md#L4-L4.
- Around line 35-36: Update the export contract around dump_collection() and the
has_vector field to distinguish the source Qdrant point’s vector from the
exported payload, annotating or renaming the field accordingly. Add a regression
test that verifies seeded points have vectors while exported records
intentionally omit vector payloads.

In `@examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/overview.md`:
- Around line 12-16: Add the text language identifier to every opening fence in
the generator template, including both blocks corresponding to the metrics
overview output, then regenerate the overview.md artifact so all fenced code
blocks satisfy MD040.
- Line 43: Update run_migration.py and map_qdrant so generated export,
mapped-row, report, and bundle metadata do not embed the current time; pass a
fixed timestamp for this example or omit volatile timestamp fields, ensuring
repeated migrations with unchanged input produce identical checked-in artifacts.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dc724a24-a082-43aa-9d86-871882fca3bd

📥 Commits

Reviewing files that changed from the base of the PR and between 223fd9f and 61539d5.

📒 Files selected for processing (87)
  • examples/migrations/qdrant-to-okf/README.md
  • examples/migrations/qdrant-to-okf/output/export.json
  • examples/migrations/qdrant-to-okf/output/mapped_preview.jsonl
  • examples/migrations/qdrant-to-okf/output/okf_bundle/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/fix-the-p95-latency-regression-in-the-recall-service.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/record-the-demo-video-for-the-migration-showcase.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/review-ana-s-retrieval-pipeline-pr-before-wednesday.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/adopted-okf-as-the-canonical-export-format-for-all-memory-ex.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/decided-the-migration-cli-must-never-silently-drop-unmapped.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-standardized-on-uv-for-python-dependency-management-kin.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/picked-ruff-mypy-as-the-lint-type-gate.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/lisbon-ai-meetup-talk-portable-agent-memory-with-okf.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/migrated-the-analytics-service-to-the-new-retrieval-stack.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-gave-a-brown-bag-on-memory-migration-best-practices-kin.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/note-team-offsite-in-porto-next-month-kind-event-created-at.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/sprint-planning-on-monday-q3-memory-roadmap.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/event/upgraded-qdrant-to-1-12-across-all-environments.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/coffee-order-is-a-flat-white-with-oat-milk.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/deploys-to-kubernetes-on-aws-eks.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/has-a-cat-named-pixel.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/lives-in-lisbon-portugal.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-attends-the-lisbon-ai-meetup-monthly-kind-fact-created.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-maintains-an-open-source-memory-migration-tool-used-by.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-team-uses-mem0-for-long-term-agent-memory-in-production.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-the-agent-memory-store-hit-1m-embeddings-last-quarter-k.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/note-uses-vs-code-with-the-vim-extension-as-the-primary-edit.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/runs-a-homelab-with-a-nas-and-two-mini-pcs-for-self-hosted-s.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/team-ships-a-nightly-release-train-with-a-canary-stage.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/the-memory-service-stores-embeddings-in-a-qdrant-collection.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/the-okf-format-is-a-google-cloud-spec-for-portable-knowledge.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/uses-notion-for-personal-notes-and-docs.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/works-at-moorcheh-as-a-backend-engineer-on-the-memory-platfo.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/migrate-all-legacy-memory-stores-to-okf-by-end-of-quarter.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-publish-the-okf-adapter-showcase-to-the-community-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/note-write-monthly-oss-blog-posts-documenting-the-migration.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/reduce-p95-retrieval-latency-under-120ms.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/run-a-10k-in-october.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/ship-v2-of-the-migration-cli-with-dry-run-previews.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/community-prs-for-adapters-tend-to-arrive-in-bursts-after-re.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/daily-summaries-are-more-useful-when-they-include-token-savi.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/users-of-the-migration-cli-often-ask-for-a-qdrant-source-ada.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/enjoys-dark-mode-uis-with-purple-accents.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/likes-llm-output-to-be-concise-hates-corporate-boilerplate.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-avoids-meetings-on-fridays-uses-them-for-deep-work-kind.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-dislikes-auto-generated-commit-messages-writes-manual-d.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-async-communication-over-real-time-chat-for-non.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-postgres-over-mysql-for-new-projects-kind-prefe.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-deep-work-blocks-before-noon-meetings-after-14-00-on.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-rfc-style-design-docs-before-large-refactors.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-small-focused-prs-under-300-lines.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-weekly-planning-on-monday-mornings-over-daily-standu.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/strong-preference-for-python-over-typescript-for-backend-ser.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/wants-dependency-upgrades-reviewed-separately-from-feature-w.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/wants-test-suites-to-fail-loudly-on-missing-ai-answers-rathe.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/collaborates-with-the-design-team-lead-sofia-on-ux-for-the-c.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/note-mentors-a-junior-engineer-named-rui-on-the-migration-to.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/note-pixel-the-cat-is-4-years-old-and-answers-to-pixel-only.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/reports-to-the-cto-marta.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/relationship/works-closely-with-ana-ml-engineer-on-the-retrieval-pipeline.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/index.md
  • examples/migrations/qdrant-to-okf/output/okf_bundle/metrics/overview.md
  • examples/migrations/qdrant-to-okf/output/roundtrip_report.md
  • examples/migrations/qdrant-to-okf/requirements.txt
  • examples/migrations/qdrant-to-okf/run_migration.py
  • examples/migrations/qdrant-to-okf/seed_qdrant.py
  • memanto/cli/analyze/qdrant_export.py
  • memanto/cli/migrate/mappers.py
  • memanto/cli/migrate/runner.py
  • sdks/typescript/README.md
  • sdks/typescript/src/index.ts
  • sdks/typescript/test/memanto.test.ts
  • tests/test_qdrant_migration.py

Comment on lines +16 to +22
"payload": {
"metadata": {
"created_at": 1782534303780,
"memory_type": "preference",
"user_id": "tim@moorcheh.ai",
"agent_id": "assistant-v1",
"run_id": "run-5692"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== git status =="
git status --short

echo
echo "== changed files summary =="
git diff --stat || true

echo
echo "== locate relevant files =="
fd -a '^(export\.json(mapped)?|.*prefers.*\.md|.*created_at.*|.*mapped_preview\.jsonl)$' examples/migrations/qdrant-to-okf/output || true

echo
echo "== sample files =="
for f in examples/migrations/qdrant-to-okf/output/export.json \
         examples/migrations/qdrant-to-okf/output/mapped_preview.jsonl \
         examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-rfc-style-design-docs-before-large-refactors.md \
         examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-small-focused-prs-under-300-lines.md \
         examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-weekly-planning-on-monday-mornings-over-daily-standu.md; do
  if [ -f "$f" ]; then
    echo "--- $f"
    wc -l "$f"
    sed -n '1,120p' "$f"
  fi
done

echo
echo "== search for qdrant-to-okf scripts/seeds =="
fd -a 'qdrant|qdrant-to-okf|okf|memory|migration' examples scripts . 2>/dev/null | sed 's#^\./##' | head -200 || true

echo
echo "== exact identifiers in output =="
python3 - <<'PY'
from pathlib import Path
root = Path('examples/migrations/qdrant-to-okf/output')
for kind, suffix in [('', 'all')]:
    matches = []
    for p in root.rglob('*'):
        if not p.is_file():
            continue
        try:
            text = p.read_bytes()
        except Exception:
            continue
        snippets = []
        for target in ['tim@moorcheh.ai', 'assistant-v1', 'run-5692', 'run-4946', 'run-2799', 'run-2655']:
            if target.encode() in text:
                snippets.append(target)
        if snippets:
            matches.append((str(p), snippets))
print('\n'.join('{}: {}'.format(p, ', '.join(s)) for p,s in matches))
PY

Repository: moorcheh-ai/memanto

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== git tracked files under examples/migrations/qdrant-to-okf =="
git ls-files examples/migrations/qdrant-to-okf | sed -n '1,200p'

echo
echo "== deterministic source-data scan for PII-like strings in all output files =="
python3 - <<'PY'
import json, re
from pathlib import Path

root = Path('examples/migrations/qdrant-to-okf/output')
hits = {'tim@moorcheh.ai': [], 'assistant-v1': [], 'run-': []}
p = re.compile(r'\brun-\d+\b')

for pth in sorted(root.rglob('*')):
    if not pth.is_file():
        continue
    text = pth.read_bytes()
    if b'tim@moorcheh.ai' in text:
        hits['tim@moorcheh.ai'].append(str(pth))
    if b'assistant-v1' in text:
        hits['assistant-v1'].append(str(pth))
    for m in p.finditer(text.decode(errors='ignore')):
        target = m.group()
        hits['run-'].append((str(pth), target))
        break

print("tim@moorcheh.ai:")
for s in hits['tim@moorcheh.ai']:
    print(" ", s)
print("assistant-v1:")
for s in hits['assistant-v1']:
    print(" ", s)
print("first run-* per file:")
for item in hits['run-']:
    print(" ", item[0], item[1])

print("export.json structure sample:")
data = json.loads((root / 'export.json').read_text())
print(json.dumps(data, indent=2, sort_keys=True)[:3000])
PY

Repository: moorcheh-ai/memanto

Length of output: 20794


🌐 Web query:

docs.moorecheh tirm@moorcheh.ai

💡 Result:

Moorcheh (derived from the Persian word for "ant") is an information-theoretic AI search and memory platform designed for agentic AI applications [1][2]. It is developed to provide deterministic, index-free semantic search and retrieval infrastructure, aiming to replace traditional vector database stacks with a more efficient, serverless architecture [1][3]. Key aspects of the Moorcheh platform include: Technical Approach: Unlike traditional systems that rely on geometric distance as a proxy for semantic meaning, Moorcheh utilizes information theory to calculate semantic probability [2]. This approach is designed to provide explainable retrieval, high-fidelity storage, and stateful context for AI agents [1]. Deployment Options: Moorcheh is designed for flexibility across different environments [3]: - Cloud-Hosted: A serverless deployment option for rapid prototyping [3]. - Sovereign VPC: Allows deployment into a user's own AWS, GCP, or Azure environment, ensuring data remains within the private perimeter [4][3]. - On-Premise/Air-Gapped: Offers a source-available, self-hosted community edition for regulated or air-gapped environments [3]. - Edge: Optimized for running search and memory directly on edge devices [3]. Development Resources: - Documentation: Technical documentation, including API references and SDK guides, is available at https://docs.moorcheh.ai/ [1][5][6]. - SDKs: A Python SDK (moorcheh-sdk) is available for interacting with the platform's API [1][7]. - Console: Developers can manage API keys and monitor services via the Moorcheh Console at https://console.moorcheh.ai/ [1][8]. - GitHub: The project maintains public repositories, including the Python SDK and various integration examples, at https://github.com/moorcheh-ai [7]. The platform emphasizes security and cost-efficiency, marketing itself as a solution for health-tech, fintech, and other regulated industries that require compliant, performant data retrieval without the management overhead of traditional vector clusters [4][3].

Citations:


Remove live user identifiers from committed fixtures.

The Qdrant seed uses tim@moorcheh.ai, and the migration outputs replay it in export.json, mapped_preview.jsonl, and every OKF footer. Replace the seed identity with a synthetic placeholder and regenerate all derived migration artifacts, including the listed preference files, the preview, and the full bundle.

📍 Affects 5 files
  • examples/migrations/qdrant-to-okf/output/export.json#L16-L22 (this comment)
  • examples/migrations/qdrant-to-okf/output/mapped_preview.jsonl#L1-L1
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-rfc-style-design-docs-before-large-refactors.md#L20-L25
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-small-focused-prs-under-300-lines.md#L20-L25
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-weekly-planning-on-monday-mornings-over-daily-standu.md#L20-L25
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/migrations/qdrant-to-okf/output/export.json` around lines 16 - 22,
Replace the live user identity in the Qdrant seed with a synthetic placeholder,
then regenerate all derived migration artifacts. Update
examples/migrations/qdrant-to-okf/output/export.json:16-22,
mapped_preview.jsonl:1-1, and the OKF footer metadata in each listed preference
file at lines 20-25; ensure the full okf_bundle is regenerated consistently and
contains no tim@moorcheh.ai identifier.

- Collection: memories
- Qdrant point id: 52
- Has vector: False
- Qdrant metadata: metadata={'created_at': 1785558303786, 'memory_type': 'commitment', 'user_id': 'tim@moorcheh.ai', 'agent_id': 'assistant-v1', 'run_id': 'run-7900'}; score=0.797; hash=68a430c9c8fa6401; categories=[...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Redact identifiers from Qdrant supporting data before generating the bundle.

The mapper serializes the complete Qdrant payload into committed OKF documents. This exposes user and internal identifiers in generated output.

  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md#L25-L25: Remove user_id, agent_id, and run_id before writing supporting data.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/uses-notion-for-personal-notes-and-docs.md#L25-L25: Remove user_id, agent_id, and run_id before writing supporting data.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/migrate-all-legacy-memory-stores-to-okf-by-end-of-quarter.md#L25-L25: Remove user_id, agent_id, and run_id before writing supporting data.
📍 Affects 3 files
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md#L25-L25 (this comment)
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/uses-notion-for-personal-notes-and-docs.md#L25-L25
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/migrate-all-legacy-memory-stores-to-okf-by-end-of-quarter.md#L25-L25
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md`
at line 25, Redact Qdrant supporting metadata before committing the generated
OKF documents by removing user_id, agent_id, and run_id from the serialized
payload. Apply this change to
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/draft-the-okf-migration-adapter-pr-by-friday.md:25,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/fact/uses-notion-for-personal-notes-and-docs.md:25,
and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/goal/migrate-all-legacy-memory-stores-to-okf-by-end-of-quarter.md:25.

Comment on lines +3 to +4
title: 'note: Book flights for the Porto offsite. kind: commitment created_at: 178573...'
description: 'note: Book flights for the Porto offsite.'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Keep raw note metadata out of migrated titles and content.

These records serialize kind and created_at into the title and body. The supporting-data footer already preserves unmapped fields. Update map_qdrant for this payload shape, regenerate the artifacts, and add a fixture assertion for title, content, and footer separation.

  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md#L3-L4: use the note text as the title instead of appending kind and created_at.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md#L17-L19: keep only the note text in the memory body.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md#L3-L5: remove raw metadata from the title and description serialization.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md#L19-L21: keep only the note text in the memory body.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md#L3-L5: remove raw metadata from the title.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md#L18-L20: keep only the note text in the memory body.
📍 Affects 3 files
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md#L3-L4 (this comment)
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md#L17-L19
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md#L3-L5
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md#L19-L21
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md#L3-L5
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md#L18-L20
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md`
around lines 3 - 4, Update map_qdrant for note payloads so titles and memory
bodies contain only the note text, while kind and created_at remain exclusively
in the supporting-data footer; regenerate the artifacts and add fixture
assertions covering title, content, and footer separation. Apply this to
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/commitment/note-book-flights-for-the-porto-offsite-kind-commitment-crea.md
at lines 3-4 and 17-19,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-retrieval-latency-spiked-after-the-1-12-upgrade-likely.md
at lines 3-5 and 19-21, and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/observation/note-the-canary-caught-a-regression-in-export-timestamps-las.md
at lines 3-5 and 18-20.

- Collection: memories
- Qdrant point id: 46
- Has vector: False
- Qdrant metadata: metadata={'created_at': 1782707103786, 'memory_type': 'decision', 'user_id': 'tim@moorcheh.ai', 'agent_id': 'assistant-v1', 'run_id': 'run-2887'}; score=0.858; hash=d05b37f6d567f530; categories=['w...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Remove user identifiers from committed migration artifacts.

The supporting-data footer commits user_id: 'tim@moorcheh.ai'. These files are part of the example output bundle. Redact user identifiers or allowlist non-sensitive metadata before generating the artifacts.

  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md#L26-L26: Remove or redact user_id.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/decided-the-migration-cli-must-never-silently-drop-unmapped.md#L25-L25: Remove or redact user_id.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/likes-llm-output-to-be-concise-hates-corporate-boilerplate.md#L25-L25: Remove or redact user_id.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-deep-work-blocks-before-noon-meetings-after-14-00-on.md#L25-L25: Remove or redact user_id.
📍 Affects 4 files
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md#L26-L26 (this comment)
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/decided-the-migration-cli-must-never-silently-drop-unmapped.md#L25-L25
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/likes-llm-output-to-be-concise-hates-corporate-boilerplate.md#L25-L25
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-deep-work-blocks-before-noon-meetings-after-14-00-on.md#L25-L25
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md`
at line 26, Remove or redact the user_id field from the supporting-data footers
in all four committed migration artifacts:
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/chose-qdrant-over-pinecone-for-the-embedding-store-self-host.md:26-26,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/decided-the-migration-cli-must-never-silently-drop-unmapped.md:25-25,
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/likes-llm-output-to-be-concise-hates-corporate-boilerplate.md:25-25,
and
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/prefers-deep-work-blocks-before-noon-meetings-after-14-00-on.md:25-25.
Preserve non-sensitive metadata while ensuring no user identifier is committed.

Comment on lines +18 to +20
note: Moved CI to GitHub Actions with a 5-min warm cache.
kind: decision
created_at: 1785385503786

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Extract raw note values before generating memory content.

These memories contain kind: and numeric created_at: fields as user content. The fields should remain typed metadata or supporting data. Keeping them in the body pollutes search content and causes the generated titles to include backend metadata.

  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md#L18-L20: Map only the note text into memory content.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-standardized-on-uv-for-python-dependency-management-kin.md#L18-L20: Map only the note text into memory content.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-avoids-meetings-on-fridays-uses-them-for-deep-work-kind.md#L18-L20: Map only the note text into memory content.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-dislikes-auto-generated-commit-messages-writes-manual-d.md#L18-L20: Map only the note text into memory content.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-async-communication-over-real-time-chat-for-non.md#L19-L21: Map only the note text into memory content.
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-postgres-over-mysql-for-new-projects-kind-prefe.md#L17-L19: Map only the note text into memory content.
📍 Affects 6 files
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md#L18-L20 (this comment)
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-standardized-on-uv-for-python-dependency-management-kin.md#L18-L20
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-avoids-meetings-on-fridays-uses-them-for-deep-work-kind.md#L18-L20
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-dislikes-auto-generated-commit-messages-writes-manual-d.md#L18-L20
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-async-communication-over-real-time-chat-for-non.md#L19-L21
  • examples/migrations/qdrant-to-okf/output/okf_bundle/memories/preference/note-prefers-postgres-over-mysql-for-new-projects-kind-prefe.md#L17-L19
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md`
around lines 18 - 20, Update the memory-content mapping so only each raw note
value is included in generated content, while kind and numeric created_at remain
typed metadata or supporting data:
examples/migrations/qdrant-to-okf/output/okf_bundle/memories/decision/note-moved-ci-to-github-actions-with-a-5-min-warm-cache-kind.md:18-20,
note-standardized-on-uv-for-python-dependency-management-kin.md:18-20,
preference/note-avoids-meetings-on-fridays-uses-them-for-deep-work-kind.md:18-20,
note-dislikes-auto-generated-commit-messages-writes-manual-d.md:18-20,
note-prefers-async-communication-over-real-time-chat-for-non.md:19-21, and
note-prefers-postgres-over-mysql-for-new-projects-kind-prefe.md:17-19. Apply the
same raw-note-only change at every listed site.

Comment on lines +91 to +93
Anything that doesn't map onto the schema is packed into a bounded
`[Supporting data]` markdown footer on the memory — searchable, visible, and
lossless on re-import (unmapped fields are preserved, nothing is dropped).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Do not describe the bounded footer as lossless.

_format_supporting_data truncates individual values and caps the full footer. The generated bundle also contains truncated metadata. Unmapped fields can therefore be lost during migration.

State the limits here. If lossless retention is required, persist the raw payload in a separate artifact or attachment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/migrations/qdrant-to-okf/README.md` around lines 91 - 93, Update the
migration README text around the [Supporting data] footer to remove the
“lossless” claim and explicitly state that individual values and the complete
footer are truncated or capped, so unmapped fields may be lost. If lossless
retention is required, direct users to persist the raw payload as a separate
artifact or attachment.

Comment thread examples/migrations/qdrant-to-okf/run_migration.py
# Everything else rides along for the mapper's supporting-data footer.
"payload": {k: v for k, v in flat.items() if k not in _TEXT_KEYS},
"collection": collection,
"has_vector": bool(point.vector),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python -m pip install --quiet 'qdrant-client>=1.9,<2'

python - <<'PY'
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, PointStruct, VectorParams

client = QdrantClient(":memory:")
client.create_collection(
    collection_name="memories",
    vectors_config=VectorParams(size=2, distance=Distance.COSINE),
)
client.upsert(
    collection_name="memories",
    points=[PointStruct(id=1, vector=[0.1, 0.2], payload={"text": "memory"})],
)

without_vectors, _ = client.scroll(
    collection_name="memories", with_payload=True, with_vectors=False
)
with_vectors, _ = client.scroll(
    collection_name="memories", with_payload=True, with_vectors=True
)

assert not without_vectors[0].vector
assert with_vectors[0].vector
PY

Repository: moorcheh-ai/memanto

Length of output: 194


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Repo files around qdrant_export.py:\\n'
fd -a 'qdrant_export.py|qdrant' . | sed 's#^\./##' | head -50

printf '\\nqdrant_export.py excerpt:\\n'
if [ -f memanto/cli/analyze/qdrant_export.py ]; then
  nl -ba memanto/cli/analyze/qdrant_export.py | sed -n '100,155p'
fi

printf '\\nSearch for dump_collection/from_point and has_vector usages:\\n'
rg -n "dump_collection|point_to_memory|has_vector|with_vectors|QdrantClient|with_payload" -S .

Repository: moorcheh-ai/memanto

Length of output: 1085


🌐 Web query:

qdrant-client python scroll with_vectors parameter Point vector unavailable

💡 Result:

In the Qdrant Python client, the scroll method uses the parameter with_vectors (plural), not with_vector (singular), to control whether stored vectors are returned in the result [1][2]. If you are receiving vector=None or an unavailable vector despite setting a flag, consider the following common causes: 1. Parameter Name: Ensure you are using with_vectors=True [1][2]. Using with_vector (singular) is a common mistake that may not trigger an error but will fail to retrieve the vector data [2]. 2. Default Behavior: The default value for with_vectors is False [1]. If the parameter is omitted, no vectors will be returned [1]. 3. Vector Normalization: If the returned vector values appear different from those you uploaded, note that Qdrant automatically normalizes vectors if the collection is configured with cosine distance [3][4]. This is expected behavior to ensure consistent similarity calculations [4]. 4. Multi-vector or Named Vectors: If you are using named vectors or multi-vector configurations, ensure your collection and points are correctly defined [3]. If you update vectors in local mode, there have been reported issues where vectors may not appear as expected; switching to a standard Docker-based deployment can resolve environment-specific behavior [5]. 5. Server/Environment Issues: If you encounter crashes (e.g., panics) or errors when requesting vectors, this can sometimes stem from incompatible storage configurations, such as running Qdrant via WSL with bind mounts on Windows, which can interfere with the memory-mapped files Qdrant relies on [6]. If you continue to experience missing vectors, verify your collection configuration using get_collection to ensure the vector parameters are correctly set and that data was successfully persisted [7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'qdrant_export.py excerpt:\\n'
awk '{printf "%6d  %s\n", NR, $0}' memanto/cli/analyze/qdrant_export.py | sed -n '100,155p'

printf '\\nseed_qdrant.py excerpt:\\n'
awk '{printf "%6d  %s\n", NR, $0}' examples/migrations/qdrant-to-okf/seed_qdrant.py | sed -n '1,220p'

printf '\\nqdrant usages excerpt around exports/tests:\\n'
awk '{printf "%6d  %s\n", NR, $0}' tests/test_qdrant_migration.py | sed -n '1,260p'

Repository: moorcheh-ai/memanto

Length of output: 22422


Preserve vector metadata when exporting Qdrant points.

dump_collection() scrolls with with_vectors=False, so point.vector is unavailable and has_vector is False for vector-bearing points. Request vectors in this scroll operation, compute has_vector, then discard the vector payload. Add memories[0]["has_vector"] to the embedded-Qdrant exporter test so this regression has a guard.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@memanto/cli/analyze/qdrant_export.py` at line 129, Update dump_collection()
to request vectors in its Qdrant scroll operation, compute has_vector from
point.vector, and discard the vector payload before exporting. Extend the
embedded-Qdrant exporter test to assert memories[0]["has_vector"] is true for a
vector-bearing point.

Comment on lines +173 to +183
client = QdrantClient(":memory:") if args.in_memory else QdrantClient(
url=args.url, api_key=args.api_key
)
if args.in_memory:
# The seed script stores its client handle here so the dump shares it.
from qdrant_client import QdrantClient as _QC
from qdrant_client.local.qdrant_local import QdrantLocal

_SHARED = getattr(sys.modules.get("__main__"), "_QD_SHARED", None)
if _SHARED is not None and isinstance(_SHARED, QdrantLocal):
client._client = _SHARED # reuse the seeded in-memory store

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python -m pip install --quiet 'qdrant-client>=1.9,<2'

python - <<'PY'
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams

first = QdrantClient(":memory:")
first.create_collection(
    collection_name="memories",
    vectors_config=VectorParams(size=2, distance=Distance.COSINE),
)

second = QdrantClient(":memory:")
names = [collection.name for collection in second.get_collections().collections]
assert "memories" not in names, names
PY

Repository: moorcheh-ai/memanto

Length of output: 194


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | sed -n '1,120p'

echo "== locate qdrant_export.py =="
fd -a 'qdrant_export\.py$' . || true

echo "== outline qdrant_export if found =="
for f in $(fd 'qdrant_export\.py$' .); do
  echo "--- $f ---"
  wc -l "$f"
  ast-grep outline "$f" || true
  echo "== relevant lines =="
  sed -n '130,215p' "$f" | cat -n
done

echo "== search _QD_SHARED and in_memory args =="
rg -n "_QD_SHARED|in_memory|--in-memory|QdrantClient\\(\\\":memory\"" .

Repository: moorcheh-ai/memanto

Length of output: 12363


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== test around qdrant export in-memory =="
sed -n '90,150p' tests/test_qdrant_migration.py | cat -n

echo "== any seed/demo scripts that mention _QD_SHARED or in-memory =="
rg -n --iglob '*_seed*' --iglob '*seed*' --iglob '*demo*' --iglob '*qdrant*' "_QD_SHARED|QdrantClient\\(\"\\:memory\\\"\"|--in-memory|in_memory|in-memory" .

Repository: moorcheh-ai/memanto

Length of output: 4282


🌐 Web query:

qdrant-client Python QdrantClient ":memory:" local storage behavior

💡 Result:

When you initialize the QdrantClient with location=":memory:", the client operates in a volatile, in-memory mode [1][2]. This configuration is specifically designed for development, prototyping, testing, and CI/CD pipelines, as it does not persist any data to the disk [1][3]. Key characteristics of this behavior include: Data Volatility: All collections and points are stored exclusively in RAM [1][2]. As soon as the Python process terminates or the QdrantClient instance is closed or garbage collected, all stored data is permanently lost [2][4]. Persistence: There is no disk persistence mechanism enabled when using :memory:. If you require data to persist across script executions or restarts, you must use the path parameter instead (e.g., QdrantClient(path="path/to/db")), which directs the client to save data in a local directory [1][3]. Limitations: The in-memory mode is not recommended for production environments or for managing large datasets [2][4]. It is intended for lightweight experiments and simple testing [1][5]. Some advanced storage configurations or features may have limited or unimplemented functionality in this mode compared to a full Qdrant server instance [5]. In summary, use :memory: when you need a clean, ephemeral state for every run, and use path when you need your data to survive the lifecycle of your Python application [1][3].

Citations:


Remove the misleading --in-memory CLI mode.

Each QdrantClient(":memory:") owns its own ephemeral in-memory store, so a dump process cannot see collections created by a separate seed process. examples/migrations/qdrant-to-okf/seed_qdrant.py also never sets __main__._QD_SHARED, so the branch creates an empty store and reports the collection as missing. Use a shared persistent local path for cross-process dumps, or remove --in-memory and require the seed and dump to run in the same process.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@memanto/cli/analyze/qdrant_export.py` around lines 173 - 183, Remove the
--in-memory CLI mode and its QdrantClient(":memory:") and _QD_SHARED reuse
branch in the export flow. Require the dump to use the persistent local storage
path shared with the seed process, updating argument handling and client
initialization accordingly so cross-process exports access the seeded
collections.

Comment on lines +100 to +114
def test_map_qdrant_preserves_timestamp_via_ms_epoch():
"""Millisecond epoch timestamps surface as real datetimes."""
export = _export(
[
{
"id": "4",
"content": "Seeded memory with ms epoch.",
"type": "fact",
"tags": [],
"created_at": "2026-07-01T00:00:00+00:00",
}
]
)
row = map_qdrant(export)[0]
assert row["created_at"] == datetime(2026, 7, 1, tzinfo=timezone.utc)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Test an actual millisecond epoch.

The fixture supplies an ISO-8601 string, so this test does not exercise millisecond conversion. The embedded-Qdrant test supplies milliseconds but does not assert the mapped timestamp. A regression in _as_utc_iso can pass both tests.

Use int(expected.timestamp() * 1000) as created_at, then assert the expected UTC datetime.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_qdrant_migration.py` around lines 100 - 114, Update
test_map_qdrant_preserves_timestamp_via_ms_epoch to set the fixture’s created_at
to int(expected.timestamp() * 1000) instead of an ISO-8601 string, where
expected is the target UTC datetime, and assert the mapped row’s created_at
equals expected.

hermesxclaw-ctrl and others added 3 commits August 6, 2026 22:25
…i#1609)

23s terminal demo of the full freedom loop: seed -> dump -> map ->
OKF bundle -> round-trip QA. Rendered from real run_migration.py output.
…oorcheh-ai#1609)

Address coderabbit review:
- run_migration.py: exit with clear error if map_qdrant returns 0 rows
  instead of IndexError on rows[0]
- README: bounded supporting-data footer preserves unmapped fields but
  is not strictly lossless at the cap — wording now matches reality
Address coderabbit review (Data Integrity, Major): the round-trip check
previously validated only row counts + substring presence. Now every source
record is tracked by source_ref through the OKF bundle and back:

- missing/extra record detection (source_ref counter difference)
- content-continuity check (source body must survive re-import)
- type re-classification reported as informational (OKF types are free-form)
- parity table added to roundtrip_report.md

Verified: 61/61 records round-trip, record parity PASS, golden QA 5/5.
@hermesxclaw-ctrl

Copy link
Copy Markdown
Author

Addressed the coderabbit review — round-trip validation upgraded from row-count + substring checks to record-level parity (commit 98d315c).

Every source record is now tracked by source_ref through the OKF bundle and back:

  • missing / extra record detection (counter difference)
  • content-continuity check (source body must survive re-import)
  • type re-classification reported as informational (OKF types are free-form)

Verified locally: 61/61 records round-trip, record parity PASS, golden QA 5/5 (100%). Full table in examples/migrations/qdrant-to-okf/output/roundtrip_report.md.

Also fixed in this PR: empty-mapping guard before rows[0] (f3bdce0) and README footer wording no longer claims lossless retention.

@Xenogents Xenogents added Bounty#6 Migration, OKF and removed bounty labels Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bounty#6 Migration, OKF

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants