import { e as getBrainDb, d as getBrainNativeDb } from './sqlite-Dsbe0wec.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:crypto';
import 'node:process';
import 'node:async_hooks';
import './dual-scope-db-ATrwq0LH.js';
import './indexes-aYlULWG3.js';
import './utils-BvHPJOVk.js';
import './conduit-Ca_OFWR_.js';
import './unique-constraint-BM-Apx1H.js';
import './memory-schema-Bi7cChwo.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';

//#region ../core/dist/memory/brain-doctor.js
/**
* Brain noise detector — T1262 memory-doctor (read-only, parallel to E1).
*
* Inspects `.cleo/brain.db` for known noise patterns without modifying any
* data. The detector is a prerequisite for the W7 shadow-write sweep
* (T1147 / v2026.4.132) and the M7 assert-clean gate that guards Sentient v1
* activation (T1148 / v2026.4.133).
*
* **Read-only contract** — this module MUST NOT write to brain.db or any
* other persistent store. All operations are SELECT-only. The sweep
* (mutation) phase ships in T1147 W7 under a shadow-write envelope.
*
* ## Noise pattern catalogue
*
* | Pattern | Description | Detectable via |
* |---------|-------------|----------------|
* | `duplicate-content` | Entries with identical `content` hash across different IDs | SHA-256 content comparison |
* | `missing-type` | Entries where `type` is NULL or empty string | NULL/empty check |
* | `missing-provenance` | Entries where `provenance` is NULL (unverified source) | NULL check |
* | `orphan-edge` | Brain graph edges pointing to non-existent nodes | JOIN gap |
* | `low-confidence` | `confidence < 0.1` entries (near-zero signal, likely noise) | threshold check |
* | `stale-unverified` | Unverified entries older than 90 days with zero retrieval count | age + retrieval join |
*
* @module memory/brain-doctor
* @task T1262 memory-doctor detector (E1-parallel, read-only)
* @task T1258 E1 canonical naming refactor
* @see T1147 W7 for the mutator sweep that acts on these findings
* @see T1148 W8 M7 gate — `cleo memory doctor --assert-clean` must exit 0 before Sentient v1
*/
/** Entries older than this (in days) with zero retrievals are flagged as stale. */
var STALE_AGE_DAYS = 90;
/** Entries with confidence below this threshold are flagged as low-confidence noise. */
var LOW_CONFIDENCE_THRESHOLD = .1;
/**
* Collect sample IDs (up to 5) from a SQLite query result.
*
* @param rows - Array of SQLite row objects with at least an `id` field.
* @returns Array of up to 5 id strings.
*/
function sampleIds(rows) {
	return rows.slice(0, 5).map((r) => r.id ?? "unknown").filter((id) => id !== "unknown");
}
/**
* Run a read-only noise scan over `.cleo/brain.db` and return a structured
* findings report.
*
* This function is intentionally side-effect-free: it opens brain.db in
* read-only mode (via `getBrainNativeDb`) and only runs SELECT queries.
* The caller bears responsibility for surfacing or acting on the findings.
*
* @param projectRoot - Absolute path to the CLEO project root.
* @returns A {@link BrainDoctorResult} describing all detected noise.
*
* @example
* ```typescript
* const result = await scanBrainNoise('/mnt/projects/cleocode');
* if (!result.isClean) {
*   console.warn(`Brain noise detected: ${result.findings.length} patterns`);
*   for (const f of result.findings) {
*     console.warn(`  ${f.pattern}: ${f.count} entries — ${f.description}`);
*   }
* }
* ```
*
* @task T1262
*/
async function scanBrainNoise(projectRoot) {
	await getBrainDb(projectRoot);
	const db = getBrainNativeDb();
	const findings = [];
	if (!db) return {
		totalScanned: 0,
		findings: [],
		isClean: true,
		scannedAt: (/* @__PURE__ */ new Date()).toISOString()
	};
	try {
		const tables = [
			"brain_observations",
			"brain_decisions",
			"brain_patterns",
			"brain_learnings"
		];
		let totalScanned = 0;
		for (const table of tables) try {
			const row = db.prepare(`SELECT COUNT(*) as c FROM ${table}`).get();
			totalScanned += row?.c ?? 0;
		} catch {}
		{
			const rows = [];
			for (const table of tables) try {
				const res = db.prepare(`SELECT id FROM ${table} WHERE type IS NULL OR type = '' LIMIT 20`).all();
				rows.push(...res);
			} catch {}
			if (rows.length > 0) findings.push({
				pattern: "missing-type",
				count: rows.length,
				sampleIds: sampleIds(rows),
				description: "Entries with NULL or empty type field — type is required for retrieval routing."
			});
		}
		{
			const rows = [];
			for (const table of tables) try {
				const res = db.prepare(`SELECT id FROM ${table} WHERE provenance IS NULL LIMIT 20`).all();
				rows.push(...res);
			} catch {}
			if (rows.length > 0) findings.push({
				pattern: "missing-provenance",
				count: rows.length,
				sampleIds: sampleIds(rows),
				description: "Entries with NULL provenance — source cannot be verified for retrieval integrity."
			});
		}
		{
			const rows = [];
			for (const table of tables) try {
				const res = db.prepare(`SELECT id FROM ${table} WHERE confidence IS NOT NULL AND confidence < ? LIMIT 20`).all(LOW_CONFIDENCE_THRESHOLD);
				rows.push(...res);
			} catch {}
			if (rows.length > 0) findings.push({
				pattern: "low-confidence",
				count: rows.length,
				sampleIds: sampleIds(rows),
				description: `Entries with confidence < ${LOW_CONFIDENCE_THRESHOLD} — near-zero signal, likely noise.`
			});
		}
		{
			const staleThreshold = /* @__PURE__ */ new Date();
			staleThreshold.setDate(staleThreshold.getDate() - STALE_AGE_DAYS);
			const staleIso = staleThreshold.toISOString();
			const rows = [];
			for (const table of tables) try {
				const res = db.prepare(`SELECT id FROM ${table}
               WHERE verified = 0
                 AND created_at < ?
               LIMIT 20`).all(staleIso);
				rows.push(...res);
			} catch {}
			if (rows.length > 0) findings.push({
				pattern: "stale-unverified",
				count: rows.length,
				sampleIds: sampleIds(rows),
				description: `Unverified entries older than ${STALE_AGE_DAYS} days — likely outdated observations.`
			});
		}
		{
			const rows = [];
			for (const table of tables) try {
				const res = db.prepare(`SELECT id FROM ${table}
               WHERE content IN (
                 SELECT content FROM ${table}
                 WHERE content IS NOT NULL
                 GROUP BY content HAVING COUNT(*) > 1
               ) LIMIT 20`).all();
				rows.push(...res);
			} catch {}
			if (rows.length > 0) findings.push({
				pattern: "duplicate-content",
				count: rows.length,
				sampleIds: sampleIds(rows),
				description: "Entries sharing identical content — duplicates inflate retrieval scores."
			});
		}
		try {
			const rows = db.prepare(`SELECT e.id FROM brain_edges e
             LEFT JOIN brain_nodes src ON src.id = e.source_id
             LEFT JOIN brain_nodes tgt ON tgt.id = e.target_id
             WHERE src.id IS NULL OR tgt.id IS NULL
             LIMIT 20`).all();
			if (rows.length > 0) findings.push({
				pattern: "orphan-edge",
				count: rows.length,
				sampleIds: sampleIds(rows),
				description: "Brain graph edges pointing to non-existent nodes — referential integrity violation."
			});
		} catch {}
		const autoExtractHealth = computeAutoExtractHealth(db);
		const provenanceDistribution = computeProvenanceDistribution(db);
		return {
			totalScanned,
			findings,
			isClean: findings.length === 0,
			scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
			autoExtractHealth,
			provenanceDistribution
		};
	} catch {
		return {
			totalScanned: 0,
			findings: [],
			isClean: true,
			scannedAt: (/* @__PURE__ */ new Date()).toISOString()
		};
	}
}
/**
* Compute auto-extract pipeline health from a live brain.db connection.
*
* Queries observation/learning counts plus brain_promotion_log fulfillment stats.
* Returns undefined when the required tables are not available.
*
* @param db - Native database instance from getBrainNativeDb (accepts DatabaseSync or compatible)
*/
function computeAutoExtractHealth(db) {
	if (!db) return void 0;
	const nativeDb = db;
	try {
		const observationCount = nativeDb.prepare(`SELECT COUNT(*) AS cnt FROM brain_observations WHERE invalid_at IS NULL`).get()?.cnt ?? 0;
		const learningCount = nativeDb.prepare(`SELECT COUNT(*) AS cnt FROM brain_learnings WHERE invalid_at IS NULL`).get()?.cnt ?? 0;
		let pendingPromotions = 0;
		let fulfilledPromotions = 0;
		try {
			pendingPromotions = nativeDb.prepare(`SELECT COUNT(*) AS cnt FROM brain_promotion_log WHERE fulfilled_at IS NULL`).get()?.cnt ?? 0;
			fulfilledPromotions = nativeDb.prepare(`SELECT COUNT(*) AS cnt FROM brain_promotion_log WHERE fulfilled_at IS NOT NULL`).get()?.cnt ?? 0;
		} catch {}
		let lastConsolidationAt = null;
		try {
			lastConsolidationAt = nativeDb.prepare(`SELECT started_at FROM brain_consolidation_events ORDER BY started_at DESC LIMIT 1`).get()?.started_at ?? null;
		} catch {}
		const extractionRatio = observationCount > 0 ? learningCount / observationCount : 1;
		return {
			observationCount,
			learningCount,
			pendingPromotions,
			fulfilledPromotions,
			extractionRatio,
			lastConsolidationAt,
			healthy: observationCount === 0 || extractionRatio >= .01
		};
	} catch {
		return;
	}
}
/**
* Compute provenance distribution counts from brain_observations.
*
* Returns counts by origin value, validated_at non-null count, and provenance_chain non-null count.
* Returns undefined when the columns do not exist (pre-T1897 database).
*/
function computeProvenanceDistribution(db) {
	if (!db) return void 0;
	const nativeDb = db;
	try {
		const total = nativeDb.prepare(`SELECT COUNT(*) AS cnt FROM brain_observations WHERE invalid_at IS NULL`).get()?.cnt ?? 0;
		const byOrigin = {};
		try {
			const rows = nativeDb.prepare(`SELECT COALESCE(origin, '__null__') AS origin_val, COUNT(*) AS cnt
           FROM brain_observations WHERE invalid_at IS NULL
           GROUP BY origin_val`).all();
			for (const row of rows) byOrigin[row.origin_val === "__null__" ? "(unset)" : row.origin_val] = row.cnt;
		} catch {}
		let verifiedCount = 0;
		try {
			verifiedCount = nativeDb.prepare(`SELECT COUNT(*) AS cnt FROM brain_observations WHERE invalid_at IS NULL AND validated_at IS NOT NULL`).get()?.cnt ?? 0;
		} catch {}
		let derivedCount = 0;
		try {
			derivedCount = nativeDb.prepare(`SELECT COUNT(*) AS cnt FROM brain_observations WHERE invalid_at IS NULL AND provenance_chain IS NOT NULL`).get()?.cnt ?? 0;
		} catch {}
		return {
			total,
			byOrigin,
			verifiedCount,
			derivedCount
		};
	} catch {
		return;
	}
}

export { scanBrainNoise };
//# sourceMappingURL=brain-doctor-BVUWGUKG.js.map
