import { g as getBrainAccessor } from './memory-accessor2-BzlgmY-Z.js';
import { u as upsertGraphNode } from './graph-auto-populate2-DYsUNGSL.js';
import { c as computeLearningQuality } from './quality-scoring-CCPuRQmJ.js';
import { d as detectSupersession, s as supersedeMemory } from './temporal-supersession-BZ46j30w.js';
import { createHash, randomBytes } from 'node:crypto';

//#region ../core/dist/memory/learnings.js
/**
* Learning Memory system for CLEO BRAIN.
*
* Records, queries, and applies accumulated insights from
* historical task data (completion rates, blocker patterns, epic sizes).
*
* Storage: SQLite brain_learnings table per ADR-009 Section 3.2.
*
* @task T4769, T5241
* @epic T4763
*/
/**
* Generate a learning ID.
*/
function generateLearningId() {
	return `L-${randomBytes(4).toString("hex")}`;
}
/**
* Store a new learning.
* @task T4769, T5241
*/
async function storeLearning(projectRoot, params) {
	if (!params.insight?.trim()) throw new Error("Insight text is required");
	if (!params.source?.trim()) throw new Error("Source is required");
	if (params.confidence < 0 || params.confidence > 1) throw new Error("Confidence must be between 0.0 and 1.0");
	if (!params._skipGate) {
		const { verifyCandidate } = await import('./extraction-gate-Ctn6QtD_.js');
		const isManualSrc = params.source.includes("manual") || params.source.includes("owner");
		const isTranscriptSrc = params.source.includes("transcript:ses_");
		const sourceConf = isManualSrc ? "owner" : isTranscriptSrc ? "speculative" : "agent";
		const gateResult = await verifyCandidate(projectRoot, {
			text: params.insight.trim(),
			memoryType: "semantic",
			tier: isManualSrc ? "medium" : "short",
			confidence: params.confidence,
			source: isManualSrc ? "manual" : "transcript",
			sourceConfidence: sourceConf,
			trusted: isManualSrc
		});
		if (gateResult.action !== "stored") {
			const existing = gateResult.id ? await (await getBrainAccessor(projectRoot)).getLearning(gateResult.id).catch(() => null) : null;
			if (existing) return {
				...existing,
				applicableTypes: JSON.parse(existing.applicableTypesJson || "[]")
			};
			return {
				id: gateResult.id ?? "",
				insight: params.insight.trim(),
				source: params.source,
				confidence: params.confidence,
				actionable: params.actionable ?? false,
				application: params.application ?? null,
				applicableTypesJson: "[]",
				applicableTypes: [],
				qualityScore: 0,
				memoryTier: "short",
				memoryType: "semantic",
				sourceConfidence: sourceConf,
				verified: false,
				contentHash: "",
				createdAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19),
				updatedAt: null,
				tierPromotedAt: null,
				tierPromotionReason: null,
				invalidAt: null,
				pruneCandidateAt: null,
				citationCount: 0,
				pruneCandidate: false
			};
		}
	}
	const accessor = await getBrainAccessor(projectRoot);
	const existingLearnings = await accessor.findLearnings();
	const normalizedInput = params.insight.trim().toLowerCase();
	const duplicate = existingLearnings.find((e) => e.insight.trim().toLowerCase() === normalizedInput);
	if (duplicate) {
		const maxConfidence = Math.max(duplicate.confidence, params.confidence);
		await accessor.updateLearning(duplicate.id, { confidence: maxConfidence });
		const updated = await accessor.getLearning(duplicate.id);
		upsertGraphNode(projectRoot, `learning:${duplicate.id}`, "learning", duplicate.insight.substring(0, 200), duplicate.qualityScore ?? .5, duplicate.insight + (duplicate.application ?? ""), {
			source: duplicate.source,
			confidence: maxConfidence,
			actionable: duplicate.actionable
		}).catch(() => {});
		return {
			...updated,
			applicableTypes: JSON.parse(updated.applicableTypesJson || "[]")
		};
	}
	const isManual = params.source.includes("manual") || params.source.includes("owner");
	const isTranscript = params.source.includes("transcript:ses_");
	const sourceConfidence = isManual ? "owner" : isTranscript ? "speculative" : "agent";
	const memoryTier = isManual ? "medium" : "short";
	const memoryType = isTranscript ? "episodic" : "semantic";
	const verified = isManual;
	const qualityScore = computeLearningQuality({
		confidence: params.confidence,
		actionable: params.actionable ?? false,
		insight: params.insight.trim(),
		application: params.application ?? null,
		sourceConfidence,
		memoryTier
	});
	const contentHashValue = createHash("sha256").update(params.insight.trim().toLowerCase()).digest("hex").slice(0, 16);
	const entry = {
		id: generateLearningId(),
		insight: params.insight.trim(),
		source: params.source.trim(),
		confidence: params.confidence,
		actionable: params.actionable ?? false,
		application: params.application ?? null,
		applicableTypesJson: params.applicableTypes ? JSON.stringify(params.applicableTypes) : "[]",
		qualityScore,
		memoryTier,
		memoryType,
		sourceConfidence,
		verified,
		contentHash: contentHashValue
	};
	const saved = await accessor.addLearning(entry);
	upsertGraphNode(projectRoot, `learning:${saved.id}`, "learning", saved.insight.substring(0, 200), qualityScore, saved.insight + (saved.application ?? ""), {
		source: saved.source,
		confidence: saved.confidence,
		actionable: saved.actionable
	}).catch(() => {});
	if (sourceConfidence === "owner" || sourceConfidence === "task-outcome") detectSupersession(projectRoot, {
		id: saved.id,
		text: saved.insight,
		createdAt: saved.createdAt ?? (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19)
	}).then((candidates) => {
		for (const candidate of candidates) supersedeMemory(projectRoot, candidate.existingId, saved.id, "auto:learning-supersedes — high overlap detected at store time").catch(() => {});
	}).catch(() => {});
	return {
		...saved,
		applicableTypes: JSON.parse(saved.applicableTypesJson || "[]")
	};
}
/**
* Search learnings by criteria.
* Results sorted by confidence (highest first).
* @task T4769, T5241
*/
async function searchLearnings(projectRoot, params = {}) {
	let entries = await (await getBrainAccessor(projectRoot)).findLearnings({
		minConfidence: params.minConfidence,
		actionable: params.actionableOnly,
		limit: params.limit
	});
	if (params.applicableType) entries = entries.filter((e) => {
		return JSON.parse(e.applicableTypesJson || "[]").includes(params.applicableType);
	});
	if (params.query) {
		const q = params.query.toLowerCase();
		entries = entries.filter((e) => e.insight.toLowerCase().includes(q) || e.source.toLowerCase().includes(q) || e.application?.toLowerCase().includes(q));
	}
	entries.sort((a, b) => b.confidence - a.confidence);
	return entries.map((e) => ({
		...e,
		applicableTypes: JSON.parse(e.applicableTypesJson || "[]")
	}));
}

export { searchLearnings as a, storeLearning as s };
//# sourceMappingURL=learnings2-2m2p7lzT.js.map
