import {
  runConsolidationProvenanceCheck
} from "./chunk-5HRY2WRF.js";
import {
  reportBufferSurpriseDistribution
} from "./chunk-ASAITVLA.js";
import {
  NamespaceStorageRouter,
  namespaceCollectionName
} from "./chunk-57QNCUEZ.js";
import {
  analyzeSessionIntegrity,
  applySessionRepair,
  planSessionRepair
} from "./chunk-YRMVARQP.js";
import {
  resolveRemnicPluginEntry
} from "./chunk-U66YHYC7.js";
import {
  createEvalBaselineSnapshot,
  getEvalHarnessStatus,
  runEvalBaselineDeltaReport,
  runEvalBenchmarkCiGate,
  validateEvalBenchmarkPack
} from "./chunk-K6WK37A6.js";
import {
  readJudgeVerdictStats
} from "./chunk-AJU4PJGY.js";
import {
  resolveCuratedIncludeFilesStatePath,
  resolveNativeKnowledgeStatePath,
  resolveOpenClawWorkspaceStatePath
} from "./chunk-7SEAZFFB.js";
import {
  parseConfig
} from "./chunk-6Z6UH6TK.js";
import {
  listMemoryGovernanceRuns,
  readMemoryGovernanceRunArtifact
} from "./chunk-EYNQTST2.js";
import {
  isSafeRouteNamespace
} from "./chunk-2LGMW3DJ.js";
import {
  analyzeGraphHealth
} from "./chunk-RK2Y4XOM.js";
import {
  StorageManager
} from "./chunk-MCC6KDQF.js";
import {
  lintWorkspaceFiles
} from "./chunk-DM2T26WE.js";
import {
  readEnvVar,
  resolveHomeDir
} from "./chunk-MARWOCVP.js";

// src/operator-toolkit.ts
import path2 from "path";
import { constants as fsConstants } from "fs";
import { access as access2, mkdir as mkdir2, readFile, readdir as readdir2, stat, unlink, writeFile } from "fs/promises";

// src/namespaces/migrate.ts
import path from "path";
import { access, mkdir, readdir, rename } from "fs/promises";
var LEGACY_NAMESPACE_CHILDREN = [
  "facts",
  "corrections",
  "entities",
  "questions",
  "artifacts",
  "identity",
  "state",
  "config",
  "summaries",
  "procedures",
  // Issue #564 PR 3: reasoning_trace memories live in their own subtree.
  // Must be included here so namespace migration moves existing traces
  // into the target namespace root alongside other memory data.
  "reasoning-traces",
  "profile.md"
];
async function exists(p) {
  try {
    await access(p);
    return true;
  } catch {
    return false;
  }
}
async function hasAnyLegacyData(rootDir) {
  for (const child of LEGACY_NAMESPACE_CHILDREN) {
    if (await exists(path.join(rootDir, child))) return true;
  }
  return false;
}
async function discoverConfiguredNamespaces(config) {
  const discovered = /* @__PURE__ */ new Set([
    config.defaultNamespace,
    config.sharedNamespace,
    ...config.namespacePolicies.map((policy) => policy.name)
  ]);
  const namespacesDir = path.join(config.memoryDir, "namespaces");
  try {
    const entries = await readdir(namespacesDir, { withFileTypes: true });
    for (const entry of entries) {
      if (entry.isDirectory() && isSafeRouteNamespace(entry.name)) {
        discovered.add(entry.name);
      }
    }
  } catch {
  }
  return [...discovered];
}
async function listNamespaces(options) {
  const storageRouter = options.storageRouter ?? new NamespaceStorageRouter(options.config);
  const namespaces = await discoverConfiguredNamespaces(options.config);
  const items = await Promise.all(
    namespaces.map(async (namespace) => {
      const storage = await storageRouter.storageFor(namespace);
      const usesLegacyRoot = namespace === options.config.defaultNamespace && storage.dir === options.config.memoryDir;
      return {
        namespace,
        rootDir: storage.dir,
        exists: await exists(storage.dir),
        usesLegacyRoot,
        hasMemoryData: await hasAnyLegacyData(storage.dir),
        collection: namespaceCollectionName(options.config.qmdCollection, namespace, {
          defaultNamespace: options.config.defaultNamespace,
          useLegacyDefaultCollection: usesLegacyRoot
        })
      };
    })
  );
  return items.sort((a, b) => a.namespace.localeCompare(b.namespace));
}
async function verifyNamespaces(options) {
  const namespaces = await listNamespaces(options);
  const problems = [];
  for (const entry of namespaces) {
    if (entry.exists && !entry.hasMemoryData) {
      problems.push(`${entry.namespace}: root exists but contains no Engram data`);
    }
  }
  return {
    ok: problems.length === 0,
    problems,
    namespaces
  };
}
async function runNamespaceMigration(options) {
  if (!options.config.namespacesEnabled) {
    throw new Error("Namespaces are disabled.");
  }
  const targetNamespace = options.to.trim();
  if (!isSafeRouteNamespace(targetNamespace)) {
    throw new Error(`Invalid namespace: ${options.to}`);
  }
  const targetRoot = path.join(options.config.memoryDir, "namespaces", targetNamespace);
  const moved = [];
  for (const child of LEGACY_NAMESPACE_CHILDREN) {
    const from = path.join(options.config.memoryDir, child);
    if (!await exists(from)) continue;
    const to = path.join(targetRoot, child);
    if (await exists(to)) {
      throw new Error(`Target already contains ${child}: ${to}`);
    }
    moved.push({ from, to });
  }
  if (!options.dryRun && moved.length > 0) {
    await mkdir(targetRoot, { recursive: true });
    for (const move of moved) {
      await rename(move.from, move.to);
    }
  }
  return {
    dryRun: options.dryRun === true,
    fromRoot: options.config.memoryDir,
    targetRoot,
    moved,
    collection: namespaceCollectionName(options.config.qmdCollection, targetNamespace, {
      defaultNamespace: options.config.defaultNamespace,
      useLegacyDefaultCollection: false
    })
  };
}

// src/operator-toolkit.ts
function isMissingPathError(error) {
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
}
function formatUnknownError(error) {
  return error instanceof Error ? error.message : String(error);
}
function resolveConfigPath(explicitPath) {
  if (explicitPath && explicitPath.trim().length > 0) return explicitPath.trim();
  const configured = readEnvVar("OPENCLAW_ENGRAM_CONFIG_PATH") || readEnvVar("OPENCLAW_CONFIG_PATH");
  if (configured && configured.trim().length > 0) return configured.trim();
  return path2.join(resolveHomeDir(), ".openclaw", "openclaw.json");
}
async function loadCliPluginConfig(configPath) {
  const resolvedPath = resolveConfigPath(configPath);
  try {
    const raw = JSON.parse(await readFile(resolvedPath, "utf-8"));
    const entry = resolveRemnicPluginEntry(raw);
    const parsedConfig = parseConfig(
      entry && typeof entry === "object" ? entry["config"] ?? {} : {}
    );
    return {
      found: true,
      path: resolvedPath,
      parsed: true,
      memoryDir: parsedConfig.memoryDir,
      workspaceDir: parsedConfig.workspaceDir
    };
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    return {
      found: !/ENOENT/i.test(message),
      path: resolvedPath,
      parsed: false,
      error: message
    };
  }
}
async function isWritable(targetPath) {
  try {
    await access2(targetPath, fsConstants.W_OK);
    return true;
  } catch {
    return false;
  }
}
async function pathExists(targetPath) {
  try {
    await access2(targetPath, fsConstants.F_OK);
    return true;
  } catch {
    return false;
  }
}
function formatConfigValue(value) {
  if (value === void 0 || value === null) return "(unset)";
  if (typeof value === "string") return value.length > 0 ? value : "(unset)";
  if (typeof value === "number" || typeof value === "boolean") return String(value);
  return JSON.stringify(value);
}
async function gatherDirectoryStatus(paths) {
  return Promise.all(paths.map(async (targetPath) => {
    try {
      await access2(targetPath, fsConstants.F_OK);
      return {
        path: targetPath,
        exists: true,
        writable: await isWritable(targetPath)
      };
    } catch {
      return {
        path: targetPath,
        exists: false,
        writable: false
      };
    }
  }));
}
function getSetupPaths(config) {
  return [
    config.memoryDir,
    config.workspaceDir,
    path2.join(config.memoryDir, "facts"),
    path2.join(config.memoryDir, "entities"),
    path2.join(config.memoryDir, "state"),
    path2.join(config.memoryDir, "questions"),
    path2.join(config.memoryDir, "artifacts"),
    path2.join(config.memoryDir, "config")
  ];
}
async function readJsonIfExists(filePath) {
  try {
    return JSON.parse(await readFile(filePath, "utf-8"));
  } catch {
    return null;
  }
}
async function summarizeNativeKnowledgeStatus(config) {
  const nativeKnowledge = config.nativeKnowledge;
  const nativeKnowledgeStateDir = nativeKnowledge?.stateDir ?? "state/native-knowledge";
  const curatedStatePath = nativeKnowledge ? resolveCuratedIncludeFilesStatePath(config.memoryDir, nativeKnowledge) : path2.join(config.memoryDir, nativeKnowledgeStateDir, "curated-include-sync.json");
  const obsidianStatePath = nativeKnowledge ? resolveNativeKnowledgeStatePath(config.memoryDir, nativeKnowledge) : path2.join(config.memoryDir, nativeKnowledgeStateDir, "obsidian-sync.json");
  const openclawStatePath = nativeKnowledge ? resolveOpenClawWorkspaceStatePath(config.memoryDir, nativeKnowledge) : path2.join(config.memoryDir, nativeKnowledgeStateDir, "openclaw-workspace-sync.json");
  const [curatedRaw, obsidianRaw, openclawRaw] = await Promise.all([
    readJsonIfExists(curatedStatePath),
    readJsonIfExists(obsidianStatePath),
    readJsonIfExists(openclawStatePath)
  ]);
  const curatedFiles = curatedRaw && typeof curatedRaw === "object" && curatedRaw !== null && "files" in curatedRaw && typeof curatedRaw.files === "object" && curatedRaw.files !== null ? curatedRaw : null;
  let curatedActiveChunkCount = 0;
  let curatedDeletedFileCount = 0;
  for (const file of Object.values(curatedFiles?.files ?? {})) {
    if (file.deleted) {
      curatedDeletedFileCount += 1;
      continue;
    }
    curatedActiveChunkCount += Array.isArray(file.chunks) ? file.chunks.length : 0;
  }
  const obsidianVaults = obsidianRaw && typeof obsidianRaw === "object" && obsidianRaw !== null && "vaults" in obsidianRaw && typeof obsidianRaw.vaults === "object" && obsidianRaw.vaults !== null ? obsidianRaw : null;
  let obsidianActiveChunkCount = 0;
  let obsidianDeletedNoteCount = 0;
  for (const vault of Object.values(obsidianVaults?.vaults ?? {})) {
    for (const note of Object.values(vault.notes ?? {})) {
      if (note.deleted) {
        obsidianDeletedNoteCount += 1;
        continue;
      }
      obsidianActiveChunkCount += Array.isArray(note.chunks) ? note.chunks.length : 0;
    }
  }
  const openclawFiles = openclawRaw && typeof openclawRaw === "object" && openclawRaw !== null && "files" in openclawRaw && typeof openclawRaw.files === "object" && openclawRaw.files !== null ? openclawRaw : null;
  let openclawActiveChunkCount = 0;
  let openclawDeletedFileCount = 0;
  for (const file of Object.values(openclawFiles?.files ?? {})) {
    if (file.deleted) {
      openclawDeletedFileCount += 1;
      continue;
    }
    openclawActiveChunkCount += Array.isArray(file.chunks) ? file.chunks.length : 0;
  }
  return {
    enabled: nativeKnowledge?.enabled === true,
    includeFiles: nativeKnowledge?.includeFiles ?? [],
    curatedIncludeSync: {
      statePath: curatedStatePath,
      exists: curatedFiles !== null,
      updatedAt: typeof curatedFiles?.updatedAt === "string" ? curatedFiles.updatedAt : null,
      fileCount: Object.keys(curatedFiles?.files ?? {}).length,
      activeChunkCount: curatedActiveChunkCount,
      deletedFileCount: curatedDeletedFileCount
    },
    openclawWorkspaceAdapterEnabled: nativeKnowledge?.openclawWorkspace?.enabled === true,
    obsidianVaultAdapterEnabled: (nativeKnowledge?.obsidianVaults?.length ?? 0) > 0,
    obsidianSync: {
      statePath: obsidianStatePath,
      exists: obsidianVaults !== null,
      updatedAt: typeof obsidianVaults?.updatedAt === "string" ? obsidianVaults.updatedAt : null,
      vaultCount: Object.keys(obsidianVaults?.vaults ?? {}).length,
      activeChunkCount: obsidianActiveChunkCount,
      deletedNoteCount: obsidianDeletedNoteCount
    },
    openclawWorkspaceSync: {
      statePath: openclawStatePath,
      exists: openclawFiles !== null,
      updatedAt: typeof openclawFiles?.updatedAt === "string" ? openclawFiles.updatedAt : null,
      fileCount: Object.keys(openclawFiles?.files ?? {}).length,
      activeChunkCount: openclawActiveChunkCount,
      deletedFileCount: openclawDeletedFileCount
    }
  };
}
var CAPTURE_INSTRUCTIONS_START = "<!-- BEGIN ENGRAM EXPLICIT CAPTURE INSTRUCTIONS -->";
var CAPTURE_INSTRUCTIONS_END = "<!-- END ENGRAM EXPLICIT CAPTURE INSTRUCTIONS -->";
function buildCaptureInstructions() {
  return [
    CAPTURE_INSTRUCTIONS_START,
    "# Memory",
    "",
    "Use this file for explicit memory capture notes when Engram runs in explicit or hybrid mode.",
    "",
    "## Suggested format",
    "",
    "- Write durable facts, decisions, commitments, or corrections.",
    "- Keep entries concise and specific.",
    "- Avoid secrets, tokens, and private credentials.",
    "",
    "## Example",
    "",
    "- Decision: recall benchmark packs live under `state/evals/benchmarks/`.",
    "- Commitment: rerun `openclaw engram doctor --json` after changing retrieval settings.",
    "",
    CAPTURE_INSTRUCTIONS_END
  ].join("\n");
}
function upsertManagedCaptureInstructions(existing, snippet) {
  if (!existing || existing.trim().length === 0) {
    return { content: `${snippet}
`, updated: false, installed: true };
  }
  if (existing.includes(CAPTURE_INSTRUCTIONS_START) && existing.includes(CAPTURE_INSTRUCTIONS_END)) {
    const next = existing.replace(
      new RegExp(`${CAPTURE_INSTRUCTIONS_START}[\\s\\S]*?${CAPTURE_INSTRUCTIONS_END}`),
      snippet
    );
    return { content: next.endsWith("\n") ? next : `${next}
`, updated: next !== existing, installed: false };
  }
  const trimmed = existing.trimEnd();
  return {
    content: `${trimmed}

${snippet}
`,
    updated: false,
    installed: true
  };
}
function removeManagedCaptureInstructions(existing) {
  if (!existing.includes(CAPTURE_INSTRUCTIONS_START) || !existing.includes(CAPTURE_INSTRUCTIONS_END)) {
    return { content: existing, removed: false };
  }
  const stripped = existing.replace(new RegExp(`\\n*${CAPTURE_INSTRUCTIONS_START}[\\s\\S]*?${CAPTURE_INSTRUCTIONS_END}\\n*`), "\n").replace(/\n{3,}/g, "\n\n").trim();
  return {
    content: stripped.length > 0 ? `${stripped}
` : "",
    removed: true
  };
}
async function runOperatorSetup(options) {
  const now = options.now ?? /* @__PURE__ */ new Date();
  const configStatus = await loadCliPluginConfig(options.configPath);
  const storage = options.orchestrator.storage;
  await storage.ensureDirectories();
  await mkdir2(options.orchestrator.config.workspaceDir, { recursive: true });
  const qmdAvailable = await options.orchestrator.qmd.probe();
  const collectionState = options.orchestrator.config.qmdEnabled ? await options.orchestrator.qmd.ensureCollection(options.orchestrator.config.memoryDir) : "skipped";
  const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(options.orchestrator.config);
  const memoryDocPath = path2.join(options.orchestrator.config.workspaceDir, "MEMORY.md");
  const captureInstructionsMode = options.captureInstructionsMode ?? (options.installCaptureInstructions ? "install" : void 0);
  let memoryDocExists = false;
  try {
    await access2(memoryDocPath, fsConstants.F_OK);
    memoryDocExists = true;
  } catch {
    memoryDocExists = false;
  }
  let memoryDocInstalled = false;
  let memoryDocUpdated = false;
  let memoryDocRemoved = false;
  const explicitCaptureEnabled = options.orchestrator.config.captureMode === "explicit" || options.orchestrator.config.captureMode === "hybrid";
  const captureInstructionsPreview = captureInstructionsMode ? buildCaptureInstructions() : null;
  if (captureInstructionsMode) {
    if (captureInstructionsMode === "preview") {
    } else if (captureInstructionsMode === "install") {
      const existing = memoryDocExists ? await readFile(memoryDocPath, "utf-8") : null;
      const next = upsertManagedCaptureInstructions(existing, captureInstructionsPreview ?? "");
      if (!existing || next.content !== existing) {
        await writeFile(memoryDocPath, next.content, "utf-8");
      }
      memoryDocExists = true;
      memoryDocInstalled = next.installed;
      memoryDocUpdated = next.updated;
    } else if (captureInstructionsMode === "remove" && memoryDocExists) {
      const existing = await readFile(memoryDocPath, "utf-8");
      const next = removeManagedCaptureInstructions(existing);
      if (next.removed) {
        if (next.content.length === 0) {
          await unlink(memoryDocPath);
          memoryDocExists = false;
        } else {
          await writeFile(memoryDocPath, next.content, "utf-8");
          memoryDocExists = true;
        }
        memoryDocRemoved = true;
      }
    }
  }
  const directories = await gatherDirectoryStatus(getSetupPaths(options.orchestrator.config));
  const nextSteps = [
    `Run \`openclaw engram doctor${options.installCaptureInstructions ? "" : " --json"}\` to verify runtime health.`,
    "Run `openclaw engram inventory --json` to capture a baseline footprint.",
    "If QMD is enabled and the collection is missing, add the collection to `~/.config/qmd/index.yml` and run `qmd update && qmd embed`."
  ];
  if (explicitCaptureEnabled && !memoryDocExists) {
    nextSteps.push("Run `openclaw engram setup --preview-capture-instructions` to review the managed explicit-capture snippet, then `--install-capture-instructions` to write it.");
  }
  return {
    schemaVersion: 1,
    generatedAt: now.toISOString(),
    config: configStatus,
    memoryDir: options.orchestrator.config.memoryDir,
    workspaceDir: options.orchestrator.config.workspaceDir,
    directories,
    qmd: {
      enabled: options.orchestrator.config.qmdEnabled,
      available: qmdAvailable,
      collectionState,
      debugStatus: options.orchestrator.qmd.debugStatus()
    },
    nativeKnowledge: nativeKnowledgeStatus,
    explicitCapture: {
      captureMode: options.orchestrator.config.captureMode,
      enabled: explicitCaptureEnabled,
      memoryDocPath,
      memoryDocExists,
      memoryDocInstalled,
      memoryDocUpdated,
      memoryDocRemoved,
      preview: captureInstructionsMode === "preview" ? captureInstructionsPreview : null
    },
    nextSteps,
    verificationCommands: [
      "openclaw engram doctor --json",
      "openclaw engram inventory --json",
      "openclaw engram benchmark recall --json"
    ]
  };
}
function summarizeHygieneWarnings(warnings, hygiene) {
  if (!hygiene?.enabled || hygiene.lintEnabled !== true) {
    return {
      key: "file_hygiene",
      status: "warn",
      summary: "File hygiene linting is disabled; bootstrap file truncation warnings are not active.",
      remediation: "Enable `fileHygiene.enabled` and `fileHygiene.lintEnabled` if large workspace bootstrap files are common.",
      details: {
        enabled: hygiene?.enabled === true,
        lintEnabled: hygiene?.lintEnabled === true
      }
    };
  }
  if (warnings.length > 0) {
    return {
      key: "file_hygiene",
      status: "warn",
      summary: `${warnings.length} bootstrap file(s) are near or above the configured budget.`,
      remediation: "Archive/split the listed files or adjust `fileHygiene` budgets.",
      details: { warnings }
    };
  }
  return {
    key: "file_hygiene",
    status: "ok",
    summary: "Bootstrap file hygiene is within budget.",
    details: {
      enabled: true,
      lintPaths: hygiene.lintPaths,
      budgetBytes: hygiene.lintBudgetBytes
    }
  };
}
function buildConfigReviewFinding(input) {
  return {
    key: input.key,
    status: input.status,
    setting: input.setting,
    currentValue: formatConfigValue(input.currentValue),
    defaultValue: formatConfigValue(input.defaultValue),
    recommendedValue: formatConfigValue(input.recommendedValue),
    summary: input.summary,
    rationale: input.rationale
  };
}
async function runOperatorConfigReview(options) {
  const now = options.now ?? /* @__PURE__ */ new Date();
  const configStatus = await loadCliPluginConfig(options.configPath);
  return buildOperatorConfigReviewReport({
    now,
    configStatus,
    config: options.orchestrator.config
  });
}
async function buildOperatorConfigReviewReport(input) {
  const { now, configStatus, config } = input;
  const findings = [];
  const searchBackend = config.searchBackend ?? "qmd";
  const workspaceBootstrapFiles = [
    path2.join(config.workspaceDir, "IDENTITY.md"),
    path2.join(config.workspaceDir, "MEMORY.md"),
    path2.join(config.workspaceDir, "USER.md")
  ];
  const workspaceBootstrapExists = (await Promise.all(workspaceBootstrapFiles.map(pathExists))).some(Boolean);
  if (config.memoryOsPreset !== "conservative" && config.memoryOsPreset !== "balanced" && config.memoryOsPreset !== "research-max" && config.memoryOsPreset !== "local-llm-heavy" && config.queryAwareIndexingEnabled === false && config.verbatimArtifactsEnabled === false && config.rerankEnabled === false) {
    findings.push(buildConfigReviewFinding({
      key: "balanced_preset",
      status: "recommend",
      setting: "memoryOsPreset",
      currentValue: config.memoryOsPreset,
      defaultValue: "(unset)",
      recommendedValue: "balanced",
      summary: "Adopt the balanced preset as the baseline configuration profile.",
      rationale: "The balanced preset enables the recommended indexing, reranking, and artifact defaults without turning on the higher-churn graph and learning loops."
    }));
  }
  if (config.qmdEnabled && config.qmdDaemonEnabled === false) {
    findings.push(buildConfigReviewFinding({
      key: "qmd_daemon",
      status: "recommend",
      setting: "qmdDaemonEnabled",
      currentValue: config.qmdDaemonEnabled,
      defaultValue: true,
      recommendedValue: true,
      summary: "Enable the QMD daemon path when QMD powers recall.",
      rationale: "The daemon path reduces recall/search contention by preferring the MCP transport instead of repeated subprocess calls when QMD is available."
    }));
  }
  if (workspaceBootstrapExists && config.nativeKnowledge?.enabled !== true) {
    findings.push(buildConfigReviewFinding({
      key: "native_knowledge_enabled",
      status: "recommend",
      setting: "nativeKnowledge.enabled",
      currentValue: config.nativeKnowledge?.enabled,
      defaultValue: false,
      recommendedValue: true,
      summary: "Enable native knowledge recall for workspace bootstrap documents.",
      rationale: "When files like IDENTITY.md or MEMORY.md already exist, native knowledge recall can chunk and inject them directly instead of relying only on extracted memories."
    }));
  }
  if (workspaceBootstrapExists && config.fileHygiene?.enabled !== true) {
    findings.push(buildConfigReviewFinding({
      key: "file_hygiene_enabled",
      status: "recommend",
      setting: "fileHygiene.enabled",
      currentValue: config.fileHygiene?.enabled,
      defaultValue: false,
      recommendedValue: true,
      summary: "Enable file hygiene to avoid silent workspace-file truncation.",
      rationale: "OpenClaw bootstrap files can grow quietly; file hygiene warns before oversized files are truncated during prompt bootstrap."
    }));
  }
  if (searchBackend === "qmd" && config.qmdEnabled === false) {
    findings.push(buildConfigReviewFinding({
      key: "qmd_search_backend_disabled",
      status: "problem",
      setting: "qmdEnabled",
      currentValue: config.qmdEnabled,
      defaultValue: true,
      recommendedValue: true,
      summary: "QMD search is selected but QMD is disabled.",
      rationale: "When searchBackend resolves to qmd while qmdEnabled is false, Engram falls back to the noop backend and disables the primary search path."
    }));
  }
  if (config.qmdColdTierEnabled === true && config.qmdEnabled === false) {
    findings.push(buildConfigReviewFinding({
      key: "qmd_cold_tier_requires_qmd",
      status: "problem",
      setting: "qmdEnabled",
      currentValue: config.qmdEnabled,
      defaultValue: true,
      recommendedValue: true,
      summary: "Cold-tier QMD recall is enabled while QMD itself is disabled.",
      rationale: "The cold tier depends on the same QMD runtime as the hot tier, so turning QMD off leaves the extra tiering path unusable."
    }));
  }
  if (config.qmdTierMigrationEnabled && config.qmdColdTierEnabled !== true) {
    findings.push(buildConfigReviewFinding({
      key: "qmd_tier_migration_requires_cold_tier",
      status: "problem",
      setting: "qmdColdTierEnabled",
      currentValue: config.qmdColdTierEnabled,
      defaultValue: false,
      recommendedValue: true,
      summary: "Hot/cold tier migration is enabled without the cold tier itself.",
      rationale: "Tier migration depends on the cold-tier collection and recall path, so enabling migration while the cold tier is off leaves the feature in a contradictory state."
    }));
  }
  if (config.conversationIndexEnabled && config.conversationIndexBackend === "qmd" && config.qmdEnabled === false) {
    findings.push(buildConfigReviewFinding({
      key: "conversation_index_qmd_requires_qmd",
      status: "problem",
      setting: "qmdEnabled",
      currentValue: config.qmdEnabled,
      defaultValue: true,
      recommendedValue: true,
      summary: "The conversation index is configured for QMD while QMD is disabled.",
      rationale: "A QMD-backed conversation index cannot rebuild or serve queries when the underlying QMD runtime is disabled."
    }));
  }
  const summary = findings.reduce(
    (acc, finding) => {
      acc[finding.status] += 1;
      return acc;
    },
    { recommend: 0, problem: 0 }
  );
  return {
    schemaVersion: 1,
    generatedAt: now.toISOString(),
    ok: configStatus.parsed && summary.problem === 0,
    config: configStatus,
    profile: {
      memoryOsPreset: config.memoryOsPreset,
      searchBackend,
      qmdEnabled: config.qmdEnabled,
      qmdDaemonEnabled: config.qmdDaemonEnabled,
      nativeKnowledgeEnabled: config.nativeKnowledge?.enabled === true,
      fileHygieneEnabled: config.fileHygiene?.enabled === true,
      conversationIndexEnabled: config.conversationIndexEnabled
    },
    summary,
    findings
  };
}
async function runOperatorDoctor(options) {
  const now = options.now ?? /* @__PURE__ */ new Date();
  const configStatus = await loadCliPluginConfig(options.configPath);
  const checks = [];
  const config = options.orchestrator.config;
  const storage = options.orchestrator.storage;
  const configReview = await buildOperatorConfigReviewReport({
    now,
    configStatus,
    config
  });
  const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(config);
  const setupPaths = await gatherDirectoryStatus(getSetupPaths(config));
  const missingPaths = setupPaths.filter((entry) => !entry.exists).map((entry) => entry.path);
  checks.push({
    key: "config",
    status: configStatus.parsed ? "ok" : options.configPath ? "error" : "warn",
    summary: configStatus.parsed ? "OpenClaw config loaded and Engram config parsed successfully." : "Config file could not be parsed.",
    remediation: configStatus.parsed ? void 0 : "Fix the config file or set OPENCLAW_ENGRAM_CONFIG_PATH/OPENCLAW_CONFIG_PATH.",
    details: configStatus
  });
  checks.push({
    key: "memory_dir",
    status: missingPaths.length === 0 ? "ok" : "warn",
    summary: missingPaths.length === 0 ? "Expected Engram directories exist." : `${missingPaths.length} expected directory path(s) are missing.`,
    remediation: missingPaths.length === 0 ? void 0 : "Run `openclaw engram setup` to create missing directories.",
    details: { directories: setupPaths }
  });
  checks.push({
    key: "config_review",
    status: configReview.summary.problem > 0 ? "error" : configReview.summary.recommend > 0 ? "warn" : "ok",
    summary: configReview.summary.problem > 0 ? `${configReview.summary.problem} configuration problem(s) detected.` : configReview.summary.recommend > 0 ? `No configuration problems detected; ${configReview.summary.recommend} optional recommendation(s) are available.` : "No configuration problems detected.",
    remediation: configReview.summary.problem > 0 || configReview.summary.recommend > 0 ? "Run `openclaw engram config-review` to inspect and fix the flagged configuration combinations." : void 0,
    details: configReview
  });
  const qmdAvailable = await options.orchestrator.qmd.probe();
  const collectionState = config.qmdEnabled ? await options.orchestrator.qmd.ensureCollection(config.memoryDir) : "skipped";
  checks.push({
    key: "qmd",
    status: !config.qmdEnabled ? "warn" : !qmdAvailable ? "error" : collectionState === "present" ? "ok" : collectionState === "missing" ? "error" : "warn",
    summary: !config.qmdEnabled ? "QMD is disabled in config." : qmdAvailable ? `QMD is reachable (${collectionState}).` : "QMD is not currently reachable.",
    remediation: !config.qmdEnabled ? "Enable `qmdEnabled` if you expect hybrid search." : !qmdAvailable ? "Ensure the `qmd` binary is installed and on PATH, or set `qmdPath`." : collectionState === "missing" ? "Add the configured collection to `~/.config/qmd/index.yml`." : collectionState === "present" ? void 0 : "Re-run `openclaw engram setup` after restoring QMD access.",
    details: {
      available: qmdAvailable,
      collectionState,
      debugStatus: options.orchestrator.qmd.debugStatus()
    }
  });
  const conversationIndex = await options.orchestrator.getConversationIndexHealth();
  checks.push({
    key: "conversation_index",
    status: conversationIndex.status === "ok" ? "ok" : conversationIndex.enabled ? "error" : "warn",
    summary: conversationIndex.enabled ? `Conversation index backend is ${conversationIndex.status}.` : "Conversation index is disabled.",
    remediation: conversationIndex.enabled && conversationIndex.status !== "ok" ? "Run `openclaw engram rebuild-index` to refresh the conversation index artifacts." : void 0,
    details: conversationIndex
  });
  const meta = await storage.loadMeta();
  checks.push({
    key: "maintenance",
    status: meta.lastExtractionAt || meta.lastConsolidationAt ? "ok" : "warn",
    summary: meta.lastExtractionAt || meta.lastConsolidationAt ? "Extraction/consolidation metadata is present." : "No extraction or consolidation metadata found yet.",
    remediation: meta.lastExtractionAt || meta.lastConsolidationAt ? void 0 : "Run a normal agent turn or `openclaw engram consolidate` after seeding memory.",
    details: meta
  });
  const syncedChunkCount = nativeKnowledgeStatus.curatedIncludeSync.activeChunkCount + nativeKnowledgeStatus.obsidianSync.activeChunkCount + nativeKnowledgeStatus.openclawWorkspaceSync.activeChunkCount;
  const hasSyncState = nativeKnowledgeStatus.curatedIncludeSync.exists || nativeKnowledgeStatus.obsidianSync.exists || nativeKnowledgeStatus.openclawWorkspaceSync.exists;
  checks.push({
    key: "native_knowledge",
    status: !nativeKnowledgeStatus.enabled ? "warn" : hasSyncState ? "ok" : "warn",
    summary: !nativeKnowledgeStatus.enabled ? "Native knowledge sync is disabled." : hasSyncState ? `Native knowledge sync state is present (${syncedChunkCount} active chunks).` : "Native knowledge sync is enabled but no sync state has been written yet.",
    remediation: !nativeKnowledgeStatus.enabled ? "Enable `nativeKnowledge.enabled` if curated workspace recall should participate in retrieval." : hasSyncState ? void 0 : "Run a recall, sync, or setup flow that touches native knowledge sources, then rerun `openclaw engram doctor --json`.",
    details: nativeKnowledgeStatus
  });
  const agentAccessEnabled = config.agentAccessHttp?.enabled === true;
  const rawAuthToken = config.agentAccessHttp?.authToken;
  const authTokenConfigured = typeof rawAuthToken === "string" && rawAuthToken.length > 0 || rawAuthToken !== null && typeof rawAuthToken === "object" && typeof rawAuthToken.source === "string";
  checks.push({
    key: "access_http_auth",
    status: !agentAccessEnabled ? "warn" : authTokenConfigured ? "ok" : "error",
    summary: !agentAccessEnabled ? "Agent access HTTP bridge is disabled." : authTokenConfigured ? "Agent access HTTP bridge has an auth token configured." : "Agent access HTTP bridge is enabled without an auth token.",
    remediation: !agentAccessEnabled ? "Ignore unless you plan to enable the HTTP bridge." : authTokenConfigured ? void 0 : "Set `agentAccessHttp.authToken` before exposing the bridge."
  });
  const warnings = config.fileHygiene?.lintEnabled ? await lintWorkspaceFiles({
    workspaceDir: config.workspaceDir,
    paths: config.fileHygiene.lintPaths,
    budgetBytes: config.fileHygiene.lintBudgetBytes,
    warnRatio: config.fileHygiene.lintWarnRatio
  }) : [];
  checks.push(summarizeHygieneWarnings(warnings, config.fileHygiene));
  checks.push(await summarizeMemoryWorthLegacyCounters(storage));
  checks.push(
    await summarizeBufferSurpriseDistribution(storage, config)
  );
  checks.push(await summarizeConsolidationProvenance(storage, config));
  checks.push(await summarizeGraphEdgeDecayStatus(config));
  checks.push(await summarizeTierDistribution(options.orchestrator.storage));
  checks.push(await summarizeDreamsPhases(config, storage));
  checks.push(summarizeSecurityMitigations(config));
  checks.push(await summarizeObservationThroughput(config.memoryDir));
  const summary = checks.reduce(
    (acc, check) => {
      acc[check.status] += 1;
      return acc;
    },
    { ok: 0, warn: 0, error: 0 }
  );
  return {
    schemaVersion: 1,
    generatedAt: now.toISOString(),
    ok: summary.error === 0,
    summary,
    config: configStatus,
    checks
  };
}
var MEMORY_WORTH_ELIGIBLE_CATEGORIES = /* @__PURE__ */ new Set(["fact"]);
async function summarizeMemoryWorthLegacyCounters(storage) {
  let legacy = 0;
  let instrumented = 0;
  let ineligible = 0;
  try {
    const memories = await storage.readAllMemories();
    for (const memory of memories) {
      if (!MEMORY_WORTH_ELIGIBLE_CATEGORIES.has(memory.frontmatter.category)) {
        ineligible += 1;
        continue;
      }
      const { mw_success, mw_fail } = memory.frontmatter;
      if (mw_success === void 0 && mw_fail === void 0) {
        legacy += 1;
      } else {
        instrumented += 1;
      }
    }
  } catch (err) {
    return {
      key: "memory_worth_legacy",
      status: "warn",
      summary: "Could not enumerate memories to count Memory Worth instrumentation.",
      remediation: "Retry `remnic doctor` after ensuring the memory directory is readable.",
      details: { error: String(err) }
    };
  }
  const total = legacy + instrumented;
  return {
    key: "memory_worth_legacy",
    status: "ok",
    summary: total === 0 ? "No Memory Worth\u2013eligible memories on disk yet \u2014 counters will populate as facts are extracted." : `${legacy} of ${total} eligible memories have no Memory Worth counters yet (${instrumented} instrumented).`,
    details: { legacy, instrumented, total, ineligible }
  };
}
async function summarizeBufferSurpriseDistribution(storage, config) {
  const storageWithLedger = storage;
  if (typeof storageWithLedger.readBufferSurpriseEvents !== "function") {
    return {
      key: "buffer_surprise_distribution",
      status: "ok",
      summary: "Buffer-surprise telemetry reader unavailable in this build.",
      details: { available: false }
    };
  }
  try {
    const dist = await reportBufferSurpriseDistribution(
      async (opts) => storageWithLedger.readBufferSurpriseEvents({ limit: opts.limit }),
      { limit: 200 }
    );
    if (dist.count === 0) {
      return {
        key: "buffer_surprise_distribution",
        status: "ok",
        summary: config.bufferSurpriseTriggerEnabled ? "Surprise trigger is enabled but no telemetry has been recorded yet." : "Surprise trigger is disabled; no telemetry expected.",
        details: {
          enabled: config.bufferSurpriseTriggerEnabled,
          distribution: dist
        }
      };
    }
    const pct = (value) => (value * 100).toFixed(1);
    return {
      key: "buffer_surprise_distribution",
      status: "ok",
      summary: `Recent surprise: mean=${dist.mean.toFixed(3)}, median=${dist.median.toFixed(3)}, p90=${dist.p90.toFixed(3)}, triggered=${pct(dist.triggeredRate)}% over ${dist.count} turns (threshold=${dist.currentThreshold ?? config.bufferSurpriseThreshold}).`,
      details: {
        enabled: config.bufferSurpriseTriggerEnabled,
        distribution: dist
      }
    };
  } catch (err) {
    return {
      key: "buffer_surprise_distribution",
      status: "warn",
      summary: "Could not read buffer-surprise telemetry ledger.",
      remediation: "Retry `remnic doctor` after ensuring the memory state directory is readable.",
      details: { error: String(err) }
    };
  }
}
async function summarizeGraphEdgeDecayStatus(config) {
  const { readGraphEdgeDecayStatus } = await import("./graph-edge-decay-PWB63GRE.js");
  const enabled = config.graphEdgeDecayEnabled === true;
  if (!enabled) {
    return {
      key: "graph_edge_decay",
      status: "ok",
      summary: "Graph-edge decay maintenance is disabled (graphEdgeDecayEnabled = false).",
      remediation: "Set graphEdgeDecayEnabled = true to opt into the periodic decay job (issue #681).",
      details: { enabled: false }
    };
  }
  const status = await readGraphEdgeDecayStatus(config.memoryDir);
  if (!status) {
    return {
      key: "graph_edge_decay",
      status: "warn",
      summary: "Graph-edge decay is enabled but has not run yet (no status file present).",
      remediation: "Trigger the cron, run `engram.graph_edge_decay_run` via MCP, or wait for the scheduled cadence to fire.",
      details: { enabled: true, lastRun: null, cadenceMs: config.graphEdgeDecayCadenceMs }
    };
  }
  return {
    key: "graph_edge_decay",
    status: "ok",
    summary: `Graph-edge decay last ran at ${status.ranAt} (${status.edgesDecayed}/${status.edgesTotal} edges decayed, ${status.edgesBelowVisibilityThreshold} below visibility threshold).`,
    details: {
      enabled: true,
      lastRun: status.ranAt,
      durationMs: status.durationMs,
      edgesTotal: status.edgesTotal,
      edgesDecayed: status.edgesDecayed,
      edgesBelowVisibilityThreshold: status.edgesBelowVisibilityThreshold,
      topDecayedEntities: status.topDecayedEntities,
      cadenceMs: config.graphEdgeDecayCadenceMs
    }
  };
}
async function summarizeTierDistribution(storage) {
  try {
    const { summarizeTiers } = await import("./tier-stats-62ZVDFKS.js");
    const summary = await summarizeTiers(storage);
    const storageDir = storage.dir ?? "";
    const journalPath = storageDir.length > 0 ? path2.join(storageDir, "state", "tier-migration-journal.jsonl") : null;
    let recentMigrations = 0;
    const demotionReasons = {};
    const sevenDaysAgoMs = Date.now() - 7 * 864e5;
    if (journalPath) {
      try {
        const { readFile: readFile2 } = await import("fs/promises");
        const raw = await readFile2(journalPath, "utf-8");
        for (const line of raw.split("\n")) {
          const trimmed = line.trim();
          if (trimmed.length === 0) continue;
          try {
            const entry = JSON.parse(trimmed);
            const tsMs = entry.ts ? Date.parse(entry.ts) : NaN;
            if (Number.isFinite(tsMs) && tsMs >= sevenDaysAgoMs && entry.changed === true) {
              recentMigrations += 1;
              if (entry.fromTier === "hot" && entry.toTier === "cold" && typeof entry.reason === "string") {
                const reason = entry.reason;
                demotionReasons[reason] = (demotionReasons[reason] ?? 0) + 1;
              }
            }
          } catch {
          }
        }
      } catch {
      }
    }
    const topDemotionReasons = Object.entries(demotionReasons).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, 5).map(([reason, count]) => ({ reason, count }));
    const statusParts = Object.entries(summary.byStatus).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, 6).map(([s, n]) => `${s}: ${n}`).join(", ");
    return {
      key: "tier_distribution",
      status: "ok",
      summary: `Tier distribution: hot=${summary.byTier.hot}, cold=${summary.byTier.cold}` + (summary.forgottenCount > 0 ? `, forgotten=${summary.forgottenCount}` : "") + `. Total: ${summary.total}.` + (recentMigrations > 0 ? ` Recent migrations (7d): ${recentMigrations}.` : ""),
      details: {
        total: summary.total,
        byTier: summary.byTier,
        byStatus: summary.byStatus,
        forgottenCount: summary.forgottenCount,
        statusSummary: statusParts,
        recentMigrations,
        topDemotionReasons
      }
    };
  } catch (err) {
    return {
      key: "tier_distribution",
      status: "ok",
      summary: "Tier distribution unavailable \u2014 could not enumerate memories.",
      details: { error: String(err) }
    };
  }
}
async function summarizeDreamsPhases(config, storage = new StorageManager(config.memoryDir)) {
  const phases = config.dreamsPhases;
  const meta = await storage.loadMeta();
  let deepSleepLastRun = null;
  let deepSleepLastRunWarning = null;
  try {
    const runsDir = path2.join(config.memoryDir, "state", "memory-governance", "runs");
    const runIds = (await readdir2(runsDir)).sort().reverse();
    if (runIds.length > 0) {
      const latestRunId = runIds[0];
      const manifestPath = path2.join(
        runsDir,
        latestRunId,
        "manifest.json"
      );
      const raw = await readFile(manifestPath, "utf-8");
      const parsed = JSON.parse(raw);
      if (typeof parsed.createdAt === "string" && parsed.createdAt.length > 0) {
        deepSleepLastRun = parsed.createdAt;
      }
    }
  } catch (error) {
    if (!isMissingPathError(error)) {
      deepSleepLastRunWarning = `Could not read latest governance run manifest: ${formatUnknownError(error)}`;
    }
  }
  const phaseLines = [
    `lightSleep: enabled=${phases.lightSleep.enabled}, cadenceMs=${phases.lightSleep.cadenceMs}, promoteHeat=${phases.lightSleep.promoteHeatThreshold}, staleDecay=${phases.lightSleep.staleDecayThreshold}, archiveDecay=${phases.lightSleep.archiveDecayThreshold}, filterStale=${phases.lightSleep.filterStaleEnabled}, lastRun=${meta.lastExtractionAt ?? "never"}`,
    `rem: enabled=${phases.rem.enabled}, cadenceMs=${phases.rem.cadenceMs}, similarity=${phases.rem.similarityThreshold}, minCluster=${phases.rem.minClusterSize}, maxPerRun=${phases.rem.maxPerRun}, minIntervalMs=${phases.rem.minIntervalMs}, lastRun=${meta.lastConsolidationAt ?? "never"}`,
    `deepSleep: enabled=${phases.deepSleep.enabled}, cadenceMs=${phases.deepSleep.cadenceMs}, versioning=${phases.deepSleep.versioningEnabled}, versioningMaxPerPage=${phases.deepSleep.versioningMaxPerPage}, lastRun=${deepSleepLastRun ?? "never"}`
  ];
  return {
    key: "dreams_phases",
    status: deepSleepLastRunWarning ? "warn" : "ok",
    summary: `Dreams pipeline phases: ${phaseLines.join("; ")}${deepSleepLastRunWarning ? `; ${deepSleepLastRunWarning}` : ""}`,
    remediation: deepSleepLastRunWarning ? "Inspect state/memory-governance/runs and repair or remove unreadable governance run artifacts." : void 0,
    details: {
      lightSleep: {
        enabled: phases.lightSleep.enabled,
        cadenceMs: phases.lightSleep.cadenceMs,
        promoteHeatThreshold: phases.lightSleep.promoteHeatThreshold,
        staleDecayThreshold: phases.lightSleep.staleDecayThreshold,
        archiveDecayThreshold: phases.lightSleep.archiveDecayThreshold,
        filterStaleEnabled: phases.lightSleep.filterStaleEnabled,
        lastRun: meta.lastExtractionAt ?? null
      },
      rem: {
        enabled: phases.rem.enabled,
        cadenceMs: phases.rem.cadenceMs,
        similarityThreshold: phases.rem.similarityThreshold,
        minClusterSize: phases.rem.minClusterSize,
        maxPerRun: phases.rem.maxPerRun,
        minIntervalMs: phases.rem.minIntervalMs,
        lastRun: meta.lastConsolidationAt ?? null
      },
      deepSleep: {
        enabled: phases.deepSleep.enabled,
        cadenceMs: phases.deepSleep.cadenceMs,
        versioningEnabled: phases.deepSleep.versioningEnabled,
        versioningMaxPerPage: phases.deepSleep.versioningMaxPerPage,
        lastRun: deepSleepLastRun,
        warning: deepSleepLastRunWarning
      }
    }
  };
}
function summarizeSecurityMitigations(config) {
  const budgetEnabled = config.recallCrossNamespaceBudgetEnabled === true;
  const anomalyEnabled = config.recallAuditAnomalyDetectionEnabled === true;
  if (!budgetEnabled && !anomalyEnabled) {
    return {
      key: "security_mitigations",
      status: "warn",
      summary: "Memory-extraction mitigations are disabled (cross-namespace budget and anomaly detection off).",
      remediation: "Enable recallCrossNamespaceBudgetEnabled and/or recallAuditAnomalyDetectionEnabled for production deployments. See docs/security/memory-extraction-threat-model.md.",
      details: {
        budgetEnabled: false,
        anomalyDetectionEnabled: false
      }
    };
  }
  const details = {
    budgetEnabled,
    anomalyDetectionEnabled: anomalyEnabled
  };
  if (budgetEnabled) {
    details.budgetConfig = {
      windowMs: config.recallCrossNamespaceBudgetWindowMs,
      softLimit: config.recallCrossNamespaceBudgetSoftLimit,
      hardLimit: config.recallCrossNamespaceBudgetHardLimit
    };
  }
  if (anomalyEnabled) {
    details.anomalyConfig = {
      windowMs: config.recallAuditAnomalyWindowMs,
      repeatQueryLimit: config.recallAuditAnomalyRepeatQueryLimit,
      namespaceWalkLimit: config.recallAuditAnomalyNamespaceWalkLimit,
      highCardinalityLimit: config.recallAuditAnomalyHighCardinalityLimit,
      rapidFireLimit: config.recallAuditAnomalyRapidFireLimit
    };
  }
  return {
    key: "security_mitigations",
    status: "ok",
    summary: `Memory-extraction mitigation config enabled: ${budgetEnabled ? "budget" : ""}${budgetEnabled && anomalyEnabled ? ", " : ""}${anomalyEnabled ? "anomaly detection" : ""}.`,
    details: { ...details, configOnly: true }
  };
}
async function summarizeObservationThroughput(memoryDir) {
  try {
    const stats = await readJudgeVerdictStats(memoryDir);
    if (stats.total === 0) {
      return {
        key: "observations",
        status: "ok",
        summary: "No observations recorded yet (extraction-judge telemetry ledger is empty or missing).",
        details: { total: 0, accept: 0, reject: 0, defer: 0, lastObservedAt: null }
      };
    }
    const acceptPct = (stats.accept / stats.total * 100).toFixed(1);
    const rejectPct = (stats.reject / stats.total * 100).toFixed(1);
    const deferPct = (stats.defer / stats.total * 100).toFixed(1);
    return {
      key: "observations",
      status: "ok",
      summary: `${stats.total} observations recorded: accept=${acceptPct}%, reject=${rejectPct}%, defer=${deferPct}%. Last observed: ${stats.lastTs ?? "unknown"}.`,
      details: {
        total: stats.total,
        accept: stats.accept,
        reject: stats.reject,
        defer: stats.defer,
        deferCapTriggered: stats.deferCapTriggered,
        deferRate: stats.deferRate,
        meanElapsedMs: stats.meanElapsedMs,
        firstObservedAt: stats.firstTs ?? null,
        lastObservedAt: stats.lastTs ?? null
      }
    };
  } catch (err) {
    return {
      key: "observations",
      status: "warn",
      summary: "Could not read observation telemetry ledger.",
      remediation: "Retry `remnic doctor` after ensuring the memory state directory is readable.",
      details: { error: String(err) }
    };
  }
}
async function summarizeConsolidationProvenance(storage, config) {
  let report;
  try {
    report = await runConsolidationProvenanceCheck({
      storage,
      memoryDir: config.memoryDir,
      // Honor the configured sidecar directory (PR #634 review): when an
      // operator overrides `versioningSidecarDir`, the default `.versions`
      // would point at the wrong location and every entry would report as
      // missing.  Undefined falls back to the helper's default.
      sidecarDir: config.versioningSidecarDir
    });
  } catch (err) {
    return {
      key: "consolidation_provenance",
      status: "warn",
      summary: "Could not run consolidation-provenance integrity check.",
      remediation: "Ensure the memory directory is readable and rerun `remnic doctor`.",
      details: { error: String(err) }
    };
  }
  if (report.issues.length === 0) {
    return {
      key: "consolidation_provenance",
      status: "ok",
      summary: report.withProvenance === 0 ? "No consolidation-provenance memories on disk yet." : `${report.withProvenance} consolidation-provenance memories verified (no broken references).`,
      details: report
    };
  }
  return {
    key: "consolidation_provenance",
    status: "warn",
    summary: `${report.issues.length} consolidation-provenance integrity issue(s) detected across ${report.withProvenance} memories with provenance frontmatter.`,
    remediation: "Broken pointers are informational. Inspect flagged memories, and if they should resolve, re-snapshot via a consolidation pass or accept pruning.",
    details: report
  };
}
function getMemoryAgeBand(memory, now) {
  const created = Date.parse(memory.frontmatter.created ?? "");
  if (!Number.isFinite(created)) return "unknown";
  const ageDays = Math.max(0, Math.floor((now.getTime() - created) / 864e5));
  if (ageDays < 7) return "0_6d";
  if (ageDays < 30) return "7_29d";
  if (ageDays < 90) return "30_89d";
  return "90d_plus";
}
async function dirSize(targetPath) {
  try {
    const info = await stat(targetPath);
    if (info.isFile()) return info.size;
    if (!info.isDirectory()) return 0;
  } catch {
    return 0;
  }
  let total = 0;
  let entries;
  try {
    entries = await readdir2(targetPath, { withFileTypes: true });
  } catch {
    return 0;
  }
  for (const entry of entries) {
    total += await dirSize(path2.join(targetPath, entry.name));
  }
  return total;
}
async function summarizeStorageFootprint(memoryDir) {
  const topLevel = [
    "facts",
    "entities",
    "questions",
    "corrections",
    "artifacts",
    "state",
    "identity",
    "namespaces",
    "summaries",
    "profile.md"
  ];
  const byTopLevel = {};
  let bytes = 0;
  for (const name of topLevel) {
    const size = await dirSize(path2.join(memoryDir, name));
    if (size > 0) {
      byTopLevel[name] = size;
      bytes += size;
    }
  }
  return { bytes, byTopLevel };
}
async function runOperatorInventory(options) {
  const now = options.now ?? /* @__PURE__ */ new Date();
  const config = options.orchestrator.config;
  const namespaceEntries = await listNamespaces({ config });
  const uniqueRootEntries = /* @__PURE__ */ new Map();
  for (const entry of namespaceEntries) {
    if (!uniqueRootEntries.has(entry.rootDir)) {
      uniqueRootEntries.set(entry.rootDir, { namespace: entry.namespace, rootDir: entry.rootDir });
    }
  }
  const categories = {};
  const statuses = {};
  const ageBands = {
    "0_6d": 0,
    "7_29d": 0,
    "30_89d": 0,
    "90d_plus": 0,
    unknown: 0
  };
  const namespaces = [];
  let totalMemories = 0;
  let totalEntities = 0;
  let archived = 0;
  let pendingReview = 0;
  let quarantined = 0;
  let rejected = 0;
  for (const entry of uniqueRootEntries.values()) {
    const storage = new StorageManager(entry.rootDir);
    const memories = await storage.readAllMemories();
    const entities = await storage.readAllEntityFiles();
    namespaces.push({
      namespace: entry.namespace,
      memoryCount: memories.length,
      entityCount: entities.length
    });
    totalMemories += memories.length;
    totalEntities += entities.length;
    for (const memory of memories) {
      const category = memory.frontmatter.category;
      categories[category] = (categories[category] ?? 0) + 1;
      const status = memory.frontmatter.status ?? "active";
      statuses[status] = (statuses[status] ?? 0) + 1;
      ageBands[getMemoryAgeBand(memory, now)] += 1;
      if (status === "archived") archived += 1;
      if (status === "pending_review") pendingReview += 1;
      if (status === "quarantined") quarantined += 1;
      if (status === "rejected") rejected += 1;
    }
  }
  const defaultStorage = new StorageManager(config.memoryDir);
  const profile = await defaultStorage.readProfile();
  const footprint = await summarizeStorageFootprint(config.memoryDir);
  const reviewRunId = (await listMemoryGovernanceRuns(config.memoryDir))[0];
  let reviewQueue = 0;
  if (reviewRunId) {
    try {
      reviewQueue = (await readMemoryGovernanceRunArtifact(config.memoryDir, reviewRunId)).reviewQueue.length;
    } catch {
      reviewQueue = 0;
    }
  }
  const conversationIndex = await options.orchestrator.getConversationIndexHealth();
  const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(config);
  return {
    schemaVersion: 1,
    generatedAt: now.toISOString(),
    memoryDir: config.memoryDir,
    totals: {
      memories: totalMemories,
      entities: totalEntities,
      namespaces: namespaceEntries.length,
      reviewQueue,
      storageBytes: footprint.bytes
    },
    categories,
    statuses,
    namespaces,
    ageBands,
    profile: {
      exists: profile.length > 0,
      chars: profile.length,
      lines: profile.length > 0 ? profile.split("\n").length : 0
    },
    storageFootprint: footprint,
    archivePressure: {
      archived,
      pendingReview,
      quarantined,
      rejected
    },
    conversationIndex: {
      enabled: conversationIndex.enabled,
      backend: conversationIndex.backend,
      status: conversationIndex.status,
      chunkDocCount: conversationIndex.chunkDocCount,
      lastUpdateAt: conversationIndex.lastUpdateAt
    },
    nativeKnowledge: {
      enabled: nativeKnowledgeStatus.enabled,
      curatedIncludeSync: nativeKnowledgeStatus.curatedIncludeSync,
      obsidianSync: nativeKnowledgeStatus.obsidianSync,
      openclawWorkspaceSync: nativeKnowledgeStatus.openclawWorkspaceSync
    }
  };
}
async function runBenchmarkRecall(options) {
  const now = options.now ?? /* @__PURE__ */ new Date();
  const status = await getEvalHarnessStatus({
    memoryDir: options.config.memoryDir,
    evalStoreDir: options.config.evalStoreDir,
    enabled: options.config.evalHarnessEnabled,
    shadowModeEnabled: options.config.evalShadowModeEnabled,
    baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,
    memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled
  });
  if (options.createSnapshot && options.snapshotId) {
    const snapshot = await createEvalBaselineSnapshot({
      memoryDir: options.config.memoryDir,
      evalStoreDir: options.config.evalStoreDir,
      baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,
      snapshotId: options.snapshotId,
      notes: options.snapshotNotes,
      gitRef: options.gitRef,
      createdAt: options.createdAt
    });
    return {
      schemaVersion: 1,
      generatedAt: now.toISOString(),
      mode: "snapshot",
      status,
      snapshot: {
        targetPath: snapshot.targetPath,
        snapshotId: snapshot.snapshot.snapshotId
      }
    };
  }
  if (options.baseEvalStoreDir && options.candidateEvalStoreDir) {
    const ciGate = await runEvalBenchmarkCiGate({
      baseEvalStoreDir: options.baseEvalStoreDir,
      candidateEvalStoreDir: options.candidateEvalStoreDir
    });
    return {
      schemaVersion: 1,
      generatedAt: now.toISOString(),
      mode: "ci-gate",
      status,
      ciGate
    };
  }
  if (options.snapshotId) {
    const baselineReport = await runEvalBaselineDeltaReport({
      memoryDir: options.config.memoryDir,
      evalStoreDir: options.config.evalStoreDir,
      benchmarkDeltaReporterEnabled: options.config.benchmarkDeltaReporterEnabled,
      snapshotId: options.snapshotId
    });
    return {
      schemaVersion: 1,
      generatedAt: now.toISOString(),
      mode: "baseline-report",
      status,
      baselineReport
    };
  }
  if (options.validatePath) {
    const validate = await validateEvalBenchmarkPack(options.validatePath, {
      memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled
    });
    return {
      schemaVersion: 1,
      generatedAt: now.toISOString(),
      mode: "validate",
      status,
      validate
    };
  }
  return {
    schemaVersion: 1,
    generatedAt: now.toISOString(),
    mode: "status",
    status
  };
}
async function runOperatorRepair(options) {
  const now = options.now ?? /* @__PURE__ */ new Date();
  const dryRun = options.dryRun === true || options.apply !== true;
  const sessionCheck = await analyzeSessionIntegrity({ memoryDir: options.config.memoryDir });
  const sessionRepairPlan = planSessionRepair({
    report: sessionCheck,
    dryRun,
    allowSessionFileRepair: options.allowSessionFileRepair,
    sessionFilesDir: options.sessionFilesDir
  });
  const sessionRepairApply = await applySessionRepair({
    plan: sessionRepairPlan
  });
  const graphHealth = await analyzeGraphHealth(options.config.memoryDir, {
    entityGraphEnabled: options.config.entityGraphEnabled,
    timeGraphEnabled: options.config.timeGraphEnabled,
    causalGraphEnabled: options.config.causalGraphEnabled,
    includeRepairGuidance: true
  });
  return {
    schemaVersion: 1,
    generatedAt: now.toISOString(),
    dryRun,
    sessionCheck,
    sessionRepairPlan,
    sessionRepairApply,
    graphHealth
  };
}

export {
  listNamespaces,
  verifyNamespaces,
  runNamespaceMigration,
  runOperatorSetup,
  runOperatorConfigReview,
  runOperatorDoctor,
  summarizeMemoryWorthLegacyCounters,
  summarizeBufferSurpriseDistribution,
  summarizeTierDistribution,
  summarizeDreamsPhases,
  summarizeObservationThroughput,
  summarizeConsolidationProvenance,
  runOperatorInventory,
  runBenchmarkRecall,
  runOperatorRepair
};
//# sourceMappingURL=chunk-I6BQZSML.js.map