From 70a37266ea8cd222d605bc63d6942b6673584511 Mon Sep 17 00:00:00 2001 From: g0 Date: Tue, 8 Sep 2026 05:20:11 +0800 Subject: [PATCH 1/3] docs(ctx_search): document hybrid retrieval and question-form query guidance --- packages/plugin/src/tools/ctx-search/constants.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/plugin/src/tools/ctx-search/constants.ts b/packages/plugin/src/tools/ctx-search/constants.ts index 0bfbf0dc8..5f2f353ea 100644 --- a/packages/plugin/src/tools/ctx-search/constants.ts +++ b/packages/plugin/src/tools/ctx-search/constants.ts @@ -1,6 +1,8 @@ export const CTX_SEARCH_TOOL_NAME = "ctx_search"; export const CTX_SEARCH_DESCRIPTION = `Your long-term recall for this project — search everything that ever happened here, not just what's currently visible. +Retrieval is HYBRID: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts. Phrase \`query\` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". + Reach for it when something feels familiar but isn't in view: "did we solve this before?", "what did we decide about X?", "when did this break?", "where does Y live?". Results only contain things you CANNOT currently see — memories already shown in and the live conversation tail are filtered out. A query that is just one or more memory ids (e.g. \`#7234\` or \`12, 34\`) bypasses text search and resolves those ids directly. Sources (omit for a broad search across all): From 0edb5324ed43a0e140dadfbcf976201720912816 Mon Sep 17 00:00:00 2001 From: g0 Date: Tue, 8 Sep 2026 05:48:35 +0800 Subject: [PATCH 2/3] docs(ctx_search): qualify hybrid claim by embedding availability; sync prompt-surface golden --- packages/plugin/src/shared/prompt-surface-a1-golden.md | 2 ++ packages/plugin/src/tools/ctx-search/constants.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/plugin/src/shared/prompt-surface-a1-golden.md b/packages/plugin/src/shared/prompt-surface-a1-golden.md index bceace2ad..e016a0195 100644 --- a/packages/plugin/src/shared/prompt-surface-a1-golden.md +++ b/packages/plugin/src/shared/prompt-surface-a1-golden.md @@ -400,6 +400,8 @@ Example: ctx_memory(action="write", category="CONSTRAINTS", content="Pi stores s ``` Your long-term recall for this project — search everything that ever happened here, not just what's currently visible. +Retrieval is HYBRID when embeddings are enabled: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts; with embeddings disabled it silently falls back to keyword-only matching — tell by results carrying no `match=semantic` labels, and then prefer literal-heavy queries. Phrase `query` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". + Reach for it when something feels familiar but isn't in view: "did we solve this before?", "what did we decide about X?", "when did this break?", "where does Y live?". Results only contain things you CANNOT currently see — memories already shown in and the live conversation tail are filtered out. A query that is just one or more memory ids (e.g. `#7234` or `12, 34`) bypasses text search and resolves those ids directly. Sources (omit for a broad search across all): diff --git a/packages/plugin/src/tools/ctx-search/constants.ts b/packages/plugin/src/tools/ctx-search/constants.ts index 5f2f353ea..91db0bf80 100644 --- a/packages/plugin/src/tools/ctx-search/constants.ts +++ b/packages/plugin/src/tools/ctx-search/constants.ts @@ -1,7 +1,7 @@ export const CTX_SEARCH_TOOL_NAME = "ctx_search"; export const CTX_SEARCH_DESCRIPTION = `Your long-term recall for this project — search everything that ever happened here, not just what's currently visible. -Retrieval is HYBRID: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts. Phrase \`query\` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". +Retrieval is HYBRID when embeddings are enabled: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts; with embeddings disabled it silently falls back to keyword-only matching — tell by results carrying no \`match=semantic\` labels, and then prefer literal-heavy queries. Phrase \`query\` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". Reach for it when something feels familiar but isn't in view: "did we solve this before?", "what did we decide about X?", "when did this break?", "where does Y live?". Results only contain things you CANNOT currently see — memories already shown in and the live conversation tail are filtered out. A query that is just one or more memory ids (e.g. \`#7234\` or \`12, 34\`) bypasses text search and resolves those ids directly. From 468a27d78f33983a46045a7dea9bc21f13d70ed8 Mon Sep 17 00:00:00 2001 From: g0 Date: Tue, 8 Sep 2026 05:58:42 +0800 Subject: [PATCH 3/3] docs(ctx_search): drop unreliable match-label fallback inference --- packages/plugin/src/shared/prompt-surface-a1-golden.md | 2 +- packages/plugin/src/tools/ctx-search/constants.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/src/shared/prompt-surface-a1-golden.md b/packages/plugin/src/shared/prompt-surface-a1-golden.md index e016a0195..f6e05e8d6 100644 --- a/packages/plugin/src/shared/prompt-surface-a1-golden.md +++ b/packages/plugin/src/shared/prompt-surface-a1-golden.md @@ -400,7 +400,7 @@ Example: ctx_memory(action="write", category="CONSTRAINTS", content="Pi stores s ``` Your long-term recall for this project — search everything that ever happened here, not just what's currently visible. -Retrieval is HYBRID when embeddings are enabled: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts; with embeddings disabled it silently falls back to keyword-only matching — tell by results carrying no `match=semantic` labels, and then prefer literal-heavy queries. Phrase `query` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". +Retrieval is HYBRID when embeddings are enabled: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts; with embeddings disabled it silently falls back to keyword-only matching. Phrase `query` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". Reach for it when something feels familiar but isn't in view: "did we solve this before?", "what did we decide about X?", "when did this break?", "where does Y live?". Results only contain things you CANNOT currently see — memories already shown in and the live conversation tail are filtered out. A query that is just one or more memory ids (e.g. `#7234` or `12, 34`) bypasses text search and resolves those ids directly. diff --git a/packages/plugin/src/tools/ctx-search/constants.ts b/packages/plugin/src/tools/ctx-search/constants.ts index 91db0bf80..e589bc713 100644 --- a/packages/plugin/src/tools/ctx-search/constants.ts +++ b/packages/plugin/src/tools/ctx-search/constants.ts @@ -1,7 +1,7 @@ export const CTX_SEARCH_TOOL_NAME = "ctx_search"; export const CTX_SEARCH_DESCRIPTION = `Your long-term recall for this project — search everything that ever happened here, not just what's currently visible. -Retrieval is HYBRID when embeddings are enabled: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts; with embeddings disabled it silently falls back to keyword-only matching — tell by results carrying no \`match=semantic\` labels, and then prefer literal-heavy queries. Phrase \`query\` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". +Retrieval is HYBRID when embeddings are enabled: ~0.7 semantic (embedding cosine) + ~0.3 keyword (FTS5 BM25), fused with per-source boosts; with embeddings disabled it silently falls back to keyword-only matching. Phrase \`query\` as a natural-language QUESTION that still embeds the key literal terms (paths, symbols, commands, config keys) — pure keyword stacks starve the semantic leg (0.7 weight), while pure prose without literal terms may miss exact FTS matches. Good: "Where is the dream log file and which error counters indicate failures?" Bad: "dream log error counter". Reach for it when something feels familiar but isn't in view: "did we solve this before?", "what did we decide about X?", "when did this break?", "where does Y live?". Results only contain things you CANNOT currently see — memories already shown in and the live conversation tail are filtered out. A query that is just one or more memory ids (e.g. \`#7234\` or \`12, 34\`) bypasses text search and resolves those ids directly.