import { g as getBrainAccessor } from './memory-accessor2-BzlgmY-Z.js';
import { u as upsertGraphNode } from './graph-auto-populate2-DYsUNGSL.js';
import { a as computePatternQuality } 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/patterns.js
/**
* Pattern Memory system for CLEO BRAIN.
*
* Extracts, stores, and queries workflow/blocker/success/failure/optimization
* patterns from completed tasks and epics.
*
* Storage: SQLite brain_patterns table per ADR-009 Section 3.2.
*
* @task T4768, T5241
* @epic T4763
*/
/**
* Generate a pattern ID.
*/
function generatePatternId() {
	return `P-${randomBytes(4).toString("hex")}`;
}
/**
* Store a new pattern.
* If a similar pattern already exists (same type + matching text), increments frequency.
* @task T4768, T5241
*/
async function storePattern(projectRoot, params) {
	if (!params.pattern?.trim()) throw new Error("Pattern description is required");
	if (!params.context?.trim()) throw new Error("Pattern context is required");
	if (!params._skipGate) {
		const { verifyCandidate } = await import('./extraction-gate-Ctn6QtD_.js');
		const sourceConf = params.source?.startsWith("auto") ?? false ? "speculative" : "agent";
		const gateResult = await verifyCandidate(projectRoot, {
			text: params.pattern.trim(),
			title: params.context.trim().slice(0, 120),
			memoryType: "procedural",
			tier: "medium",
			confidence: .6,
			source: "transcript",
			sourceConfidence: sourceConf
		});
		if (gateResult.action !== "stored") {
			const existing = gateResult.id ? await (await getBrainAccessor(projectRoot)).getPattern(gateResult.id).catch(() => null) : null;
			if (existing) return {
				...existing,
				examples: JSON.parse(existing.examplesJson || "[]")
			};
			const now = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
			return {
				id: gateResult.id ?? "",
				type: params.type,
				pattern: params.pattern.trim(),
				context: params.context.trim(),
				frequency: 1,
				successRate: params.successRate ?? null,
				impact: params.impact ?? null,
				antiPattern: params.antiPattern ?? null,
				mitigation: params.mitigation ?? null,
				examplesJson: "[]",
				examples: [],
				extractedAt: now,
				qualityScore: 0,
				memoryTier: "medium",
				memoryType: "procedural",
				sourceConfidence: sourceConf,
				verified: false,
				contentHash: "",
				tierPromotedAt: null,
				tierPromotionReason: null,
				invalidAt: null,
				pruneCandidateAt: null,
				citationCount: 0,
				pruneCandidate: false
			};
		}
	}
	const accessor = await getBrainAccessor(projectRoot);
	const existingPatterns = await accessor.findPatterns({ type: params.type });
	const normalizedInput = params.pattern.trim().toLowerCase();
	const duplicate = existingPatterns.find((e) => e.pattern.trim().toLowerCase() === normalizedInput);
	const now = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
	if (duplicate) {
		const existingExamples = JSON.parse(duplicate.examplesJson || "[]");
		const newExamples = params.examples ?? [];
		const mergedExamples = Array.from(new Set([...existingExamples, ...newExamples]));
		await accessor.updatePattern(duplicate.id, {
			frequency: duplicate.frequency + 1,
			extractedAt: now,
			examplesJson: JSON.stringify(mergedExamples)
		});
		const updated = await accessor.getPattern(duplicate.id);
		upsertGraphNode(projectRoot, `pattern:${duplicate.id}`, "pattern", duplicate.pattern.substring(0, 200), duplicate.qualityScore ?? .5, duplicate.pattern + duplicate.context, {
			type: duplicate.type,
			impact: duplicate.impact ?? void 0,
			frequency: duplicate.frequency + 1
		}).catch(() => {});
		return {
			...updated,
			examples: mergedExamples
		};
	}
	const memoryTier = "medium";
	const memoryType = "procedural";
	const sourceConfidence = params.source?.startsWith("auto") ? "speculative" : "agent";
	const verified = false;
	const examplesJson = params.examples ? JSON.stringify(params.examples) : "[]";
	const qualityScore = computePatternQuality({
		type: params.type,
		pattern: params.pattern.trim(),
		context: params.context.trim(),
		examples_json: examplesJson,
		sourceConfidence,
		memoryTier
	});
	const contentHashValue = createHash("sha256").update(params.pattern.trim().toLowerCase()).digest("hex").slice(0, 16);
	const entry = {
		id: generatePatternId(),
		type: params.type,
		pattern: params.pattern.trim(),
		context: params.context.trim(),
		frequency: 1,
		successRate: params.successRate ?? null,
		impact: params.impact ?? null,
		antiPattern: params.antiPattern ?? null,
		mitigation: params.mitigation ?? null,
		examplesJson,
		extractedAt: now,
		qualityScore,
		memoryTier,
		memoryType,
		sourceConfidence,
		verified,
		contentHash: contentHashValue
	};
	const saved = await accessor.addPattern(entry);
	upsertGraphNode(projectRoot, `pattern:${saved.id}`, "pattern", saved.pattern.substring(0, 200), qualityScore, saved.pattern + saved.context, {
		type: saved.type,
		impact: saved.impact ?? void 0
	}).catch(() => {});
	if (sourceConfidence === "owner" || sourceConfidence === "task-outcome") detectSupersession(projectRoot, {
		id: saved.id,
		text: saved.pattern + " " + saved.context,
		createdAt: saved.extractedAt ?? (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19)
	}).then((candidates) => {
		for (const candidate of candidates) supersedeMemory(projectRoot, candidate.existingId, saved.id, "auto:pattern-supersedes — high overlap detected at store time").catch(() => {});
	}).catch(() => {});
	return {
		...saved,
		examples: JSON.parse(saved.examplesJson || "[]")
	};
}
/**
* Search patterns by criteria.
* @task T4768, T5241
*/
async function searchPatterns(projectRoot, params = {}) {
	let entries = await (await getBrainAccessor(projectRoot)).findPatterns({
		type: params.type,
		impact: params.impact,
		minFrequency: params.minFrequency,
		limit: params.limit
	});
	if (params.query) {
		const q = params.query.toLowerCase();
		entries = entries.filter((e) => e.pattern.toLowerCase().includes(q) || e.context.toLowerCase().includes(q) || e.antiPattern?.toLowerCase().includes(q) || e.mitigation?.toLowerCase().includes(q));
	}
	return entries.map((e) => ({
		...e,
		examples: JSON.parse(e.examplesJson || "[]")
	}));
}

export { searchPatterns as a, storePattern as s };
//# sourceMappingURL=patterns2-DYKfsbwN.js.map
