import './memory-schema-Bi7cChwo.js';
import './sqlite-Dsbe0wec.js';
import { m as memoryFindHitNext } from './mvi-helpers-BNsJ8ZpQ.js';
import './graph-auto-populate2-DYsUNGSL.js';
import 'node:crypto';
import { s as searchBrain, h as hybridSearch } from './brain-search2-tm7GcSB8.js';
import { o as observeBrain } from './observe2-hCg9xf6C.js';
import './indexes-aYlULWG3.js';
import './utils-BvHPJOVk.js';
import './chunk-DDP5xfzh.js';
import 'node:module';
import './paths-2M_UxD_H.js';
import 'node:fs';
import 'node:path';
import 'node:os';
import 'node:events';
import 'node:diagnostics_channel';
import 'fs';
import 'events';
import 'util';
import 'path';
import 'assert';
import 'worker_threads';
import 'module';
import 'node:url';
import 'url';
import 'buffer';
import 'node:child_process';
import 'node:process';
import 'node:async_hooks';
import './unique-constraint-BM-Apx1H.js';
import './dual-scope-db-ATrwq0LH.js';
import './conduit-Ca_OFWR_.js';
import './agent-registry-BtE5uhMO.js';
import './nexus-sqlite2-DgTuv9BQ.js';
import './nexus-schema2-BEd-ol6e.js';
import './logger-ChCwlV5k.js';
import 'node:sqlite';
import './lock-BoHF25mx.js';
import './index-IVoIz4D5.js';
import 'constants';
import 'stream';
import './memory-accessor2-BzlgmY-Z.js';
import './typed-query-l1D_QElt.js';
import './quality-scoring-CCPuRQmJ.js';
import './brain-similarity-B2HLXCge.js';
import './brain-embedding-Djw9ekXu.js';
import './cross-db-cleanup-C_FLyd-6.js';

//#region ../core/dist/memory/retrieval/build-retrieval-bundle.js
/**
* BRAIN Multi-Pass Retrieval Bundle (PSYCHE Wave 4 · T1090).
*
* Executes up to three passes in parallel:
* - Cold (20 % of budget): user-profile traits + peer instructions
* - Warm (50 % of budget): peer-scoped learnings, patterns, decisions
* - Hot  (30 % of budget): session narrative + recent observations + active tasks
*
* @task T1090
* @epic T1083
*/
/** Default token budget for `buildRetrievalBundle` (characters / 4 ≈ tokens). */
var DEFAULT_TOKEN_BUDGET = 4e3;
/** Default pass-mask: all three passes active. */
var DEFAULT_PASS_MASK = {
	cold: true,
	warm: true,
	hot: true
};
/** Cold pass budget share (20 %). */
var COLD_BUDGET_FRACTION = .2;
/** Hot pass budget share (30 %). */
var HOT_BUDGET_FRACTION = .3;
/**
* Estimate tokens consumed by an arbitrary string.
* Uses the approximate 4-chars-per-token heuristic.
*/
function estimateTokens(text) {
	return Math.ceil(text.length / 4);
}
/**
* Cold pass — fetch user-profile traits and peer instructions from NEXUS.
*
* Calls `listUserProfile({ minConfidence: 0.5 })` from Wave 1 (T1078).
* `peerInstructions` is populated from the sigil's `systemPromptFragment`
* when a sigil exists for `peerId` (Wave 8 — T1148). Falls back to an empty
* string when no sigil is found or when the sigil has no fragment set.
*
* @param peerId   - CANT peer identifier (used to look up the sigil).
* @param nexusDb  - Drizzle nexus database handle.
* @returns Cold-pass bundle slice: userProfile traits + peerInstructions + sigilCard.
*
* @task T1090
* @task T1148
*/
async function fetchIdentity(peerId, nexusDb) {
	const { listUserProfile } = await import('./user-profile-D3aqqLc0.js');
	const { getSigil } = await import('./sigil-C7yjo4Ai.js');
	const [userProfile, sigilCard] = await Promise.all([listUserProfile(nexusDb, { minConfidence: .5 }), getSigil(nexusDb, peerId).catch(() => null)]);
	return {
		userProfile,
		peerInstructions: sigilCard?.systemPromptFragment ?? "",
		sigilCard
	};
}
/**
* Warm pass — fetch peer-scoped learnings, patterns, and decisions from BRAIN.
*
* Uses the Wave 2 peer_id filter: each query returns rows where
* `peer_id = peerId OR peer_id = 'global'`. When `query` is supplied the
* learnings search is narrowed to relevant entries via FTS; decisions and
* patterns are returned by recency (most recent first, capped at 10 each).
*
* @param peerId   - CANT peer identifier.
* @param brainDb  - Drizzle brain database handle.
* @param query    - Optional search term to scope learnings retrieval.
* @returns Warm-pass bundle slice: peerLearnings, peerPatterns, decisions.
*
* @task T1090
*/
async function fetchPeerMemory(peerId, query) {
	const { getBrainNativeDb } = await import('./memory-sqlite-Dg5uGJCo.js');
	const nativeDb = getBrainNativeDb();
	if (!nativeDb) return {
		peerLearnings: [],
		peerPatterns: [],
		decisions: []
	};
	const peerFilter = peerId !== "global";
	const learningSqlWithPeer = `SELECT id, insight, created_at, provenance_class FROM brain_learnings
             WHERE (peer_id = ? OR peer_id = 'global')
             ORDER BY created_at DESC LIMIT 10`;
	const learningSqlGlobal = `SELECT id, insight, created_at, provenance_class FROM brain_learnings
             WHERE peer_id = 'global'
             ORDER BY created_at DESC LIMIT 10`;
	const learningSqlLegacy = "SELECT id, insight, created_at FROM brain_learnings ORDER BY created_at DESC LIMIT 10";
	let learningRows = [];
	try {
		learningRows = peerFilter ? nativeDb.prepare(learningSqlWithPeer).all(peerId) : nativeDb.prepare(learningSqlGlobal).all();
	} catch {
		try {
			learningRows = nativeDb.prepare(learningSqlLegacy).all();
		} catch {
			learningRows = [];
		}
	}
	const patternSqlWithPeer = `SELECT id, pattern, extracted_at, provenance_class FROM brain_patterns
           WHERE (peer_id = ? OR peer_id = 'global')
           ORDER BY extracted_at DESC LIMIT 10`;
	const patternSqlGlobal = `SELECT id, pattern, extracted_at, provenance_class FROM brain_patterns
           WHERE peer_id = 'global'
           ORDER BY extracted_at DESC LIMIT 10`;
	const patternSqlLegacy = "SELECT id, pattern, extracted_at FROM brain_patterns ORDER BY extracted_at DESC LIMIT 10";
	let patternRows = [];
	try {
		patternRows = peerFilter ? nativeDb.prepare(patternSqlWithPeer).all(peerId) : nativeDb.prepare(patternSqlGlobal).all();
	} catch {
		try {
			patternRows = nativeDb.prepare(patternSqlLegacy).all();
		} catch {
			patternRows = [];
		}
	}
	const decisionSqlWithPeer = `SELECT id, decision, created_at, provenance_class FROM brain_decisions
           WHERE (peer_id = ? OR peer_id = 'global')
           ORDER BY created_at DESC LIMIT 10`;
	const decisionSqlGlobal = `SELECT id, decision, created_at, provenance_class FROM brain_decisions
           WHERE peer_id = 'global'
           ORDER BY created_at DESC LIMIT 10`;
	const decisionSqlLegacy = "SELECT id, decision, created_at FROM brain_decisions ORDER BY created_at DESC LIMIT 10";
	let decisionRows = [];
	try {
		decisionRows = peerFilter ? nativeDb.prepare(decisionSqlWithPeer).all(peerId) : nativeDb.prepare(decisionSqlGlobal).all();
	} catch {
		try {
			decisionRows = nativeDb.prepare(decisionSqlLegacy).all();
		} catch {
			decisionRows = [];
		}
	}
	return {
		peerLearnings: learningRows.map((r) => ({
			id: r.id,
			insight: r.insight,
			createdAt: r.created_at,
			provenanceClass: r.provenance_class ?? "unswept-pre-T1151"
		})),
		peerPatterns: patternRows.map((r) => ({
			id: r.id,
			pattern: r.pattern,
			extractedAt: r.extracted_at,
			provenanceClass: r.provenance_class ?? "unswept-pre-T1151"
		})),
		decisions: decisionRows.map((r) => ({
			id: r.id,
			decision: r.decision,
			createdAt: r.created_at,
			provenanceClass: r.provenance_class ?? "unswept-pre-T1151"
		}))
	};
}
/**
* Hot pass — fetch live session state: narrative + recent observations + active tasks.
*
* Calls `getSessionNarrative(sessionId)` from Wave 3 (T1089).
* Active tasks are queried from tasks.db via the DataAccessor.
*
* @param sessionId  - Active session identifier.
* @param projectRoot - Project root for DB resolution (tasks.db + brain.db).
* @returns Hot-pass bundle slice: sessionNarrative, recentObservations, activeTasks.
*
* @task T1090
*/
async function fetchSessionState(sessionId, projectRoot) {
	const { getSessionNarrative } = await import('./session-narrative-B6H2uYEO.js');
	let sessionNarrative = "";
	try {
		const { getBrainDb } = await import('./memory-sqlite-Dg5uGJCo.js');
		await getBrainDb(projectRoot);
		sessionNarrative = (await getSessionNarrative(sessionId))?.narrative ?? "";
	} catch {}
	const { getBrainNativeDb } = await import('./memory-sqlite-Dg5uGJCo.js');
	const nativeDb = getBrainNativeDb();
	let recentObservations = [];
	if (nativeDb) try {
		recentObservations = nativeDb.prepare(`SELECT id, title, narrative, created_at, provenance_class
           FROM brain_observations
           WHERE source_session_id = ?
           ORDER BY created_at DESC, id DESC LIMIT 10`).all(sessionId).map((r) => ({
			id: r.id,
			title: r.title,
			narrative: r.narrative ?? "",
			createdAt: r.created_at,
			provenanceClass: r.provenance_class ?? "unswept-pre-T1151"
		}));
	} catch {
		recentObservations = [];
	}
	let activeTasks = [];
	try {
		const { getTaskAccessor } = await import('./data-accessor-CVbz8X_7.js').then(function (n) { return n.d; });
		const { tasks } = await (await getTaskAccessor(projectRoot)).queryTasks({
			status: ["active", "in_progress"],
			limit: 10
		});
		activeTasks = tasks.map((t) => ({
			id: t.id,
			title: t.title,
			status: t.status
		}));
	} catch {
		activeTasks = [];
	}
	return {
		sessionNarrative,
		recentObservations,
		activeTasks
	};
}
/**
* Build a structured multi-pass retrieval bundle for agent briefing.
*
* Executes up to three passes in parallel (controlled by `passMask`):
*
* - **Cold** (20 % of budget): user-profile traits + peer instructions
* - **Warm** (50 % of budget): peer-scoped learnings, patterns, decisions
* - **Hot**  (30 % of budget): session narrative + recent observations + active tasks
*
* When the total token estimate exceeds `tokenBudget`, the hot pass is trimmed
* first (observations then tasks) to preserve the more stable cold/warm context.
*
* This function is the primary entry point consumed by `computeBriefing` in
* `packages/core/src/sessions/briefing.ts` (T1091).
*
* @param req         - Retrieval request with peerId, sessionId, optional query and passMask.
* @param projectRoot - Project root directory for DB resolution.
* @returns Fully-structured `RetrievalBundle` with token accounting.
*
* @example
* ```ts
* const bundle = await buildRetrievalBundle(
*   { peerId: 'cleo-prime', sessionId: 'ses_abc', passMask: { cold: true, warm: true, hot: true } },
*   '/mnt/projects/cleocode',
* );
* console.log(bundle.cold.userProfile.length, 'profile traits');
* ```
*
* @task T1090
* @epic T1083
*/
async function buildRetrievalBundle(req, projectRoot) {
	const { peerId, sessionId, query, passMask = DEFAULT_PASS_MASK, tokenBudget = DEFAULT_TOKEN_BUDGET } = req;
	const mask = {
		...DEFAULT_PASS_MASK,
		...passMask
	};
	const coldBudget = Math.floor(tokenBudget * COLD_BUDGET_FRACTION);
	const hotBudget = Math.floor(tokenBudget * HOT_BUDGET_FRACTION);
	const [coldResult, warmResult, hotResult] = await Promise.all([
		mask.cold ? (async () => {
			try {
				const { getNexusDb } = await import('./nexus-sqlite-CBdrYCMo.js');
				return await fetchIdentity(peerId, await getNexusDb());
			} catch {
				return {
					userProfile: [],
					peerInstructions: "",
					sigilCard: null
				};
			}
		})() : Promise.resolve({
			userProfile: [],
			peerInstructions: "",
			sigilCard: null
		}),
		mask.warm ? (async () => {
			try {
				const { getBrainDb } = await import('./memory-sqlite-Dg5uGJCo.js');
				await getBrainDb(projectRoot);
				return await fetchPeerMemory(peerId, query);
			} catch {
				return {
					peerLearnings: [],
					peerPatterns: [],
					decisions: []
				};
			}
		})() : Promise.resolve({
			peerLearnings: [],
			peerPatterns: [],
			decisions: []
		}),
		mask.hot ? fetchSessionState(sessionId, projectRoot) : Promise.resolve({
			sessionNarrative: "",
			recentObservations: [],
			activeTasks: []
		})
	]);
	const REFUSED_CLASS = "unswept-pre-T1151";
	const refusedWarmLearnings = warmResult.peerLearnings.filter((e) => e.provenanceClass === REFUSED_CLASS);
	const acceptedWarmLearnings = warmResult.peerLearnings.filter((e) => e.provenanceClass !== REFUSED_CLASS);
	const refusedWarmPatterns = warmResult.peerPatterns.filter((e) => e.provenanceClass === REFUSED_CLASS);
	const acceptedWarmPatterns = warmResult.peerPatterns.filter((e) => e.provenanceClass !== REFUSED_CLASS);
	const refusedWarmDecisions = warmResult.decisions.filter((e) => e.provenanceClass === REFUSED_CLASS);
	const acceptedWarmDecisions = warmResult.decisions.filter((e) => e.provenanceClass !== REFUSED_CLASS);
	const refusedHotObservations = hotResult.recentObservations.filter((e) => e.provenanceClass === REFUSED_CLASS);
	const acceptedHotObservations = hotResult.recentObservations.filter((e) => e.provenanceClass !== REFUSED_CLASS);
	const refusedCount = refusedWarmLearnings.length + refusedWarmPatterns.length + refusedWarmDecisions.length + refusedHotObservations.length;
	if (refusedCount > 0) console.warn(`[buildRetrievalBundle] M6 refusal gate: refused ${refusedCount} entries with provenanceClass='unswept-pre-T1151'. Run T1147 W7 sweep (.132) to promote entries to 'swept-clean'. Bundle may be empty until sweep completes.`);
	const filteredWarmResult = {
		peerLearnings: acceptedWarmLearnings,
		peerPatterns: acceptedWarmPatterns,
		decisions: acceptedWarmDecisions
	};
	const filteredHotObservations = acceptedHotObservations;
	let coldTokens = 0;
	for (const trait of coldResult.userProfile) coldTokens += estimateTokens(`${trait.traitKey}:${trait.traitValue}`);
	coldTokens += estimateTokens(coldResult.peerInstructions);
	let warmTokens = 0;
	for (const l of filteredWarmResult.peerLearnings) warmTokens += estimateTokens(l.insight);
	for (const p of filteredWarmResult.peerPatterns) warmTokens += estimateTokens(p.pattern);
	for (const d of filteredWarmResult.decisions) warmTokens += estimateTokens(d.decision);
	let hotTokens = estimateTokens(hotResult.sessionNarrative);
	for (const o of filteredHotObservations) hotTokens += estimateTokens(o.narrative || o.title);
	for (const t of hotResult.activeTasks) hotTokens += estimateTokens(`${t.id} ${t.title}`);
	let trimmedObservations = filteredHotObservations;
	let trimmedTasks = hotResult.activeTasks;
	if (coldTokens + warmTokens + hotTokens > tokenBudget) {
		const hotAllowed = tokenBudget - coldTokens - warmTokens;
		const effectiveHotBudget = Math.max(0, Math.min(hotBudget, hotAllowed));
		let usedHot = estimateTokens(hotResult.sessionNarrative);
		trimmedObservations = [];
		for (const obs of filteredHotObservations) {
			const cost = estimateTokens(obs.narrative || obs.title);
			if (usedHot + cost <= effectiveHotBudget) {
				trimmedObservations.push(obs);
				usedHot += cost;
			}
		}
		trimmedTasks = [];
		for (const task of hotResult.activeTasks) {
			const cost = estimateTokens(`${task.id} ${task.title}`);
			if (usedHot + cost <= effectiveHotBudget) {
				trimmedTasks.push(task);
				usedHot += cost;
			}
		}
		hotTokens = usedHot;
	}
	let trimmedProfile = coldResult.userProfile;
	if (coldTokens > coldBudget) {
		let usedCold = estimateTokens(coldResult.peerInstructions);
		trimmedProfile = [];
		for (const trait of coldResult.userProfile) {
			const cost = estimateTokens(`${trait.traitKey}:${trait.traitValue}`);
			if (usedCold + cost <= coldBudget) {
				trimmedProfile.push(trait);
				usedCold += cost;
			}
		}
		coldTokens = usedCold;
	}
	const total = coldTokens + warmTokens + hotTokens;
	return {
		cold: {
			userProfile: trimmedProfile,
			peerInstructions: coldResult.peerInstructions,
			sigilCard: coldResult.sigilCard ?? null
		},
		warm: {
			peerLearnings: filteredWarmResult.peerLearnings,
			peerPatterns: filteredWarmResult.peerPatterns,
			decisions: filteredWarmResult.decisions
		},
		hot: {
			sessionNarrative: hotResult.sessionNarrative,
			recentObservations: trimmedObservations,
			activeTasks: trimmedTasks
		},
		tokenCounts: {
			cold: coldTokens,
			warm: warmTokens,
			hot: hotTokens,
			total
		}
	};
}
//#endregion
//#region ../core/dist/memory/retrieval/get-current-session-id.js
/**
* Get the CALLER's current session ID, env-first (T11344 · Epic T11284).
*
* Best-effort: returns undefined when no session can be resolved or the store
* is unavailable. Used by logRetrieval to group memory retrievals by session.
*
* T11344 — routes through the canonical `resolveCurrentSessionId` (env-first)
* instead of `sessionStatus` (most-recent active row). This is the memory
* scope-leakage fix: a spawned agent's memory retrievals are now grouped under
* ITS `CLEO_SESSION_ID`, not under whichever session last touched the DB.
*
* @param projectRoot - Project root directory
* @returns Current session ID or undefined if unavailable
* @task T11344
*/
async function getCurrentSessionId(projectRoot) {
	try {
		const { resolveCurrentSessionId } = await import('./session-store2-q55969ZP.js');
		return await resolveCurrentSessionId(projectRoot) ?? void 0;
	} catch {
		return;
	}
}
//#endregion
//#region ../core/dist/memory/retrieval/increment-citation-counts.js
/**
* Increment citationCount for a list of entry IDs.
*
* Routes each ID to the correct table based on its ID prefix. All updates
* are best-effort — errors are silently swallowed.
*
* @param projectRoot - Project root for brain.db resolution
* @param ids - Entry IDs whose citation counts should be incremented
*/
async function incrementCitationCounts(projectRoot, ids) {
	if (ids.length === 0) return;
	const { getBrainDb, getBrainNativeDb } = await import('./memory-sqlite-Dg5uGJCo.js');
	await getBrainDb(projectRoot);
	const nativeDb = getBrainNativeDb();
	if (!nativeDb) return;
	const now = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
	for (const id of ids) {
		let table;
		if (id.startsWith("D-") || /^D\d/.test(id)) table = "brain_decisions";
		else if (id.startsWith("P-") || /^P\d/.test(id)) table = "brain_patterns";
		else if (id.startsWith("L-") || /^L\d/.test(id)) table = "brain_learnings";
		else table = "brain_observations";
		try {
			nativeDb.prepare(`UPDATE ${table} SET citation_count = citation_count + 1, updated_at = ? WHERE id = ?`).run(now, id);
		} catch {}
	}
}
//#endregion
//#region ../core/dist/memory/retrieval/log-retrieval.js
/**
* Log a retrieval event to brain_retrieval_log for co-retrieval analysis.
*
* Creates the table on first use if it doesn't exist (self-healing).
* Best-effort: errors are silently swallowed.
*
* @param projectRoot - Project root directory
* @param query - The search query or fetch IDs
* @param entryIds - Array of entry IDs returned in this retrieval
* @param source - Retrieval source ('find', 'fetch', 'hybrid', 'timeline', 'budget')
* @param tokensUsed - Estimated tokens consumed (optional)
* @param sessionId - Session ID for grouping retrievals by session (optional, soft FK to tasks.db)
*/
async function logRetrieval(projectRoot, query, entryIds, source, tokensUsed, sessionId) {
	if (entryIds.length === 0) return;
	const { getBrainDb, getBrainNativeDb } = await import('./memory-sqlite-Dg5uGJCo.js');
	await getBrainDb(projectRoot);
	const nativeDb = getBrainNativeDb();
	if (!nativeDb) return;
	const createSql = "CREATE TABLE IF NOT EXISTS brain_retrieval_log (id INTEGER PRIMARY KEY AUTOINCREMENT,query TEXT NOT NULL,entry_ids TEXT NOT NULL,entry_count INTEGER NOT NULL,source TEXT NOT NULL,tokens_used INTEGER,session_id TEXT,created_at TEXT NOT NULL DEFAULT (datetime('now')))";
	try {
		nativeDb.prepare(createSql).run();
	} catch {
		return;
	}
	try {
		nativeDb.prepare("INSERT INTO brain_retrieval_log (query, entry_ids, entry_count, source, tokens_used, session_id) VALUES (?, ?, ?, ?, ?, ?)").run(query, JSON.stringify(entryIds), entryIds.length, source, tokensUsed ?? null, sessionId ?? null);
	} catch {}
}
//#endregion
//#region ../core/dist/memory/retrieval/search.js
/**
* BRAIN Search — Layer 1 compact search + budget-aware hybrid retrieval.
*
* Provides two search entry points:
* - searchBrainCompact: token-efficient index-level search (~50 tokens/hit)
* - retrieveWithBudget: multi-strategy (FTS5 + vector + graph) within a token budget
*
* @task T5131
* @epic T5149
*/
/**
* Token-efficient compact search across BRAIN tables.
* Returns index-level hits (~50 tokens per result).
*
* Delegates to searchBrain() from brain-search.ts for FTS5/LIKE search,
* then projects results to a compact format with optional date filtering.
*
* @param projectRoot - Project root directory
* @param params - Search parameters
* @returns Compact search results with token estimate
*
* @example
* ```ts
* // Search for observations related to authentication decisions.
* // Returns compact hits (~50 tokens each) from BRAIN tables.
* const result = await searchBrainCompact('/path/to/project', {
*   query: 'authentication decisions',
*   limit: 5,
*   tables: ['decisions', 'observations'],
* });
*
* // Result shape: { results: BrainCompactHit[], total: number, tokensEstimated: number }
* console.assert(typeof result.total === 'number', 'total is a number');
* console.assert(Array.isArray(result.results), 'results is an array');
* console.assert(typeof result.tokensEstimated === 'number', 'tokensEstimated present');
* ```
*/
async function searchBrainCompact(projectRoot, params) {
	const { query, limit, tables, dateStart, dateEnd, agent, useRRF = true, peerId, includeGlobal, mode, since } = params;
	if (!query?.trim()) return {
		results: [],
		total: 0,
		tokensEstimated: 0
	};
	const effectiveLimit = limit ?? 10;
	const agentFilter = agent !== void 0 && agent !== null;
	if (mode === "recency" && !agentFilter) {
		const { getBrainDb, getBrainNativeDb } = await import('./memory-sqlite-Dg5uGJCo.js');
		await getBrainDb(projectRoot);
		const nativeDb = getBrainNativeDb();
		if (!nativeDb) return {
			results: [],
			total: 0,
			tokensEstimated: 0
		};
		const targetTables = tables && tables.length > 0 ? tables : [
			"observations",
			"learnings",
			"patterns",
			"decisions"
		];
		const sinceClause = since ? ` AND created_at >= '${since}'` : "";
		const dateStartClause = dateStart ? ` AND created_at >= '${dateStart}'` : "";
		const dateEndClause = dateEnd ? ` AND created_at <= '${dateEnd}'` : "";
		const perTableLimit = effectiveLimit * 2;
		const results = [];
		for (const table of targetTables) {
			let sql;
			if (table === "observations") sql = `SELECT id, title, created_at FROM brain_observations WHERE 1=1${sinceClause}${dateStartClause}${dateEndClause} ORDER BY created_at DESC LIMIT ${perTableLimit}`;
			else if (table === "learnings") sql = `SELECT id, insight AS title, created_at FROM brain_learnings WHERE 1=1${sinceClause}${dateStartClause}${dateEndClause} ORDER BY created_at DESC LIMIT ${perTableLimit}`;
			else if (table === "patterns") sql = `SELECT id, pattern AS title, extracted_at AS created_at FROM brain_patterns WHERE 1=1${since ? ` AND extracted_at >= '${since}'` : ""}${dateStart ? ` AND extracted_at >= '${dateStart}'` : ""}${dateEnd ? ` AND extracted_at <= '${dateEnd}'` : ""} ORDER BY extracted_at DESC LIMIT ${perTableLimit}`;
			else sql = `SELECT id, decision AS title, created_at FROM brain_decisions WHERE 1=1${sinceClause}${dateStartClause}${dateEndClause} ORDER BY created_at DESC LIMIT ${perTableLimit}`;
			try {
				const rows = nativeDb.prepare(sql).all();
				for (const row of rows) results.push({
					id: row.id,
					type: table.replace(/s$/, ""),
					title: (row.title ?? "").slice(0, 80),
					date: row.created_at ?? "",
					relevance: 0
				});
			} catch {}
		}
		results.sort((a, b) => b.date > a.date ? 1 : b.date < a.date ? -1 : 0);
		const trimmed = results.slice(0, effectiveLimit);
		for (const hit of trimmed) hit._next = memoryFindHitNext(hit.id);
		return {
			results: trimmed,
			total: trimmed.length,
			tokensEstimated: trimmed.length * 50
		};
	}
	if (useRRF && !agentFilter && mode !== "lexical" || mode === "hybrid" && !agentFilter) {
		const [ftsResult, rrfResults] = await Promise.all([searchBrain(projectRoot, query, {
			limit: effectiveLimit * 3,
			tables,
			peerId,
			includeGlobal
		}).catch(() => ({
			decisions: [],
			patterns: [],
			learnings: [],
			observations: []
		})), hybridSearch(query, projectRoot, { limit: effectiveLimit * 2 })]);
		const dateMap = /* @__PURE__ */ new Map();
		for (const d of ftsResult.decisions) {
			const raw = d;
			dateMap.set(d.id, (d.createdAt ?? raw["created_at"]) || "");
		}
		for (const p of ftsResult.patterns) {
			const raw = p;
			dateMap.set(p.id, (p.extractedAt ?? raw["extracted_at"]) || "");
		}
		for (const l of ftsResult.learnings) {
			const raw = l;
			dateMap.set(l.id, (l.createdAt ?? raw["created_at"]) || "");
		}
		for (const o of ftsResult.observations) {
			const raw = o;
			dateMap.set(o.id, (o.createdAt ?? raw["created_at"]) || "");
		}
		const singularToTable = {
			decision: "decisions",
			pattern: "patterns",
			learning: "learnings",
			observation: "observations"
		};
		const ftsRanks = rrfResults.map((r) => r.ftsRank ?? void 0).filter((v) => v !== void 0);
		const maxFtsRank = ftsRanks.length > 0 ? Math.max(...ftsRanks) : 0;
		const rrfScores = rrfResults.map((r) => r.score);
		const minRrf = rrfScores.length > 0 ? Math.min(...rrfScores) : 0;
		const rrfRange = (rrfScores.length > 0 ? Math.max(...rrfScores) : 0) - minRrf;
		let results = rrfResults.map((r) => {
			const bm25Score = r.ftsRank !== void 0 ? 1 - (maxFtsRank > 0 ? r.ftsRank / maxFtsRank : 0) : 0;
			const rrfScore = r.score;
			const relevance = rrfRange > 0 ? (r.score - minRrf) / rrfRange : r.score;
			return {
				id: r.id,
				type: r.type,
				title: r.title.slice(0, 80),
				date: dateMap.get(r.id) ?? "",
				relevance,
				rrfScore,
				bm25Score
			};
		}).filter((r) => {
			return dateMap.has(r.id);
		});
		if (tables && tables.length > 0) results = results.filter((r) => tables.includes(singularToTable[r.type]));
		if (since) results = results.filter((r) => !r.date || r.date >= since);
		if (dateStart) results = results.filter((r) => !r.date || r.date >= dateStart);
		if (dateEnd) results = results.filter((r) => !r.date || r.date <= dateEnd);
		results = results.slice(0, effectiveLimit);
		for (const hit of results) hit._next = memoryFindHitNext(hit.id);
		if (results.length > 0) {
			const returnedIds = results.map((r) => r.id);
			setImmediate(() => {
				incrementCitationCounts(projectRoot, returnedIds).catch(() => {});
				getCurrentSessionId(projectRoot).then((sessionId) => {
					return logRetrieval(projectRoot, query, returnedIds, "find-rrf", results.length * 50, sessionId);
				}).catch(() => {});
			});
		}
		return {
			results,
			total: results.length,
			tokensEstimated: results.length * 50
		};
	}
	const searchResult = await searchBrain(projectRoot, query, {
		limit: effectiveLimit,
		tables: agentFilter ? ["observations"] : tables,
		peerId,
		includeGlobal
	});
	let results = [];
	if (!agentFilter) {
		for (const d of searchResult.decisions) {
			const raw = d;
			results.push({
				id: d.id,
				type: "decision",
				title: d.decision.slice(0, 80),
				date: (d.createdAt ?? raw["created_at"]) || ""
			});
		}
		for (const p of searchResult.patterns) {
			const raw = p;
			results.push({
				id: p.id,
				type: "pattern",
				title: p.pattern.slice(0, 80),
				date: (p.extractedAt ?? raw["extracted_at"]) || ""
			});
		}
		for (const l of searchResult.learnings) {
			const raw = l;
			results.push({
				id: l.id,
				type: "learning",
				title: l.insight.slice(0, 80),
				date: (l.createdAt ?? raw["created_at"]) || ""
			});
		}
	}
	for (const o of searchResult.observations) {
		const raw = o;
		if (agentFilter) {
			if ((o.agent ?? raw["agent"] ?? null) !== agent) continue;
		}
		results.push({
			id: o.id,
			type: "observation",
			title: o.title.slice(0, 80),
			date: (o.createdAt ?? raw["created_at"]) || ""
		});
	}
	if (since) results = results.filter((r) => r.date >= since);
	if (dateStart) results = results.filter((r) => r.date >= dateStart);
	if (dateEnd) results = results.filter((r) => r.date <= dateEnd);
	for (const hit of results) hit._next = memoryFindHitNext(hit.id);
	if (results.length > 0) {
		const returnedIds = results.map((r) => r.id);
		setImmediate(() => {
			incrementCitationCounts(projectRoot, returnedIds).catch(() => {});
			getCurrentSessionId(projectRoot).then((sessionId) => {
				return logRetrieval(projectRoot, query, returnedIds, "find", results.length * 50, sessionId);
			}).catch(() => {});
		});
	}
	return {
		results,
		total: results.length,
		tokensEstimated: results.length * 50
	};
}

export { buildRetrievalBundle, observeBrain, searchBrainCompact };
//# sourceMappingURL=brain-retrieval2-CM6hsYog.js.map
