diff --git a/src/services/context/ObservationCompiler.ts b/src/services/context/ObservationCompiler.ts index c18d07eb..aad1d17a 100644 --- a/src/services/context/ObservationCompiler.ts +++ b/src/services/context/ObservationCompiler.ts @@ -141,7 +141,8 @@ export function queryObservationsMulti( o.project FROM observations o LEFT JOIN sdk_sessions s ON o.memory_session_id = s.memory_session_id - WHERE o.project IN (${projectPlaceholders}) + WHERE (o.project IN (${projectPlaceholders}) + OR o.merged_into_project IN (${projectPlaceholders})) AND type IN (${typePlaceholders}) AND EXISTS ( SELECT 1 FROM json_each(o.concepts) @@ -151,6 +152,7 @@ export function queryObservationsMulti( ORDER BY o.created_at_epoch DESC LIMIT ? `).all( + ...projects, ...projects, ...typeArray, ...conceptArray, @@ -189,11 +191,12 @@ export function querySummariesMulti( ss.project FROM session_summaries ss LEFT JOIN sdk_sessions s ON ss.memory_session_id = s.memory_session_id - WHERE ss.project IN (${projectPlaceholders}) + WHERE (ss.project IN (${projectPlaceholders}) + OR ss.merged_into_project IN (${projectPlaceholders})) ${platformSource ? "AND COALESCE(s.platform_source, 'claude') = ?" : ''} ORDER BY ss.created_at_epoch DESC LIMIT ? - `).all(...projects, ...(platformSource ? [platformSource] : []), config.sessionCount + SUMMARY_LOOKAHEAD) as SessionSummary[]; + `).all(...projects, ...projects, ...(platformSource ? [platformSource] : []), config.sessionCount + SUMMARY_LOOKAHEAD) as SessionSummary[]; } /** diff --git a/src/services/sync/ChromaSync.ts b/src/services/sync/ChromaSync.ts index 4b885f09..a4545e8d 100644 --- a/src/services/sync/ChromaSync.ts +++ b/src/services/sync/ChromaSync.ts @@ -28,6 +28,7 @@ interface StoredObservation { id: number; memory_session_id: string; project: string; + merged_into_project: string | null; text: string | null; type: string; title: string | null; @@ -47,6 +48,7 @@ interface StoredSummary { id: number; memory_session_id: string; project: string; + merged_into_project: string | null; request: string | null; investigated: string | null; learned: string | null; @@ -129,11 +131,12 @@ export class ChromaSync { const files_read = parseFileList(obs.files_read); const files_modified = parseFileList(obs.files_modified); - const baseMetadata: Record = { + const baseMetadata: Record = { sqlite_id: obs.id, doc_type: 'observation', memory_session_id: obs.memory_session_id, project: obs.project, + merged_into_project: obs.merged_into_project ?? null, created_at_epoch: obs.created_at_epoch, type: obs.type || 'discovery', title: obs.title || 'Untitled' @@ -190,11 +193,12 @@ export class ChromaSync { private formatSummaryDocs(summary: StoredSummary): ChromaDocument[] { const documents: ChromaDocument[] = []; - const baseMetadata: Record = { + const baseMetadata: Record = { sqlite_id: summary.id, doc_type: 'session_summary', memory_session_id: summary.memory_session_id, project: summary.project, + merged_into_project: summary.merged_into_project ?? null, created_at_epoch: summary.created_at_epoch, prompt_number: summary.prompt_number || 0 }; @@ -346,6 +350,7 @@ export class ChromaSync { id: observationId, memory_session_id: memorySessionId, project: project, + merged_into_project: null, text: null, // Legacy field, not used type: obs.type, title: obs.title, @@ -390,6 +395,7 @@ export class ChromaSync { id: summaryId, memory_session_id: memorySessionId, project: project, + merged_into_project: null, request: summary.request, investigated: summary.investigated, learned: summary.learned, diff --git a/src/services/worker/SearchManager.ts b/src/services/worker/SearchManager.ts index 996a82a9..ba64fb09 100644 --- a/src/services/worker/SearchManager.ts +++ b/src/services/worker/SearchManager.ts @@ -170,8 +170,16 @@ export class SearchManager { // Include project in the Chroma where clause to scope vector search. // Without this, larger projects dominate the top-N results and smaller // projects get crowded out before the post-hoc SQLite filter. + // Match both native-provenance rows (project) and adopted merged-worktree + // rows (merged_into_project) so a parent-project query surfaces its + // merged children's observations too. if (options.project) { - const projectFilter = { project: options.project }; + const projectFilter = { + $or: [ + { project: options.project }, + { merged_into_project: options.project } + ] + }; whereFilter = whereFilter ? { $and: [whereFilter, projectFilter] } : projectFilter;