import {
  countRecallTokenOverlap,
  normalizeRecallTokens
} from "./chunk-DT5TVLJE.js";
import {
  StorageManager
} from "./chunk-DCE6SQLA.js";
import {
  getCachedRuleMemories,
  setCachedRuleMemories
} from "./chunk-PFV5C235.js";

// src/semantic-rule-verifier.ts
var DEFAULT_MIN_EFFECTIVE_CONFIDENCE = 0.45;
function verificationConfidenceMultiplier(status) {
  switch (status) {
    case "verified":
      return 1;
    case "source-memory-not-episode":
      return 0.45;
    case "source-memory-archived":
      return 0.4;
    case "source-memory-forgotten":
      return 0.3;
    case "source-memory-missing":
      return 0.35;
    default:
      return 0.35;
  }
}
function resolveVerificationStatus(sourceMemory) {
  if (!sourceMemory) return "source-memory-missing";
  if (sourceMemory.frontmatter.status === "archived") {
    return "source-memory-archived";
  }
  if (sourceMemory.frontmatter.status === "forgotten") return "source-memory-forgotten";
  if (sourceMemory.frontmatter.memoryKind !== "episode") return "source-memory-not-episode";
  return "verified";
}
function resolveEffectiveConfidence(rule, sourceMemory) {
  const status = resolveVerificationStatus(sourceMemory);
  const ruleConfidence = Number.isFinite(rule.frontmatter.confidence) ? rule.frontmatter.confidence : 0.8;
  const sourceConfidence = Number.isFinite(sourceMemory?.frontmatter.confidence) ? sourceMemory.frontmatter.confidence : ruleConfidence;
  const anchoredConfidence = Math.min(ruleConfidence, sourceConfidence);
  const effectiveConfidence = Math.max(
    0,
    Math.min(1, anchoredConfidence * verificationConfidenceMultiplier(status))
  );
  return { status, effectiveConfidence };
}
function scoreVerifiedSemanticRuleCandidate(rule, sourceMemory, queryTokens, effectiveConfidence) {
  const matchedFields = /* @__PURE__ */ new Set();
  let score = 0;
  const ruleContentMatches = countRecallTokenOverlap(queryTokens, rule.content);
  if (ruleContentMatches > 0) {
    score += ruleContentMatches * 5;
    matchedFields.add("ruleContent");
  }
  const tagMatches = countRecallTokenOverlap(queryTokens, rule.frontmatter.tags?.join(" "));
  if (tagMatches > 0) {
    score += tagMatches * 2;
    matchedFields.add("tags");
  }
  const sourceContentMatches = countRecallTokenOverlap(queryTokens, sourceMemory?.content);
  if (sourceContentMatches > 0) {
    score += sourceContentMatches * 2;
    matchedFields.add("sourceContent");
  }
  if (score > 0) {
    score += effectiveConfidence;
  }
  return { score, matchedFields };
}
async function searchVerifiedSemanticRules(options) {
  const queryTokens = new Set(normalizeRecallTokens(options.query, ["what", "which"]));
  if (queryTokens.size === 0 || options.maxResults <= 0) return [];
  const storage = new StorageManager(options.memoryDir);
  const version = storage.getMemoryStatusVersion();
  let cachedRules = getCachedRuleMemories(storage.dir, version);
  if (!cachedRules) {
    const allMems = await storage.readAllMemories();
    cachedRules = setCachedRuleMemories(storage.dir, allMems, version);
  }
  const { all: ruleMemories, byId: memoryById } = cachedRules;
  const minEffectiveConfidence = options.minEffectiveConfidence ?? DEFAULT_MIN_EFFECTIVE_CONFIDENCE;
  const candidates = [];
  for (const memory of ruleMemories) {
    if (memory.frontmatter.source !== "semantic-rule-promotion") continue;
    const sourceMemoryId = memory.frontmatter.sourceMemoryId;
    if (!sourceMemoryId) continue;
    const sourceMemory = memoryById.get(sourceMemoryId);
    const { status, effectiveConfidence } = resolveEffectiveConfidence(memory, sourceMemory);
    if (effectiveConfidence < minEffectiveConfidence) continue;
    const { score, matchedFields } = scoreVerifiedSemanticRuleCandidate(
      memory,
      sourceMemory,
      queryTokens,
      effectiveConfidence
    );
    if (score <= 0) continue;
    candidates.push({
      rule: memory,
      score,
      sourceMemoryId,
      verificationStatus: status,
      effectiveConfidence,
      matchedFields: [...matchedFields].sort()
    });
  }
  return candidates.sort(
    (left, right) => right.score - left.score || right.effectiveConfidence - left.effectiveConfidence || right.rule.frontmatter.updated.localeCompare(left.rule.frontmatter.updated)
  ).slice(0, options.maxResults);
}

export {
  searchVerifiedSemanticRules
};
//# sourceMappingURL=chunk-L5IIGA5V.js.map