#19022: memory: support per-agent QMD collection paths
size: S
## Summary
- **Problem:** QMD backend resolves custom collection paths from global `memory.qmd.paths` only — all agents share the same collections in multi-agent setups.
- **Why it matters:** Agent-specific knowledge leaks into unrelated agents' search results, reducing relevance. The builtin backend already supports per-agent scoping via `memorySearch.extraPaths`, but QMD has no equivalent.
- **What changed:** Added optional `qmd.paths` to per-agent config (`AgentConfig`). `resolveMemoryBackendConfig()` now appends per-agent paths after global paths.
- **What did NOT change:** Global `memory.qmd.paths` behavior is untouched. Default memory paths (`MEMORY.md`, `memory/*.md`) remain workspace-scoped as before. No changes to builtin backend or `memorySearch.extraPaths`.
## Change Type (select all)
- [x] Feature
## Scope (select all touched areas)
- [x] Memory / storage
## Linked Issue/PR
- Closes #19005
## User-visible / Behavior Changes
New optional config key `agents.list[].qmd.paths` (array of `MemoryQmdIndexPath`). Per-agent paths are appended to global `memory.qmd.paths`. No behavior change for existing configs without the new key.
## Security Impact (required)
- New permissions/capabilities? `No`
- Secrets/tokens handling changed? `No`
- New/changed network calls? `No`
- Command/tool execution surface changed? `No`
- Data access scope changed? `No`
## Repro + Verification
### Environment
- Runtime: Node 22+ / Bun
### Steps
1. Configure two agents with different `qmd.paths` in config
2. Run `resolveMemoryBackendConfig` for each agent
3. Verify collections include global + agent-specific paths
### Expected
- Each agent's resolved collections contain global paths plus only their own per-agent paths
### Actual
- Confirmed via unit test
## Evidence
- [x] Failing test/log before + passing after — new test `merges per-agent qmd.paths with global paths` (8/8 passing)
## Human Verification (required)
- Verified scenarios: new test covers merge behavior for agent with per-agent paths and agent without
- Edge cases checked: agent with no `qmd` config gets only global paths; collection name deduplication still works
- What you did **not** verify: live gateway with real QMD command
## Compatibility / Migration
- Backward compatible? `Yes`
- Config/env changes? `No` (additive optional key)
- Migration needed? `No`
## Failure Recovery (if this breaks)
- How to disable/revert: remove `qmd` key from agent configs; behavior reverts to global-only paths
- Known bad symptoms: unexpected collections in agent search results
## Risks and Mitigations
None — additive config key with no impact on existing setups.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds per-agent QMD collection paths (`agents.list[].qmd.paths`) that are appended after global `memory.qmd.paths` during resolution, enabling agent-specific knowledge scoping in multi-agent setups.
- The core resolution logic in `backend-config.ts` is clean and reuses the existing `resolveCustomPaths` helper — collection name deduplication via `nameSet` is preserved.
- The new test covers the key scenarios (agent with per-agent paths, agent without).
- **Critical issue:** The `qmd` field was added to the `AgentConfig` TypeScript type but **not** to the `AgentEntrySchema` Zod schema in `src/config/zod-schema.agent-runtime.ts`. That schema uses `.strict()`, which means any config that uses the new `agents.list[].qmd.paths` key will fail validation with an "unrecognized key" error at runtime. The Zod schema must be updated for this feature to work.
<h3>Confidence Score: 2/5</h3>
- This PR will not work as intended due to a missing Zod schema update — configs using the new key will be rejected at runtime.
- The implementation logic is correct and the test passes, but the Zod validation schema for agent entries uses `.strict()` and was not updated to include the new `qmd` field. This means the feature is dead on arrival: any user config that sets `agents.list[].qmd.paths` will fail config validation before the resolution code ever runs.
- Pay close attention to `src/config/zod-schema.agent-runtime.ts` — the `AgentEntrySchema` needs a `qmd` field added to match the TypeScript type change in `types.agents.ts`.
<sub>Last reviewed commit: 80f4a45</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#16968: fix(qmd): per-collection search to prevent large collections drowni...
by ProgramCaiCai · 2026-02-15
77.3%
#20966: fix(memory/qmd): migrate orphaned unscoped collections on upgrade
by marcodelpin · 2026-02-19
76.9%
#22937: fix: remove legacy unsuffixed QMD collections on upgrade
by sud0n1m-ziggy · 2026-02-21
76.0%
#12939: fix(memory): strip null bytes from workspace paths causing ENOTDIR
by omair445 · 2026-02-09
75.9%
#9726: feat: add identityDir config for separate identity file location
by rickburn · 2026-02-05
75.7%
#9678: Cross-agent memory read allowlist
by Helmi · 2026-02-05
74.8%
#9381: Fix: Allow QMD CLI memory search when scope is restrictive
by vishaltandale00 · 2026-02-05
74.6%
#19329: feat: add per-agent compaction and context pruning overrides
by curtismercier · 2026-02-17
74.6%
#9149: Fix: Allow QMD backend to work without OpenAI auth
by vishaltandale00 · 2026-02-04
74.2%
#9624: fix(memory): resolve QMD search returning empty results [AI-assisted]
by kowshik24 · 2026-02-05
74.0%