# Pipeline mechanics Full step-by-step for `mem0-integrate`. Read this when you are executing a step. The one-line-per-step overview and every non-negotiable rule live in `../SKILL.md`, which is loaded on every run; this file is loaded on demand. Verbatim subagent system prompts for steps 8 and 10 are in [`subagent-prompts.md`](subagent-prompts.md). ## 1. Language detection | Signal | Track | |---|---| | `package.json` + TypeScript config | Node / TypeScript | | `package.json` (no TS config) | Node / JavaScript | | `pyproject.toml` or `requirements.txt` | Python | Monorepo with both, ask which subdirectory to operate in, then recurse. ## 2. Repo comprehension: what does this repo do, and where is the backend? Before any decision (product, goal, plan), understand the repo enough to locate *where in the backend* the integration belongs. This is not fit-surveying, the user already decided Mem0 fits. This is mechanics: you cannot write a plan without knowing what files matter. Read, in order, with a token budget. Do not scan the whole tree. 1. `README.md` (root) plus the first page of any `README_*.md` variants. 2. `CONTRIBUTING.md` / `AGENTS.md` / `CLAUDE.md` at root if present. These often spell out architecture and entry points. 3. `package.json` / `pyproject.toml` scripts and entry points. 4. The layout of the top two directory levels, not recursive. 5. Key config files: `docker-compose.yml`, `Dockerfile`, `Makefile`, `langgraph.json`, `next.config.*`, `nuxt.config.*`. Produce `.mem0-integration/repo-summary.md`: # Repo comprehension **What this repo does:** **Architecture at a glance:** - Backend: - Frontend: - Agent loop / orchestration: - Existing memory/session/state systems: **Candidate backend integration surfaces** (ranked, best first): 1. `:` 2. ... 3. ... **Not a fit here:** **Sources read:** Show the user the rendered summary and ask: *"Is this understanding correct? Which of the candidate surfaces (1, 2, 3 ...) should step 3 forward target?"* Gate rules: - No backend surface found, exit code 1. Preconditions should already have caught frontend-only repos; reaching this point means a subtler miss (for example the "backend" is actually just a static build). Do not force a fit. - Every candidate surface would require replacing an existing memory or session system, exit code 1 with the additive-principle rationale. The user can point at a non-conflicting location manually and re-run. - User corrections update `repo-summary.md` and re-confirm. Max 3 rounds, beyond that exit code 1. The user's chosen surface index is baked into `product.json` as `preferred_site` and referenced by steps 5 and 6. ## 3. Product selection: Platform vs OSS Read the `## Identify the User's Setup` block in `https://docs.mem0.ai/llms.txt` for the Platform-first routing rules, then apply the heuristics below. Ask, but never blank. - Other managed-service SDKs present (`@clerk/*`, `stripe`, `@supabase/*`, `openai`, `@upstash/*`, `posthog-*`), 3 or more, recommend **Platform**. - Local-infra signals (`docker-compose.yml` with postgres / redis / qdrant / neo4j, ollama configs, self-hosted auth), 2 or more, recommend **OSS**. - No strong signal, default recommendation **Platform**: lower integration cost, and migration later is supported. Example: > I see `stripe`, `@clerk/nextjs`, and `@supabase/supabase-js`, managed > services throughout. I recommend **Mem0 Platform** (4-line integration). > Override and use open source? Bake the choice into the goal doc in step 5. Do not re-decide later. ## 4. API key check (env first, then ask) | Track | Key | Where to find | |---|---|---| | Platform | `MEM0_API_KEY` | https://app.mem0.ai | | OSS (default LLM) | `OPENAI_API_KEY` | https://platform.openai.com/api-keys | Present in env, continue. `MEM0_API_KEY` missing and the track is **Platform**, **default to Agent Mode**: run `mem0 init --agent --agent-caller --json` (after `pip install mem0-cli` or `npm install -g @mem0/cli`), substituting your agent identity such as `claude-code`, `cursor`, `codex`. If you forgot `--agent-caller`, run `mem0 identify ` after init. Cache the key to `.env` with user consent and continue. Tell the user to claim it later with `mem0 init --email `: same key, no agent disruption. Missing and **CI mode** (`MEM0_INTEGRATE_CI=1`), exit code 2 with the name of the missing key. Never echo key values into `trace.jsonl`. Persist to `.env` only with explicit user consent, and append `.env` to `.gitignore` if it is not there already. If the user is on OSS and wants a non-OpenAI LLM, route them to the `components/llms/*` docs and re-run this step with the chosen provider's key. ## 5. Goal doc, the hard gate Write `.mem0-integration/goal.md` and **require user approval before step 6**. # Mem0 Integration Goal **What gets stored:** **When it gets retrieved:** **Why:** **Product:** Platform | OSS (locked from step 3, do not change) **Delegated skill:** . **Out of scope:** Rules: - The user must approve explicitly. If they edit the doc, reload and re-confirm. - `goal.md` is the contract the test suite is written against. Never rewrite it after step 6 starts. - Max 3 rejection rounds. On the 4th, exit code 3 with the rejection notes: the integration is not well-specified enough to proceed. ## 6. Integration plan, where and how (hard gate) `goal.md` is what and why. This step produces where and how, and gets explicit sign-off before any code is written. Do a **scoped** read of the repo, no wide survey: - Grep for the LLM call sites that match the goal (`openai.chat.`, `anthropic.messages.`, `model.generateContent`, `ChatOpenAI`, `createLLM`). - Grep for the user-identity source (`req.user`, `session.user`, `auth()`, `ctx.userId`, cookies). - Check `package.json` / `pyproject.toml` / `requirements.txt` for conflicts, for example an existing `mem0ai` at a different version. Then write `.mem0-integration/plan.md`: # Mem0 Integration Plan **Write pattern:** )."> **Read pattern:** , limit=5) and inject results as a system message."> **User identifier source:** **Session scoping:** - user_id: - agent_id: - run_id: **Write call site:** `` inside `` **Read call site:** `` inside `` **Dependencies to add:** - `@` **Preserved behavior:** **Coexistence:** **Feature flag:** **Sources consulted:** **E2E recipe:** start: ready_probe: status= / log="" / sleep=> compose_services: write_call: write_async_wait_ms: read_call: read_assert: = that MUST appear in read_call's output for the E2E to pass. Derived from goal.md's "What gets stored."> **Rejected alternatives:** Rules: - Show the user the proposed call sites with 10 lines of context around each before asking for approval. - If no plausible call site exists for either write or read, exit code 5 and ask the user to name the files manually. That is the "no fit here" signal, do not guess. - Max 3 rejection rounds on the plan. On the 4th, exit code 5 with the last plan and the user's notes. - If the user edits `plan.md` by hand, reload and re-confirm. `plan.md`, not `goal.md`, is the contract the subagent implements against in step 8. ## 7. Tests first (TDD) The main agent writes failing tests against `goal.md` in the repo's native test framework: | Track | Default framework | |---|---| | Python | `pytest` | | TypeScript | `vitest` if detected, else `jest` | | JavaScript | same | Test assertion shapes must match the **canonical signatures**: - Platform method signatures: `https://docs.mem0.ai/openapi.json`, the request body schemas for `/v1/memories/` and `/v1/memories/search/`. - OSS method signatures: the delegated skill named in `plan.md` (fetched from its raw URL), or `skills/mem0/SKILL.md` as the default. - Do not hand-roll request shapes. If the delegated skill has an example block, lift it verbatim. Minimum two test files, paths taken from `plan.md` call sites: - `test_mem0_write.` asserts `add()` is called at the write call site with the right payload shape (Platform messages-array vs OSS string) and the right `user_id` source. - `test_mem0_read.` asserts `search()` runs before the read call site and the result is wired into the LLM prompt or response path. Tests MUST be importable with `MEM0_API_KEY` unset. This is the design pressure that forces step 8's lazy `MemoryClient()` / `Memory()` construction: eager module-level init hits the API on import and breaks pre-existing test collection when the key is missing. Run the tests. They **must fail**. If they pass before any implementation, the tests are wrong. Rewrite them. ## 8. Implementation (subagent, fresh context) Spawn a subagent with: - **Inputs**: the repo, `goal.md`, `plan.md`, the two test files, and direct URLs to the delegated skill (from `plan.md`), the SDK source (pinned per `mem0_tested_versions`), `https://docs.mem0.ai/llms.txt`, and `https://docs.mem0.ai/openapi.json`. - **No access** to the main agent's reasoning trace or scratchpad. - **System prompt**: use the implementation prompt in [`subagent-prompts.md`](subagent-prompts.md) verbatim. The subagent returns a diff. The main agent reviews it against `plan.md` (the mechanical contract) and `goal.md` (the intent): - Approved, apply the diff and commit. - Rejected, return with specific actionable feedback, not "try again." - Max 3 review loops. Beyond that, exit code 4 with the last diff and the reviewer feedback. ## 9. Commit and handoff Create branch `mem0-integrate/` and commit in **separate commits** so reviewers can cherry-pick: 1. `mem0: add gated dependency`, just the `pyproject.toml` / `package.json` change. 2. `mem0: add integration module`, the new files. 3. `mem0: wire into `, the call-site edits, still gated. 4. `mem0: add tests`, the new test files. With `--no-heal`, print `Run /mem0-test-integration to verify.` and exit. Otherwise proceed to step 10. ## 10. Self-healing loop (default ON, disable with `--no-heal`) Run `/mem0-test-integration --ci` in a subprocess. If `scorecard.json` reports `overall: pass`, done, exit 0. Otherwise loop: 1. **Categorize the failing check** from `scorecard.json` and route: - `install` / `static_checks`, dependency or import fix. - `unit_tests`, wiring or assertion fix. - `smoke_test`, API key or SDK call-shape fix. - `e2e_test`, recipe, flag-wiring, or integration-point fix. - **Pre-existing test failure** (test skill exit code 7, `non_invasive: false` in the scorecard), **STOP**. This is a non-invasiveness violation. Do NOT attempt to fix it, that breaks principle 3. Exit code 6 with a rationale. 2. **Spawn a remediation subagent** with fresh context. Inputs: `plan.md`, `goal.md`, `scorecard.md`, `scorecard.json`, the last committed diff, and the relevant log for the failing category (`test-stdout.log` / `smoke-stdout.log` / `e2e-app.log` / `e2e-calls.log`). Use the remediation prompt in [`subagent-prompts.md`](subagent-prompts.md) verbatim. 3. **Apply the diff** and commit on the same branch as `mem0-heal: attempt `. Do NOT amend earlier commits, reviewers need the heal trail. 4. **Re-run `/mem0-test-integration --ci`**: - `overall: pass`, done, exit 0. - Same check still failing, increment the attempt counter and loop. - A *different* check now failing, that is a regression. Revert the heal commit (`git revert HEAD --no-edit`), record it in `.mem0-integration/heal-trace.md`, exit code 6. 5. **Bounded iterations.** Default 3 attempts per failing category, override with `--heal-max N` (hard cap 10). On exhaustion, exit code 6 with the full attempt trace: each diff, each scorecard, final log tail. 6. **Post-loop summary** written to `.mem0-integration/heal-trace.md`: which category failed, how many attempts, each diff's intent, final status, and on success the delta from the initial scorecard to the final one.