import {
  expandTildePath
} from "./chunk-IXEJRKCZ.js";
import {
  StorageManager
} from "./chunk-MCC6KDQF.js";
import {
  parseContinuityImprovementLoops
} from "./chunk-QSVPYQPG.js";
import {
  sanitizeMemoryContent
} from "./chunk-FVQJYWH7.js";
import {
  log
} from "./chunk-2ODBA7MQ.js";

// src/compounding/engine.ts
import { createHash } from "crypto";
import { mkdir as mkdir2, readFile as readFile2, readdir as readdir2, unlink, writeFile as writeFile2 } from "fs/promises";
import path2 from "path";

// src/shared-context/manager.ts
import { mkdir, readFile, readdir, appendFile, writeFile, stat } from "fs/promises";
import path from "path";
import { z } from "zod";
var SharedFeedbackEntrySchema = z.object({
  agent: z.string().min(1),
  decision: z.enum(["approved", "approved_with_feedback", "rejected"]),
  reason: z.string().min(1),
  date: z.string().min(8),
  // ISO-ish; keep loose
  learning: z.string().optional(),
  outcome: z.string().optional(),
  severity: z.enum(["low", "medium", "high"]).optional(),
  confidence: z.number().min(0).max(1).optional(),
  workflow: z.string().min(1).optional(),
  tags: z.array(z.string().min(1)).optional(),
  evidenceWindowStart: z.string().min(8).optional(),
  evidenceWindowEnd: z.string().min(8).optional(),
  refs: z.array(z.string()).optional()
});
function safeSlug(s) {
  let slug = s.toLowerCase().replace(/[^a-z0-9]+/g, "-");
  let start = 0;
  while (start < slug.length && slug[start] === "-") start++;
  let end = slug.length;
  while (end > start && slug[end - 1] === "-") end--;
  return slug.slice(start, end).slice(0, 80) || "output";
}
function ymd(d) {
  return d.toISOString().slice(0, 10);
}
var CROSS_SIGNAL_STOPWORDS = /* @__PURE__ */ new Set([
  "a",
  "an",
  "and",
  "are",
  "as",
  "at",
  "be",
  "by",
  "for",
  "from",
  "has",
  "have",
  "in",
  "is",
  "it",
  "of",
  "on",
  "or",
  "that",
  "the",
  "this",
  "to",
  "was",
  "were",
  "with",
  "agent",
  "output",
  "today",
  "daily",
  "notes",
  "note",
  "summary"
]);
function extractTopicTokens(text, maxTokens = 12) {
  const seen = /* @__PURE__ */ new Set();
  const out = [];
  const tokens = text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).map((token) => token.trim()).filter((token) => token.length >= 4).filter((token) => !CROSS_SIGNAL_STOPWORDS.has(token));
  for (const token of tokens) {
    if (seen.has(token)) continue;
    seen.add(token);
    out.push(token);
    if (out.length >= maxTokens) break;
  }
  return out;
}
function stripYamlFrontmatter(text) {
  if (!text.startsWith("---\n")) return text;
  const closing = text.indexOf("\n---\n", 4);
  if (closing === -1) return text;
  return text.slice(closing + 5);
}
function semanticRoot(token) {
  let root = token.toLowerCase();
  if (root.endsWith("izations") && root.length > 9) {
    root = `${root.slice(0, -8)}ize`;
  } else if (root.endsWith("ization") && root.length > 8) {
    root = `${root.slice(0, -7)}ize`;
  } else if (root.endsWith("isations") && root.length > 9) {
    root = `${root.slice(0, -8)}ise`;
  } else if (root.endsWith("isation") && root.length > 8) {
    root = `${root.slice(0, -7)}ise`;
  } else {
    const suffixes = [
      "ations",
      "ation",
      "ments",
      "ment",
      "ingly",
      "edly",
      "ings",
      "ing",
      "ers",
      "er",
      "ies",
      "ied",
      "ions",
      "ion",
      "es",
      "ed",
      "s"
    ];
    for (const suffix of suffixes) {
      if (root.length > suffix.length + 3 && root.endsWith(suffix)) {
        root = root.slice(0, -suffix.length);
        break;
      }
    }
  }
  if (root.length > 4 && root.endsWith("e")) {
    root = root.slice(0, -1);
  }
  return root;
}
function mergeOverlaps(base, extra) {
  const merged = /* @__PURE__ */ new Map();
  for (const entry of [...base, ...extra]) {
    const existing = merged.get(entry.token);
    if (existing) {
      for (const agent of entry.agents) existing.agents.add(agent);
      for (const sourcePath of entry.sourcePaths) existing.sourcePaths.add(sourcePath);
    } else {
      merged.set(entry.token, {
        agents: new Set(entry.agents),
        sourcePaths: new Set(entry.sourcePaths)
      });
    }
  }
  return [...merged.entries()].map(([token, value]) => ({
    token,
    agents: [...value.agents].sort(),
    sourcePaths: [...value.sourcePaths].sort(),
    agentCount: value.agents.size
  })).filter((entry) => entry.agentCount >= 2).sort((a, b) => b.agentCount - a.agentCount || a.token.localeCompare(b.token));
}
async function computeSemanticOverlapCandidates(sources, maxCandidates, timeoutAtMs) {
  const tokenRows = [];
  for (const source of sources) {
    for (const token of source.topics) {
      if (Date.now() >= timeoutAtMs) return { overlaps: [], candidateCount: tokenRows.length, timedOut: true };
      await new Promise((resolve) => setImmediate(resolve));
      tokenRows.push({ token, agent: source.agent, path: source.path });
      if (tokenRows.length >= maxCandidates) break;
    }
    if (tokenRows.length >= maxCandidates) break;
  }
  const byRoot = /* @__PURE__ */ new Map();
  for (const row of tokenRows) {
    if (Date.now() >= timeoutAtMs) return { overlaps: [], candidateCount: tokenRows.length, timedOut: true };
    await new Promise((resolve) => setImmediate(resolve));
    const root = semanticRoot(row.token);
    if (root.length < 4) continue;
    const rootGroup = byRoot.get(root) ?? /* @__PURE__ */ new Map();
    const tokenGroup = rootGroup.get(row.token) ?? { agents: /* @__PURE__ */ new Set(), paths: /* @__PURE__ */ new Set() };
    tokenGroup.agents.add(row.agent);
    tokenGroup.paths.add(row.path);
    rootGroup.set(row.token, tokenGroup);
    byRoot.set(root, rootGroup);
  }
  const overlaps = [];
  for (const [root, tokenMap] of byRoot.entries()) {
    if (Date.now() >= timeoutAtMs) return { overlaps: [], candidateCount: tokenRows.length, timedOut: true };
    await new Promise((resolve) => setImmediate(resolve));
    if (tokenMap.size < 2) continue;
    const agents = /* @__PURE__ */ new Set();
    const sourcePaths = /* @__PURE__ */ new Set();
    for (const value of tokenMap.values()) {
      for (const agent of value.agents) agents.add(agent);
      for (const sourcePath of value.paths) sourcePaths.add(sourcePath);
    }
    if (agents.size < 2) continue;
    overlaps.push({
      token: `semantic:${root}`,
      agents: [...agents].sort(),
      sourcePaths: [...sourcePaths].sort(),
      agentCount: agents.size
    });
  }
  overlaps.sort((a, b) => b.agentCount - a.agentCount || a.token.localeCompare(b.token));
  return {
    overlaps,
    candidateCount: tokenRows.length,
    timedOut: false
  };
}
async function computeSemanticOverlapsWithTimeout(sources, timeoutMs, maxCandidates) {
  const safeTimeoutMs = Math.max(1, Math.floor(timeoutMs));
  const safeMaxCandidates = Math.max(0, Math.floor(maxCandidates));
  if (safeMaxCandidates === 0 || sources.length === 0) {
    return { overlaps: [], candidateCount: 0, timedOut: false };
  }
  const timeoutAtMs = Date.now() + safeTimeoutMs;
  return computeSemanticOverlapCandidates(sources, safeMaxCandidates, timeoutAtMs);
}
function feedbackDecisionPriority(decision) {
  switch (decision) {
    case "rejected":
      return 3;
    case "approved_with_feedback":
      return 2;
    case "approved":
      return 1;
  }
}
function feedbackSeverityPriority(severity) {
  switch (severity) {
    case "high":
      return 3;
    case "medium":
      return 2;
    case "low":
      return 1;
    default:
      return 0;
  }
}
function compareFeedbackPriority(a, b) {
  return feedbackDecisionPriority(b.decision) - feedbackDecisionPriority(a.decision) || feedbackSeverityPriority(b.severity) - feedbackSeverityPriority(a.severity) || a.date.localeCompare(b.date);
}
function formatFeedbackLine(entry) {
  const extras = [`feedback: ${entry.date}`];
  if (entry.severity) extras.push(`severity: ${entry.severity}`);
  if (entry.refs?.length) extras.push(`refs: ${entry.refs.join(", ")}`);
  return `- [${entry.agent}] ${entry.decision}: ${entry.reason} [${extras.join("; ")}]`;
}
function formatOverlapLine(entry) {
  return `- \`${entry.token}\` (${entry.agentCount} agents: ${entry.agents.join(", ")}) [sources: ${entry.sourcePaths.join(", ")}]`;
}
function resolveSharedContextDir(config) {
  return typeof config.sharedContextDir === "string" && config.sharedContextDir.length > 0 ? expandTildePath(config.sharedContextDir) : path.join(expandTildePath(config.workspaceDir), "shared-context");
}
var SharedContextManager = class {
  constructor(config) {
    this.config = config;
    const base = resolveSharedContextDir(config);
    this.dir = base;
    this.prioritiesPath = path.join(base, "priorities.md");
    this.prioritiesInboxPath = path.join(base, "priorities.inbox.md");
    this.outputsDir = path.join(base, "agent-outputs");
    this.roundtableDir = path.join(base, "roundtable");
    this.feedbackDir = path.join(base, "feedback");
    this.feedbackInboxPath = path.join(this.feedbackDir, "inbox.jsonl");
    this.crossSignalsDir = path.join(base, "cross-signals");
  }
  config;
  dir;
  prioritiesPath;
  prioritiesInboxPath;
  outputsDir;
  roundtableDir;
  feedbackDir;
  feedbackInboxPath;
  crossSignalsDir;
  async ensureStructure() {
    await mkdir(this.dir, { recursive: true });
    await mkdir(this.outputsDir, { recursive: true });
    await mkdir(this.roundtableDir, { recursive: true });
    await mkdir(this.feedbackDir, { recursive: true });
    await mkdir(this.crossSignalsDir, { recursive: true });
    await mkdir(path.join(this.dir, "staging"), { recursive: true });
    await mkdir(path.join(this.dir, "kpis"), { recursive: true });
    await mkdir(path.join(this.dir, "calendar"), { recursive: true });
    await mkdir(path.join(this.dir, "content-calendar"), { recursive: true });
    await this.ensureFile(
      this.prioritiesPath,
      [
        "# Priorities",
        "",
        "This is the shared priority stack. Agents should read this before acting.",
        "",
        "## Current",
        "- (empty)",
        "",
        "## Notes",
        "- (empty)",
        ""
      ].join("\n")
    );
    await this.ensureFile(
      this.prioritiesInboxPath,
      [
        "# Priorities Inbox",
        "",
        "Append-only inbox. Curator merges into priorities.md.",
        ""
      ].join("\n")
    );
    await this.ensureFile(this.feedbackInboxPath, "");
  }
  async ensureFile(fp, content) {
    try {
      await stat(fp);
    } catch {
      await writeFile(fp, content, "utf-8");
    }
  }
  async readPriorities() {
    try {
      return await readFile(this.prioritiesPath, "utf-8");
    } catch {
      return "";
    }
  }
  async readLatestRoundtable() {
    try {
      const files = (await readdir(this.roundtableDir)).filter((f) => f.endsWith(".md")).sort().reverse();
      const fp = files[0] ? path.join(this.roundtableDir, files[0]) : null;
      if (!fp) return "";
      return await readFile(fp, "utf-8");
    } catch {
      return "";
    }
  }
  async readLatestCrossSignals() {
    try {
      const files = (await readdir(this.crossSignalsDir)).filter((f) => f.endsWith(".md")).sort().reverse();
      const fp = files[0] ? path.join(this.crossSignalsDir, files[0]) : null;
      if (!fp) return "";
      return await readFile(fp, "utf-8");
    } catch {
      return "";
    }
  }
  async writeAgentOutput(opts) {
    const createdAt = opts.createdAt ?? /* @__PURE__ */ new Date();
    const date = ymd(createdAt);
    const time = createdAt.toISOString().slice(11, 19).replace(/:/g, "");
    const slug = safeSlug(opts.title);
    const dir = path.join(this.outputsDir, opts.agentId, date);
    await mkdir(dir, { recursive: true });
    const fp = path.join(dir, `${time}-${slug}.md`);
    const body = `---
kind: agent_output
agent: ${opts.agentId}
createdAt: ${createdAt.toISOString()}
title: ${opts.title.replace(/\n/g, " ").slice(0, 200)}
---

` + opts.content.trimEnd() + "\n";
    await writeFile(fp, body, "utf-8");
    return fp;
  }
  async appendFeedback(entry) {
    const parsed = SharedFeedbackEntrySchema.parse(entry);
    await appendFile(this.feedbackInboxPath, JSON.stringify(parsed) + "\n", "utf-8");
  }
  async appendPrioritiesInbox(opts) {
    const stamp = (/* @__PURE__ */ new Date()).toISOString();
    const lines = [
      "",
      `## ${stamp} (${opts.agentId})`,
      "",
      opts.text.trimEnd(),
      ""
    ].join("\n");
    await appendFile(this.prioritiesInboxPath, lines, "utf-8");
  }
  async synthesizeCrossSignals(opts) {
    const date = opts.date ?? ymd(/* @__PURE__ */ new Date());
    const maxSummaryItems = Math.max(1, opts.maxSummaryItems ?? 8);
    const outputs = [];
    try {
      const agents = await readdir(this.outputsDir, { withFileTypes: true });
      for (const a of agents) {
        if (!a.isDirectory()) continue;
        const dayDir = path.join(this.outputsDir, a.name, date);
        try {
          const files = (await readdir(dayDir)).filter((f) => f.endsWith(".md")).sort();
          for (const f of files) {
            const p = path.join(dayDir, f);
            const raw = await readFile(p, "utf-8");
            const title = (raw.match(/^title:\s*(.+)$/m)?.[1] ?? f).trim();
            outputs.push({ agent: a.name, path: p, title, raw });
          }
        } catch {
        }
      }
    } catch {
    }
    const feedback = [];
    try {
      const raw = await readFile(this.feedbackInboxPath, "utf-8");
      for (const line of raw.split("\n")) {
        if (!line.trim()) continue;
        try {
          const obj = JSON.parse(line);
          const parsed = SharedFeedbackEntrySchema.safeParse(obj);
          if (!parsed.success) continue;
          if (String(parsed.data.date).startsWith(date)) feedback.push(parsed.data);
        } catch {
        }
      }
    } catch {
    }
    const sources = outputs.map((output) => {
      const body = stripYamlFrontmatter(output.raw);
      return {
        agent: output.agent,
        path: output.path,
        title: output.title,
        topics: extractTopicTokens(`${output.title}
${body}`)
      };
    });
    const overlapMap = /* @__PURE__ */ new Map();
    for (const source of sources) {
      for (const token of source.topics) {
        const existing = overlapMap.get(token);
        if (existing) {
          existing.agents.add(source.agent);
          existing.sourcePaths.add(source.path);
        } else {
          overlapMap.set(token, {
            agents: /* @__PURE__ */ new Set([source.agent]),
            sourcePaths: /* @__PURE__ */ new Set([source.path])
          });
        }
      }
    }
    const overlaps = [...overlapMap.entries()].map(([token, v]) => ({
      token,
      agents: [...v.agents].sort(),
      sourcePaths: [...v.sourcePaths].sort(),
      agentCount: v.agents.size
    })).filter((entry) => entry.agentCount >= 2).sort((a, b) => b.agentCount - a.agentCount || a.token.localeCompare(b.token));
    const semanticEnabled = this.config.sharedCrossSignalSemanticEnabled === true || this.config.crossSignalsSemanticEnabled === true;
    const semanticTimeoutMs = this.config.sharedCrossSignalSemanticTimeoutMs ?? this.config.crossSignalsSemanticTimeoutMs ?? 4e3;
    const semanticMaxCandidates = this.config.sharedCrossSignalSemanticMaxCandidates ?? 120;
    let semanticApplied = false;
    let semanticTimedOut = false;
    let semanticCandidateCount = 0;
    let semanticAddedOverlapCount = 0;
    let mergedOverlaps = overlaps;
    if (semanticEnabled) {
      try {
        const semanticResult = await computeSemanticOverlapsWithTimeout(
          sources,
          semanticTimeoutMs,
          semanticMaxCandidates
        );
        semanticTimedOut = semanticResult.timedOut;
        semanticCandidateCount = semanticResult.candidateCount;
        if (!semanticResult.timedOut && semanticResult.overlaps.length > 0) {
          mergedOverlaps = mergeOverlaps(overlaps, semanticResult.overlaps);
          semanticAddedOverlapCount = Math.max(0, mergedOverlaps.length - overlaps.length);
          semanticApplied = semanticAddedOverlapCount > 0;
        }
      } catch (err) {
        log.warn(`shared-context semantic cross-signals failed; fail-open to deterministic output: ${err}`);
      }
    }
    const feedbackByDecision = {
      approved: 0,
      approved_with_feedback: 0,
      rejected: 0
    };
    for (const entry of feedback) {
      feedbackByDecision[entry.decision] += 1;
    }
    const report = {
      date,
      generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
      sourceCount: sources.length,
      feedbackCount: feedback.length,
      feedbackByDecision,
      feedbackEntries: [...feedback].sort(compareFeedbackPriority),
      sources,
      overlaps: mergedOverlaps,
      semantic: {
        enabled: semanticEnabled,
        applied: semanticApplied,
        timedOut: semanticTimedOut,
        candidateCount: semanticCandidateCount,
        maxCandidates: Math.max(0, Math.floor(semanticMaxCandidates)),
        addedOverlapCount: semanticAddedOverlapCount
      }
    };
    const crossSignalsPath = path.join(this.crossSignalsDir, `${date}.json`);
    await writeFile(crossSignalsPath, `${JSON.stringify(report, null, 2)}
`, "utf-8");
    const recurringThemeLines = mergedOverlaps.length === 0 ? ["- No multi-agent topic overlap detected."] : mergedOverlaps.slice(0, maxSummaryItems).map((entry) => formatOverlapLine(entry));
    const riskSignals = [...feedback].filter((entry) => entry.decision !== "approved" || entry.severity === "high" || entry.severity === "medium").sort(compareFeedbackPriority).slice(0, maxSummaryItems);
    const riskLines = riskSignals.length === 0 ? ["- No explicit blockers or elevated review risks recorded."] : riskSignals.map((entry) => formatFeedbackLine(entry));
    const promotionCandidates = mergedOverlaps.filter((entry) => entry.agentCount >= 3).slice(0, maxSummaryItems);
    const promotionLines = promotionCandidates.length === 0 ? ["- No promotion candidates yet."] : promotionCandidates.map(
      (entry) => `- Consider promoting \`${entry.token}\` into priorities or operating rules [sources: ${entry.sourcePaths.join(", ")}]`
    );
    const crossSignalsMarkdown = [
      `# Cross-Signals \u2014 ${date}`,
      "",
      "## Overview",
      `- Source outputs analyzed: ${sources.length}`,
      `- Feedback entries analyzed: ${feedback.length}`,
      `- Decision totals: approved=${feedbackByDecision.approved}, approved_with_feedback=${feedbackByDecision.approved_with_feedback}, rejected=${feedbackByDecision.rejected}`,
      `- Semantic enhancer: ${semanticEnabled ? semanticTimedOut ? "enabled (timed out, fail-open)" : semanticApplied ? "enabled (applied)" : "enabled (no additional overlaps)" : "disabled"}`,
      `- JSON report: ${crossSignalsPath}`,
      "",
      "## Recurring Themes",
      ...recurringThemeLines,
      "",
      "## Risks And Blockers",
      ...riskLines,
      "",
      "## Potential Promotions",
      ...promotionLines,
      "",
      "## Sources",
      ...sources.length === 0 ? ["- (none)"] : sources.map(
        (source) => `- [${source.agent}] ${source.title} (${source.path})`
      ),
      ""
    ].join("\n");
    const crossSignalsMarkdownPath = path.join(this.crossSignalsDir, `${date}.md`);
    await writeFile(crossSignalsMarkdownPath, crossSignalsMarkdown, "utf-8");
    return {
      date,
      crossSignalsPath,
      crossSignalsMarkdownPath,
      overlapCount: mergedOverlaps.length,
      report
    };
  }
  async curateDaily(opts) {
    const date = opts.date ?? ymd(/* @__PURE__ */ new Date());
    const maxChars = Math.max(2e3, opts.maxChars ?? 2e4);
    const crossSignals = await this.synthesizeCrossSignals({ date });
    const feedbackLines = crossSignals.report.feedbackEntries.length === 0 ? ["- (none)"] : crossSignals.report.feedbackEntries.map((entry) => formatFeedbackLine(entry));
    const overlapBullets = crossSignals.report.overlaps.length === 0 ? ["- No multi-agent topic overlap detected."] : crossSignals.report.overlaps.slice(0, 8).map((entry) => formatOverlapLine(entry));
    const md = [
      `# Roundtable \u2014 ${date}`,
      "",
      "## Notable Agent Outputs",
      ...crossSignals.report.sources.length === 0 ? ["- (none)"] : crossSignals.report.sources.map((source) => `- ${source.title} (${source.path})`),
      "",
      "## Feedback (Approve/Reject)",
      ...feedbackLines,
      "",
      "## Cross-Signals",
      `- Source outputs analyzed: ${crossSignals.report.sourceCount}`,
      `- Feedback entries analyzed: ${crossSignals.report.feedbackCount}`,
      `- Decision totals: approved=${crossSignals.report.feedbackByDecision.approved}, approved_with_feedback=${crossSignals.report.feedbackByDecision.approved_with_feedback}, rejected=${crossSignals.report.feedbackByDecision.rejected}`,
      `- Semantic enhancer: ${crossSignals.report.semantic.enabled ? crossSignals.report.semantic.timedOut ? "enabled (timed out, fail-open)" : crossSignals.report.semantic.applied ? "enabled (applied)" : "enabled (no additional overlaps)" : "disabled"}`,
      `- Cross-signals JSON: ${crossSignals.crossSignalsPath}`,
      `- Cross-signals markdown: ${crossSignals.crossSignalsMarkdownPath}`,
      ...overlapBullets,
      ""
    ];
    const out = md.join("\n");
    const trimmed = out.length > maxChars ? out.slice(0, maxChars) + "\n\n...(trimmed)\n" : out;
    const roundtablePath = path.join(this.roundtableDir, `${date}.md`);
    await writeFile(roundtablePath, trimmed, "utf-8");
    log.info(`shared-context curated daily roundtable: ${roundtablePath}`);
    return {
      date,
      roundtablePath,
      crossSignalsPath: crossSignals.crossSignalsPath,
      crossSignalsMarkdownPath: crossSignals.crossSignalsMarkdownPath,
      overlapCount: crossSignals.overlapCount
    };
  }
};

// src/compounding/engine.ts
var COMPOUNDING_VERSION = 2;
var RETIREMENT_WINDOW_WEEKS = 8;
function stableSlug(value) {
  return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "item";
}
function tokenizeRecallQuery(text) {
  const seen = /* @__PURE__ */ new Set();
  const out = [];
  for (const token of text.toLowerCase().replace(/[^a-z0-9\s]+/g, " ").split(/\s+/).map((part) => part.trim()).filter((part) => part.length >= 3)) {
    if (seen.has(token)) continue;
    seen.add(token);
    out.push(token);
  }
  return out;
}
function weekIdToIndex(weekId) {
  const match = weekId.match(/^(\d{4})-W(\d{2})$/);
  if (!match) return Number.POSITIVE_INFINITY;
  const year = Number(match[1]);
  const week = Number(match[2]);
  if (!Number.isInteger(year) || !Number.isInteger(week) || week < 1 || week > 53) {
    return Number.POSITIVE_INFINITY;
  }
  const jan4 = new Date(Date.UTC(year, 0, 4));
  const jan4Day = jan4.getUTCDay() || 7;
  const isoWeekOneStart = new Date(jan4);
  isoWeekOneStart.setUTCDate(jan4.getUTCDate() - (jan4Day - 1));
  const targetWeekStart = new Date(isoWeekOneStart);
  targetWeekStart.setUTCDate(isoWeekOneStart.getUTCDate() + (week - 1) * 7);
  return Math.floor(targetWeekStart.getTime() / (7 * 24 * 60 * 60 * 1e3));
}
function normalizeConfidence(value) {
  if (typeof value !== "number" || !Number.isFinite(value)) return null;
  const clamped = Math.max(0, Math.min(1, value));
  return Number(clamped.toFixed(3));
}
function normalizeTags(tags) {
  if (!Array.isArray(tags)) return [];
  return [...new Set(tags.map((tag) => String(tag).trim()).filter((tag) => tag.length > 0))].sort();
}
function normalizeEvidenceWindow(start, end) {
  const safeStart = typeof start === "string" && start.trim().length > 0 ? start : null;
  const safeEnd = typeof end === "string" && end.trim().length > 0 ? end : null;
  return { start: safeStart, end: safeEnd };
}
function mergeEvidenceWindows(current, next) {
  return {
    start: current.start === null ? next.start : next.start === null ? current.start : current.start <= next.start ? current.start : next.start,
    end: current.end === null ? next.end : next.end === null ? current.end : current.end >= next.end ? current.end : next.end
  };
}
function stableMistakeId(category, pattern, agent, workflow) {
  return [
    category,
    agent ? stableSlug(agent) : "global",
    workflow ? stableSlug(workflow) : "default",
    stableSlug(pattern).slice(0, 48)
  ].join(":");
}
function stableRubricId(kind, subject) {
  return `${kind}:${stableSlug(subject)}`;
}
function stablePromotionCandidateId(sourceType, subject, content) {
  const digest = createHash("sha256").update(`${sourceType}\0${subject}\0${content}`).digest("hex").slice(0, 12);
  return `${sourceType}:${digest}`;
}
function rubricArtifactFileName(entry, slugCollisions) {
  const slug = stableSlug(entry.subject);
  if ((slugCollisions.get(slug) ?? 0) <= 1) return `${slug}.md`;
  const suffix = createHash("sha256").update(`${entry.kind}:${entry.subject}`).digest("hex").slice(0, 8);
  return `${slug}-${suffix}.md`;
}
function inferLegacyMistakeScope(pattern) {
  const separatorIndex = pattern.indexOf(":");
  if (separatorIndex <= 0) return { agent: null, workflow: null };
  const subject = pattern.slice(0, separatorIndex).trim();
  return {
    agent: subject.length > 0 ? subject : null,
    workflow: null
  };
}
function inferLegacyMistakeMetadata(pattern) {
  if (pattern.startsWith("memory-action/")) {
    return {
      category: "action",
      agent: null,
      workflow: "memory-actions"
    };
  }
  const scope = inferLegacyMistakeScope(pattern);
  return {
    category: "feedback",
    agent: scope.agent,
    workflow: scope.workflow
  };
}
function normalizePromotionWhitespace(value) {
  return value.replace(/\s+/g, " ").trim();
}
function stripTrailingPromotionPunctuation(value) {
  return value.replace(/[,:;]+$/g, "").trim();
}
function extractExplicitIfThenRule(value) {
  const normalized = normalizePromotionWhitespace(value);
  const match = normalized.match(/^if\b([\s\S]+?)\bthen\b([\s\S]+?)(?:[.!?])?$/i);
  if (!match) return null;
  const condition = stripTrailingPromotionPunctuation(normalizePromotionWhitespace(match[1] ?? ""));
  const outcome = stripTrailingPromotionPunctuation(normalizePromotionWhitespace(match[2] ?? ""));
  if (condition.length === 0 || outcome.length === 0) return null;
  return `IF ${condition} THEN ${outcome}.`;
}
function normalizePromotedGuidanceContent(value) {
  const explicitRule = extractExplicitIfThenRule(value);
  if (explicitRule) return explicitRule;
  const normalized = normalizePromotionWhitespace(value);
  if (normalized.length === 0) return normalized;
  return /[.!?]$/.test(normalized) ? normalized : `${normalized}.`;
}
function canonicalPromotionContentKey(value) {
  return normalizePromotedGuidanceContent(value).toLowerCase();
}
function lessonContentFromPattern(pattern, agent) {
  if (!agent) return normalizePromotionWhitespace(pattern);
  const prefix = `${agent}:`;
  if (!pattern.startsWith(prefix)) return normalizePromotionWhitespace(pattern);
  const withoutPrefix = pattern.slice(prefix.length).trim();
  return withoutPrefix.length > 0 ? normalizePromotionWhitespace(withoutPrefix) : normalizePromotionWhitespace(pattern);
}
function promotionCategoryForContent(content) {
  return extractExplicitIfThenRule(content) ? "rule" : "principle";
}
function clampPromotionScore(value) {
  if (!Number.isFinite(value)) return 0.65;
  return Number(Math.max(0.65, Math.min(0.98, value)).toFixed(3));
}
function defaultTierMigrationCycleBudget(config, trigger) {
  if (trigger === "extraction") {
    const limit2 = 12;
    return {
      limit: limit2,
      scanLimit: limit2 * 4,
      minIntervalMs: 6e4
    };
  }
  const limit = config.qmdTierAutoBackfillEnabled ? 200 : 50;
  return {
    limit,
    scanLimit: limit * 4,
    minIntervalMs: config.qmdTierAutoBackfillEnabled ? 12e4 : 3e5
  };
}
function isoWeekId(d) {
  const dt = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
  const day = dt.getUTCDay() || 7;
  dt.setUTCDate(dt.getUTCDate() + 4 - day);
  const yearStart = new Date(Date.UTC(dt.getUTCFullYear(), 0, 1));
  const week = Math.ceil(((dt.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
  const yyyy = dt.getUTCFullYear();
  return `${yyyy}-W${String(week).padStart(2, "0")}`;
}
function isoMonthId(d) {
  return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, "0")}`;
}
function monthIdFromIsoWeek(weekId) {
  const match = weekId.match(/^(\d{4})-W(\d{2})$/);
  if (!match) return isoMonthId(/* @__PURE__ */ new Date());
  const year = Number(match[1]);
  const week = Number(match[2]);
  const jan4 = new Date(Date.UTC(year, 0, 4));
  const jan4Day = jan4.getUTCDay() || 7;
  const isoWeekOneMonday = new Date(jan4);
  isoWeekOneMonday.setUTCDate(jan4.getUTCDate() - (jan4Day - 1));
  const monday = new Date(isoWeekOneMonday);
  monday.setUTCDate(isoWeekOneMonday.getUTCDate() + (week - 1) * 7);
  return isoMonthId(monday);
}
function cadenceStaleWindowMs(cadence) {
  switch (cadence) {
    case "daily":
      return 2 * 24 * 60 * 60 * 1e3;
    case "weekly":
      return 10 * 24 * 60 * 60 * 1e3;
    case "monthly":
      return 45 * 24 * 60 * 60 * 1e3;
    case "quarterly":
      return 120 * 24 * 60 * 60 * 1e3;
    default:
      return 45 * 24 * 60 * 60 * 1e3;
  }
}
var CompoundingEngine = class {
  constructor(config, storage = new StorageManager(config.memoryDir)) {
    this.config = config;
    this.storage = storage;
    this.weeklyDir = path2.join(config.memoryDir, "compounding", "weekly");
    this.rubricsDir = path2.join(config.memoryDir, "compounding", "rubrics");
    this.rubricsIndexPath = path2.join(this.rubricsDir, "index.json");
    this.rubricsAgentsDir = path2.join(this.rubricsDir, "agents");
    this.rubricsWorkflowsDir = path2.join(this.rubricsDir, "workflows");
    this.rubricsPath = path2.join(config.memoryDir, "compounding", "rubrics.md");
    this.mistakesPath = path2.join(config.memoryDir, "compounding", "mistakes.json");
    this.feedbackInboxPath = path2.join(resolveSharedContextDir(config), "feedback", "inbox.jsonl");
    this.identityAuditWeeklyDir = path2.join(config.memoryDir, "identity", "audits", "weekly");
    this.identityAuditMonthlyDir = path2.join(config.memoryDir, "identity", "audits", "monthly");
    this.memoryActionEventsPath = path2.join(config.memoryDir, "state", "memory-actions.jsonl");
  }
  config;
  storage;
  weeklyDir;
  rubricsDir;
  rubricsIndexPath;
  rubricsAgentsDir;
  rubricsWorkflowsDir;
  rubricsPath;
  mistakesPath;
  feedbackInboxPath;
  identityAuditWeeklyDir;
  identityAuditMonthlyDir;
  memoryActionEventsPath;
  async ensureDirs() {
    await mkdir2(this.weeklyDir, { recursive: true });
    await mkdir2(path2.dirname(this.mistakesPath), { recursive: true });
    await mkdir2(path2.dirname(this.rubricsPath), { recursive: true });
    await mkdir2(this.rubricsDir, { recursive: true });
    await mkdir2(this.rubricsAgentsDir, { recursive: true });
    await mkdir2(this.rubricsWorkflowsDir, { recursive: true });
  }
  async synthesizeWeekly(opts) {
    await this.ensureDirs();
    const weekId = opts?.weekId ?? isoWeekId(/* @__PURE__ */ new Date());
    const entries = await this.readFeedbackEntriesForWeek(weekId);
    const actionEvents = await this.readActionEventsForWeek(weekId);
    const actionPatterns = this.buildActionFailurePatterns(actionEvents);
    const outcomeSummary = this.buildActionOutcomeSummary(actionEvents);
    const previousMistakes = await this.readMistakes();
    const mistakes = this.buildMistakes(entries, actionPatterns, weekId, previousMistakes?.registry ?? []);
    const rubrics = this.buildRubricSnapshot(entries, outcomeSummary);
    let promotionCandidates = this.config.compoundingSemanticEnabled ? this.derivePromotionCandidates(outcomeSummary, mistakes.registry, rubrics) : [];
    if (this.config.cmcConsolidationEnabled) {
      try {
        const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation.js");
        const causalCandidates = await deriveCausalPromotionCandidates({
          memoryDir: this.config.memoryDir,
          causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,
          gatewayConfig: this.config.gatewayConfig,
          gatewayAgentId: this.config.modelSource === "gateway" ? this.config.gatewayAgentId || void 0 : void 0,
          workspaceDir: this.config.workspaceDir,
          pluginConfig: this.config,
          config: {
            minRecurrence: this.config.cmcConsolidationMinRecurrence,
            minSessions: this.config.cmcConsolidationMinSessions,
            successThreshold: this.config.cmcConsolidationSuccessThreshold
          }
        });
        if (causalCandidates.length > 0) {
          promotionCandidates = [...promotionCandidates, ...causalCandidates];
        }
        try {
          await materializeAfterCausalConsolidation({
            config: this.config,
            memoryDir: this.config.memoryDir
          });
        } catch (materializeError) {
          log.warn(
            `[cmc] Codex materialize post-hook failed (non-fatal): ${materializeError instanceof Error ? materializeError.message : String(materializeError)}`
          );
        }
      } catch (error) {
        log.warn(`[cmc] causal consolidation in synthesizeWeekly failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
      }
    }
    if (this.config.calibrationEnabled) {
      try {
        const { runCalibrationConsolidation } = await import("./calibration.js");
        const calRules = await runCalibrationConsolidation({
          memoryDir: this.config.memoryDir,
          gatewayConfig: this.config.gatewayConfig,
          gatewayAgentId: this.config.modelSource === "gateway" ? this.config.gatewayAgentId || void 0 : void 0,
          workspaceDir: this.config.workspaceDir
        });
        log.debug(`[calibration] weekly synthesis produced ${calRules.length} calibration rule(s)`);
      } catch (error) {
        log.warn(`[calibration] weekly consolidation failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
      }
    }
    const continuity = this.config.continuityAuditEnabled ? await this.readContinuityAuditReferences(weekId) : { monthId: monthIdFromIsoWeek(weekId), weeklyPath: null, monthlyPath: null };
    const reportPath = path2.join(this.weeklyDir, `${weekId}.md`);
    const md = this.formatWeeklyReport(weekId, entries, mistakes.patterns, mistakes.details, continuity, outcomeSummary, promotionCandidates);
    await writeFile2(reportPath, md, "utf-8");
    const reportJsonPath = path2.join(this.weeklyDir, `${weekId}.json`);
    const weeklyArtifact = {
      version: COMPOUNDING_VERSION,
      generatedAt: mistakes.updatedAt,
      weekId,
      feedback: {
        count: entries.length,
        byDecision: {
          approved: entries.filter((wrapped) => wrapped.entry.decision === "approved").length,
          approved_with_feedback: entries.filter((wrapped) => wrapped.entry.decision === "approved_with_feedback").length,
          rejected: entries.filter((wrapped) => wrapped.entry.decision === "rejected").length
        },
        entries: entries.map((wrapped) => ({
          agent: wrapped.entry.agent,
          workflow: wrapped.entry.workflow ?? null,
          decision: wrapped.entry.decision,
          reason: wrapped.entry.reason,
          learning: wrapped.entry.learning?.trim() || null,
          outcome: wrapped.entry.outcome?.trim() || null,
          severity: wrapped.entry.severity ?? null,
          confidence: normalizeConfidence(wrapped.entry.confidence),
          tags: normalizeTags(wrapped.entry.tags),
          provenance: `${path2.basename(wrapped.sourcePath)}:L${wrapped.sourceLine}#${wrapped.entryId}`,
          evidenceWindow: normalizeEvidenceWindow(wrapped.entry.evidenceWindowStart, wrapped.entry.evidenceWindowEnd)
        }))
      },
      mistakes: {
        count: mistakes.patterns.length,
        patterns: mistakes.patterns,
        registry: mistakes.registry
      },
      rubrics,
      outcomes: outcomeSummary,
      promotionCandidates,
      continuity
    };
    await writeFile2(reportJsonPath, JSON.stringify(weeklyArtifact, null, 2) + "\n", "utf-8");
    const rubricsMarkdown = this.formatRubrics(outcomeSummary, rubrics);
    await writeFile2(this.rubricsPath, rubricsMarkdown, "utf-8");
    await writeFile2(this.rubricsIndexPath, JSON.stringify(rubrics, null, 2) + "\n", "utf-8");
    await this.syncRubricArtifacts(rubrics);
    await writeFile2(
      this.mistakesPath,
      JSON.stringify({
        version: COMPOUNDING_VERSION,
        updatedAt: mistakes.updatedAt,
        patterns: mistakes.patterns,
        registry: mistakes.registry
      }, null, 2) + "\n",
      "utf-8"
    );
    log.info(
      `compounding: wrote weekly=${reportPath} weeklyJson=${reportJsonPath} rubrics=${this.rubricsPath} rubricsIndex=${this.rubricsIndexPath} mistakes=${this.mistakesPath}`
    );
    return {
      weekId,
      reportPath,
      reportJsonPath,
      rubricsPath: this.rubricsPath,
      rubricsIndexPath: this.rubricsIndexPath,
      mistakesCount: mistakes.patterns.length,
      promotionCandidateCount: promotionCandidates.length
    };
  }
  async promoteCandidate(opts) {
    const report = {
      enabled: this.config.compoundingEnabled === true && this.config.compoundingSemanticEnabled === true,
      dryRun: opts.dryRun === true,
      weekId: opts.weekId,
      promoted: [],
      skipped: []
    };
    if (!report.enabled) {
      report.skipped.push({ weekId: opts.weekId, candidateId: opts.candidateId, reason: "disabled" });
      return report;
    }
    const artifact = await this.readWeeklyArtifact(opts.weekId);
    if (!artifact) {
      report.skipped.push({ weekId: opts.weekId, candidateId: opts.candidateId, reason: "weekly-artifact-missing" });
      return report;
    }
    const candidate = artifact.promotionCandidates.find((entry) => entry.id === opts.candidateId);
    if (!candidate) {
      report.skipped.push({ weekId: opts.weekId, candidateId: opts.candidateId, reason: "candidate-not-found" });
      return report;
    }
    const content = normalizePromotedGuidanceContent(candidate.content);
    const persistedContent = sanitizeMemoryContent(content).text;
    const storage = opts.storage ?? new StorageManager(this.config.memoryDir);
    const existing = (await storage.readAllMemories()).find(
      (memory) => memory.frontmatter.category === candidate.category && memory.frontmatter.status !== "archived" && memory.frontmatter.status !== "forgotten" && canonicalPromotionContentKey(memory.content) === canonicalPromotionContentKey(persistedContent)
    );
    if (existing) {
      report.skipped.push({
        weekId: opts.weekId,
        candidateId: opts.candidateId,
        reason: "duplicate-guidance",
        existingMemoryId: existing.frontmatter.id
      });
      return report;
    }
    const tags = [
      "compounding",
      "compounding-promotion",
      `compounding-source-${candidate.sourceType}`,
      ...candidate.agent ? [`agent:${stableSlug(candidate.agent)}`] : [],
      ...candidate.workflow ? [`workflow:${stableSlug(candidate.workflow)}`] : []
    ];
    const uniqueTags = [...new Set(tags)];
    const lineage = [`compounding:${opts.weekId}:${opts.candidateId}`];
    const confidence = clampPromotionScore(candidate.score);
    if (opts.dryRun === true) {
      report.promoted.push({
        id: `dry-run:${opts.weekId}:${opts.candidateId}`,
        candidateId: opts.candidateId,
        category: candidate.category,
        content: persistedContent,
        confidence,
        tags: uniqueTags,
        lineage
      });
      return report;
    }
    const id = await storage.writeMemory(candidate.category, persistedContent, {
      source: "compounding-promotion",
      tags: uniqueTags,
      confidence,
      lineage,
      memoryKind: "note"
    });
    report.promoted.push({
      id,
      candidateId: opts.candidateId,
      category: candidate.category,
      content: persistedContent,
      confidence,
      tags: uniqueTags,
      lineage
    });
    return report;
  }
  async synthesizeContinuityAudit(opts) {
    const period = opts?.period === "monthly" ? "monthly" : "weekly";
    const key = opts?.key?.trim() || (period === "weekly" ? isoWeekId(/* @__PURE__ */ new Date()) : isoMonthId(/* @__PURE__ */ new Date()));
    const nowIso = (/* @__PURE__ */ new Date()).toISOString();
    const [identityAnchor, improvementLoopsRaw, openIncidents, closedIncidents, mistakes] = await Promise.all([
      this.readOptionalIdentityAnchorForAudit(),
      this.readOptionalImprovementLoopsForAudit(),
      this.readContinuityIncidentsForAudit(200, "open"),
      this.readContinuityIncidentsForAudit(200, "closed"),
      this.readMistakes()
    ]);
    const anchorPresent = (identityAnchor ?? "").trim().length > 0;
    const improvementLoops = improvementLoopsRaw ? parseContinuityImprovementLoops(improvementLoopsRaw) : [];
    const activeLoops = improvementLoops.filter((loop) => loop.status === "active");
    const staleActiveLoops = activeLoops.filter((loop) => {
      const reviewedAt = Date.parse(loop.lastReviewed);
      if (!Number.isFinite(reviewedAt)) return true;
      return Date.now() - reviewedAt > cadenceStaleWindowMs(loop.cadence);
    });
    const hardeningCandidates = [];
    if (!anchorPresent) {
      hardeningCandidates.push("Create/update identity anchor baseline and verify recovery injection path.");
    }
    if (openIncidents.length > 0) {
      hardeningCandidates.push(
        `Close or downgrade ${openIncidents.length} open continuity incident${openIncidents.length === 1 ? "" : "s"}.`
      );
    }
    if (improvementLoops.length === 0) {
      hardeningCandidates.push("Initialize continuity improvement-loops register with cadence and kill conditions.");
    } else if (staleActiveLoops.length > 0) {
      hardeningCandidates.push(
        `Review stale active continuity loop${staleActiveLoops.length === 1 ? "" : "s"}: ${staleActiveLoops.slice(0, 3).map((loop) => loop.id).join(", ")}.`
      );
    }
    if ((mistakes?.patterns.length ?? 0) > 0) {
      hardeningCandidates.push("Review latest compounding mistakes and convert one pattern into preventive continuity rule.");
    }
    const nextAction = hardeningCandidates[0] ?? "No critical drift detected; keep weekly/monthly continuity audit cadence.";
    const lines = [
      `# Continuity Audit \u2014 ${period} ${key}`,
      "",
      `Generated: ${nowIso}`,
      `Scope: ${period}`,
      "",
      "## Signal Summary",
      `- Identity anchor present: ${anchorPresent ? "yes" : "no"}`,
      `- Improvement loops tracked: ${improvementLoops.length}`,
      `- Active improvement loops: ${activeLoops.length}`,
      `- Stale active loops: ${staleActiveLoops.length}`,
      `- Open incidents: ${openIncidents.length}`,
      `- Closed incidents: ${closedIncidents.length}`,
      `- Compounding mistake patterns: ${mistakes?.patterns.length ?? 0}`,
      "",
      "## Drift Checks",
      `- Identity anchor drift: ${anchorPresent ? "pass" : "needs attention"}`,
      `- Incident backlog: ${openIncidents.length === 0 ? "pass" : "needs attention"}`,
      `- Improvement-loop coverage: ${improvementLoops.length > 0 ? "pass" : "needs attention"}`,
      `- Improvement-loop freshness: ${staleActiveLoops.length === 0 ? "pass" : "needs attention"}`,
      "",
      "## Stale Rule Detection",
      `- Open incidents older than closure window: ${openIncidents.length > 0 ? "possible" : "none detected"}`,
      `- Stale active continuity loops: ${staleActiveLoops.length > 0 ? staleActiveLoops.map((l) => l.id).join(", ") : "none detected"}`,
      `- Preventive rule coverage on closed incidents: ${closedIncidents.some((i) => (i.preventiveRule ?? "").trim().length > 0) ? "present" : "not detected"}`,
      "",
      "## Next Hardening Action",
      `- ${nextAction}`,
      "",
      "## Open Incident IDs",
      ...openIncidents.length > 0 ? openIncidents.slice(0, 20).map((i) => `- ${i.id}`) : ["- (none)"],
      ""
    ];
    const reportPath = await this.storage.writeIdentityAudit(period, key, lines.join("\n"));
    return { period, key, reportPath };
  }
  async readMistakes() {
    try {
      const raw = await readFile2(this.mistakesPath, "utf-8");
      const parsed = JSON.parse(raw);
      if (!parsed || !Array.isArray(parsed.patterns)) return null;
      if (!Array.isArray(parsed.registry)) {
        const updatedAt = typeof parsed.updatedAt === "string" && parsed.updatedAt.length > 0 ? parsed.updatedAt : (/* @__PURE__ */ new Date(0)).toISOString();
        parsed.registry = parsed.patterns.map((pattern) => {
          const metadata = inferLegacyMistakeMetadata(pattern);
          return {
            id: stableMistakeId(metadata.category, pattern, metadata.agent, metadata.workflow),
            pattern,
            category: metadata.category,
            status: "active",
            agent: metadata.agent,
            workflow: metadata.workflow,
            tags: [],
            severity: null,
            confidence: null,
            outcome: null,
            provenance: [],
            firstSeenAt: updatedAt,
            lastSeenAt: updatedAt,
            recurrenceCount: 1,
            lastWeekId: isoWeekId(new Date(updatedAt)),
            evidenceWindow: { start: null, end: null }
          };
        });
      }
      return parsed;
    } catch {
      return null;
    }
  }
  async readRubrics() {
    try {
      const raw = await readFile2(this.rubricsIndexPath, "utf-8");
      const parsed = JSON.parse(raw);
      if (!parsed || !Array.isArray(parsed.agents) || !Array.isArray(parsed.workflows)) return null;
      parsed.agents = parsed.agents.map((entry) => this.normalizeRubricEntry(entry));
      parsed.workflows = parsed.workflows.map((entry) => this.normalizeRubricEntry(entry));
      return parsed;
    } catch {
      return null;
    }
  }
  async readWeeklyArtifact(weekId) {
    try {
      const raw = await readFile2(path2.join(this.weeklyDir, `${weekId}.json`), "utf-8");
      const parsed = JSON.parse(raw);
      if (!parsed || parsed.weekId !== weekId || !Array.isArray(parsed.promotionCandidates)) {
        return null;
      }
      return parsed;
    } catch {
      return null;
    }
  }
  async buildRecallSection(query, opts) {
    const [mistakes, rubrics] = await Promise.all([
      this.readMistakes(),
      this.readRubrics()
    ]);
    const maxPatterns = Math.max(0, Math.floor(opts?.maxPatterns ?? 40));
    const maxRubrics = Math.max(0, Math.floor(opts?.maxRubrics ?? 4));
    const queryTokens = tokenizeRecallQuery(query);
    const activePatterns = (mistakes?.registry ?? []).filter((entry) => entry.status === "active").sort(
      (a, b) => b.recurrenceCount - a.recurrenceCount || b.lastSeenAt.localeCompare(a.lastSeenAt) || a.pattern.localeCompare(b.pattern)
    );
    const topPatterns = activePatterns.slice(0, maxPatterns);
    const allRubrics = [
      ...rubrics?.workflows ?? [],
      ...rubrics?.agents ?? []
    ];
    const scoredRubrics = allRubrics.map((entry) => ({
      entry,
      score: this.scoreRubricForQuery(entry, queryTokens)
    })).sort(
      (a, b) => b.score - a.score || b.entry.observations.length - a.entry.observations.length || a.entry.subject.localeCompare(b.entry.subject)
    );
    const topRubrics = scoredRubrics.filter((item) => item.score > 0 || queryTokens.length === 0).slice(0, maxRubrics).map((item) => item.entry);
    if (topPatterns.length === 0 && topRubrics.length === 0) return null;
    const lines = [
      "## Institutional Learning (Compounded)",
      ""
    ];
    if (topPatterns.length > 0) {
      lines.push("Avoid repeating these patterns:");
      for (const entry of topPatterns) {
        const scope = entry.workflow ?? entry.agent ?? null;
        const metadata = [`recurrence=${entry.recurrenceCount}`];
        if (scope) metadata.push(`scope=${scope}`);
        lines.push(`- ${entry.pattern} _(${metadata.join(", ")})_`);
      }
      lines.push("");
    }
    if (topRubrics.length > 0) {
      lines.push("Active rubrics:");
      for (const rubric of topRubrics) {
        const notes = rubric.observations.slice(0, 2).join("; ");
        lines.push(`- ${rubric.kind} ${rubric.subject}: ${notes}`);
      }
    }
    return lines.join("\n");
  }
  tierMigrationCycleBudget(trigger) {
    return defaultTierMigrationCycleBudget(this.config, trigger);
  }
  async readFeedbackEntriesForWeek(weekId) {
    const out = [];
    try {
      const raw = await readFile2(this.feedbackInboxPath, "utf-8");
      const lines = raw.split("\n");
      for (let idx = 0; idx < lines.length; idx += 1) {
        const line = lines[idx];
        if (!line.trim()) continue;
        try {
          const obj = JSON.parse(line);
          const parsed = SharedFeedbackEntrySchema.safeParse(obj);
          if (!parsed.success) continue;
          const d = new Date(parsed.data.date);
          if (!Number.isFinite(d.getTime())) continue;
          if (isoWeekId(d) !== weekId) continue;
          const sourceLine = idx + 1;
          out.push({
            entry: parsed.data,
            sourceLine,
            sourcePath: this.feedbackInboxPath,
            entryId: `${parsed.data.agent}-${parsed.data.date}-${sourceLine}`.replace(/[^a-zA-Z0-9._:-]/g, "_")
          });
        } catch {
        }
      }
    } catch {
    }
    return out;
  }
  buildActionFailurePatterns(events) {
    const out = [];
    for (const event of events) {
      const failed = event.outcome === "failed" || event.outcome === "skipped";
      if (!failed && event.policyDecision === null) continue;
      const suffix = event.reason && event.reason.trim().length > 0 ? ` - ${event.reason.trim().slice(0, 140)}` : "";
      out.push(
        `memory-action/${event.namespace}: ${event.action} ${event.outcome}${event.policyDecision ? `/${event.policyDecision}` : ""}${suffix}`
      );
    }
    return out;
  }
  async readActionEventsForWeek(weekId) {
    const out = [];
    const rows = await this.storage.readMemoryActionEventRows(Number.MAX_SAFE_INTEGER);
    for (const row of rows) {
      const event = row.event;
      const ts = new Date(event.timestamp);
      if (!Number.isFinite(ts.getTime()) || isoWeekId(ts) !== weekId) continue;
      out.push({
        line: row.line,
        action: event.action,
        outcome: event.outcome,
        policyDecision: event.policyDecision === "deny" || event.policyDecision === "defer" ? event.policyDecision : null,
        namespace: typeof event.namespace === "string" && event.namespace.length > 0 ? event.namespace : "default",
        reason: typeof event.reason === "string" ? event.reason : null
      });
    }
    return out;
  }
  buildActionOutcomeSummary(events) {
    const byAction = /* @__PURE__ */ new Map();
    for (const event of events) {
      const key = event.action;
      const acc = byAction.get(key) ?? {
        counts: { applied: 0, skipped: 0, failed: 0 },
        provenance: /* @__PURE__ */ new Set()
      };
      if (event.outcome === "applied") acc.counts.applied += 1;
      else if (event.outcome === "skipped") acc.counts.skipped += 1;
      else acc.counts.failed += 1;
      acc.provenance.add(`${path2.basename(this.memoryActionEventsPath)}:L${event.line}`);
      byAction.set(key, acc);
    }
    const out = [];
    for (const [action, data] of byAction.entries()) {
      const total = data.counts.applied + data.counts.skipped + data.counts.failed;
      if (total <= 0) continue;
      const weightedScore = Number(((data.counts.applied * 1 - data.counts.skipped * 0.5 - data.counts.failed * 1.5) / total).toFixed(3));
      out.push({
        action,
        counts: data.counts,
        total,
        weightedScore,
        provenance: [...data.provenance].sort().slice(0, 8)
      });
    }
    out.sort((a, b) => b.total - a.total || b.weightedScore - a.weightedScore || a.action.localeCompare(b.action));
    return out;
  }
  derivePromotionCandidates(summary, mistakes, rubrics) {
    const deduped = /* @__PURE__ */ new Map();
    const upsert = (candidate) => {
      const key = `${candidate.category}:${canonicalPromotionContentKey(candidate.content)}`;
      const existing = deduped.get(key);
      if (!existing) {
        deduped.set(key, candidate);
        return;
      }
      const mergedProvenance = [.../* @__PURE__ */ new Set([...existing.provenance, ...candidate.provenance])];
      if (candidate.score > existing.score) {
        deduped.set(key, {
          ...candidate,
          provenance: mergedProvenance
        });
        return;
      }
      existing.provenance = mergedProvenance;
    };
    for (const item of summary) {
      if (item.total < 3) continue;
      if (item.weightedScore < 0.3) continue;
      const content = normalizePromotedGuidanceContent(
        `Prefer ${item.action} when the same workflow recurs; this week's outcomes were applied=${item.counts.applied}, skipped=${item.counts.skipped}, failed=${item.counts.failed}.`
      );
      upsert({
        id: stablePromotionCandidateId("action-outcome", item.action, content),
        sourceType: "action-outcome",
        subject: item.action,
        category: promotionCategoryForContent(content),
        content,
        score: item.weightedScore,
        rationale: "High applied ratio with low failure/skips in weekly outcome telemetry.",
        outcome: item.counts,
        provenance: item.provenance,
        agent: null,
        workflow: "memory-actions"
      });
    }
    for (const entry of mistakes) {
      if (entry.status !== "active") continue;
      if (entry.recurrenceCount < 2) continue;
      const content = normalizePromotedGuidanceContent(lessonContentFromPattern(entry.pattern, entry.agent));
      if (content.length === 0) continue;
      const confidence = entry.confidence ?? 0.75;
      const score = Number(Math.min(0.97, 0.45 + Math.min(entry.recurrenceCount, 6) * 0.08 + confidence * 0.15).toFixed(3));
      upsert({
        id: stablePromotionCandidateId("mistake-pattern", entry.id, content),
        sourceType: "mistake-pattern",
        subject: entry.pattern,
        category: promotionCategoryForContent(content),
        content,
        score,
        rationale: `Recurring lesson still active after ${entry.recurrenceCount} confirmations in the mistake registry.`,
        outcome: null,
        provenance: entry.provenance.length > 0 ? entry.provenance : [`mistakes.json#${entry.id}`],
        agent: entry.agent,
        workflow: entry.workflow
      });
    }
    for (const rubric of [...rubrics.workflows, ...rubrics.agents]) {
      for (const observation of this.getRubricObservationEntries(rubric)) {
        if (this.isSyntheticOutcomeRubricObservation(observation.note)) continue;
        const evidenceCount = observation.provenance.length;
        if (evidenceCount < 2) continue;
        const content = normalizePromotedGuidanceContent(observation.note);
        if (content.length === 0) continue;
        const score = Number(Math.min(0.95, 0.5 + Math.min(evidenceCount, 5) * 0.08).toFixed(3));
        upsert({
          id: stablePromotionCandidateId("rubric", `${rubric.id}:${observation.note}`, content),
          sourceType: "rubric",
          subject: `${rubric.kind}:${rubric.subject}`,
          category: promotionCategoryForContent(content),
          content,
          score,
          rationale: `Rubric guidance repeated across ${evidenceCount} supporting observations.`,
          outcome: null,
          provenance: observation.provenance,
          agent: rubric.kind === "agent" ? rubric.subject : null,
          workflow: rubric.kind === "workflow" ? rubric.subject : null
        });
      }
    }
    return [...deduped.values()].sort((a, b) => b.score - a.score || a.subject.localeCompare(b.subject)).slice(0, 10);
  }
  buildMistakes(entries, actionPatterns = [], weekId, previousRegistry = []) {
    const patterns = [];
    const evidenceByPattern = /* @__PURE__ */ new Map();
    for (const wrapped of entries) {
      const e = wrapped.entry;
      const pattern = e.learning && e.learning.trim().length > 0 ? `${e.agent}: ${e.learning.trim()}` : e.decision === "rejected" ? `${e.agent}: ${e.reason.trim()}`.slice(0, 240) : null;
      if (!pattern) continue;
      const provenance = [`${path2.basename(wrapped.sourcePath)}:L${wrapped.sourceLine}#${wrapped.entryId}`];
      patterns.push({ pattern, provenance });
      const previous = evidenceByPattern.get(pattern) ?? {
        category: "feedback",
        agent: e.agent,
        workflow: e.workflow ?? null,
        tags: /* @__PURE__ */ new Set(),
        severity: e.severity ?? null,
        confidence: normalizeConfidence(e.confidence),
        outcome: e.outcome?.trim() || null,
        timestamps: [],
        evidenceWindow: normalizeEvidenceWindow(e.evidenceWindowStart, e.evidenceWindowEnd)
      };
      for (const tag of normalizeTags(e.tags)) previous.tags.add(tag);
      previous.timestamps.push(e.date);
      if (previous.workflow === null && e.workflow) previous.workflow = e.workflow;
      if (previous.severity === null && e.severity) previous.severity = e.severity;
      if (previous.confidence === null) previous.confidence = normalizeConfidence(e.confidence);
      if (previous.outcome === null && e.outcome) previous.outcome = e.outcome.trim();
      const nextEvidenceWindow = normalizeEvidenceWindow(e.evidenceWindowStart, e.evidenceWindowEnd);
      previous.evidenceWindow = mergeEvidenceWindows(previous.evidenceWindow, nextEvidenceWindow);
      evidenceByPattern.set(pattern, previous);
    }
    for (const pattern of actionPatterns) {
      patterns.push({ pattern, provenance: [`${path2.basename(this.memoryActionEventsPath)}:*`] });
      const previous = evidenceByPattern.get(pattern) ?? {
        category: "action",
        agent: null,
        workflow: "memory-actions",
        tags: /* @__PURE__ */ new Set(),
        severity: "medium",
        confidence: null,
        outcome: null,
        timestamps: [],
        evidenceWindow: { start: null, end: null }
      };
      evidenceByPattern.set(pattern, previous);
    }
    const byPattern = /* @__PURE__ */ new Map();
    for (const item of patterns) {
      const existing = byPattern.get(item.pattern) ?? /* @__PURE__ */ new Set();
      for (const provenance of item.provenance) existing.add(provenance);
      byPattern.set(item.pattern, existing);
    }
    const details = [...byPattern.entries()].map(([pattern, provenance]) => ({ pattern, provenance: [...provenance].sort() })).slice(0, 500);
    const previousById = new Map(previousRegistry.map((entry) => [entry.id, entry]));
    const previousByPattern = new Map(previousRegistry.map((entry) => [entry.pattern, entry]));
    const registry = details.map((detail) => {
      const evidence = evidenceByPattern.get(detail.pattern);
      const id = stableMistakeId(
        evidence?.category ?? "feedback",
        detail.pattern,
        evidence?.agent ?? null,
        evidence?.workflow ?? null
      );
      const previous = previousById.get(id) ?? previousByPattern.get(detail.pattern);
      const timestamps = (evidence?.timestamps ?? []).filter((value) => typeof value === "string" && value.length > 0).sort();
      const firstSeenAt = previous?.firstSeenAt ?? timestamps[0] ?? (/* @__PURE__ */ new Date()).toISOString();
      const lastSeenAt = timestamps[timestamps.length - 1] ?? previous?.lastSeenAt ?? firstSeenAt;
      return {
        id,
        pattern: detail.pattern,
        category: evidence?.category ?? "feedback",
        status: "active",
        agent: evidence?.agent ?? null,
        workflow: evidence?.workflow ?? null,
        tags: evidence ? [...evidence.tags].sort() : [],
        severity: evidence?.severity ?? null,
        confidence: evidence?.confidence ?? null,
        outcome: evidence?.outcome ?? null,
        provenance: detail.provenance,
        firstSeenAt,
        lastSeenAt,
        recurrenceCount: previous?.lastWeekId === weekId ? previous.recurrenceCount : (previous?.recurrenceCount ?? 0) + 1,
        lastWeekId: weekId,
        evidenceWindow: evidence?.evidenceWindow ?? { start: null, end: null },
        retiredAt: null
      };
    });
    const seenIds = new Set(registry.map((entry) => entry.id));
    const seenPatterns = new Set(registry.map((entry) => entry.pattern));
    for (const previous of previousRegistry) {
      if (seenIds.has(previous.id) || seenPatterns.has(previous.pattern)) continue;
      const staleWeeks = weekIdToIndex(weekId) - weekIdToIndex(previous.lastWeekId);
      registry.push({
        ...previous,
        status: staleWeeks >= RETIREMENT_WINDOW_WEEKS ? "retired" : previous.status,
        retiredAt: staleWeeks >= RETIREMENT_WINDOW_WEEKS ? previous.retiredAt ?? (/* @__PURE__ */ new Date()).toISOString() : previous.retiredAt ?? null
      });
    }
    registry.sort(
      (a, b) => Number(b.status === "active") - Number(a.status === "active") || b.recurrenceCount - a.recurrenceCount || b.lastSeenAt.localeCompare(a.lastSeenAt) || a.pattern.localeCompare(b.pattern)
    );
    return {
      version: COMPOUNDING_VERSION,
      updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
      patterns: details.map((d) => d.pattern),
      details,
      registry
    };
  }
  formatWeeklyReport(weekId, entries, patterns, patternDetails, continuity, outcomeSummary, promotionCandidates) {
    const byAgent = /* @__PURE__ */ new Map();
    for (const wrapped of entries) {
      const list = byAgent.get(wrapped.entry.agent) ?? [];
      list.push(wrapped);
      byAgent.set(wrapped.entry.agent, list);
    }
    const lines = [
      `# Weekly Compounding \u2014 ${weekId}`,
      "",
      "This file is generated by Engram's compounding engine (v5.0).",
      "",
      "## Summary",
      `- Feedback entries: ${entries.length}`,
      `- Mistake patterns: ${patterns.length}`,
      "",
      "## By Agent"
    ];
    if (byAgent.size === 0) {
      lines.push("- (none)");
    } else {
      for (const [agent, list] of Array.from(byAgent.entries()).sort((a, b) => a[0].localeCompare(b[0]))) {
        const approved = list.filter((e) => e.entry.decision === "approved").length;
        const awf = list.filter((e) => e.entry.decision === "approved_with_feedback").length;
        const rejected = list.filter((e) => e.entry.decision === "rejected").length;
        lines.push(`### ${agent}`);
        lines.push(`- approved: ${approved}`);
        lines.push(`- approved_with_feedback: ${awf}`);
        lines.push(`- rejected: ${rejected}`);
        const provenance = list.slice(0, 3).map((e) => `${path2.basename(e.sourcePath)}:L${e.sourceLine}#${e.entryId}`);
        if (provenance.length > 0) {
          lines.push(`- provenance: ${provenance.join(", ")}`);
        }
        lines.push("");
      }
    }
    lines.push("## Patterns (Avoid / Prefer)");
    if (patterns.length === 0) {
      lines.push("- (none yet)");
    } else {
      const detailMap = new Map(patternDetails.map((d) => [d.pattern, d.provenance]));
      for (const p of patterns.slice(0, 100)) {
        const provenance = detailMap.get(p) ?? [];
        if (provenance.length > 0) {
          lines.push(`- ${p} _(source: ${provenance.join(", ")})_`);
        } else {
          lines.push(`- ${p}`);
        }
      }
    }
    lines.push("");
    lines.push("## Outcome Weighting");
    if (outcomeSummary.length === 0) {
      lines.push("- (no action outcomes recorded this week)");
    } else {
      for (const item of outcomeSummary.slice(0, 20)) {
        lines.push(
          `- ${item.action}: applied=${item.counts.applied}, skipped=${item.counts.skipped}, failed=${item.counts.failed}, weight=${item.weightedScore} _(source: ${item.provenance.join(", ")})_`
        );
      }
    }
    lines.push("");
    if (this.config.compoundingSemanticEnabled) {
      lines.push("## Promotion Candidates (Advisory)");
      if (promotionCandidates.length === 0) {
        lines.push("- (no advisory promotion candidates this week)");
      } else {
        for (const candidate of promotionCandidates) {
          const outcomeSummaryText = candidate.outcome ? ` outcomes[a=${candidate.outcome.applied}, s=${candidate.outcome.skipped}, f=${candidate.outcome.failed}]` : "";
          lines.push(
            `- [${candidate.sourceType}] ${candidate.subject} -> ${candidate.content} (category=${candidate.category}, score=${candidate.score}, id=${candidate.id}): ${candidate.rationale}${outcomeSummaryText} _(source: ${candidate.provenance.join(", ")})_`
          );
        }
      }
      lines.push("");
      lines.push("_Advisory only: no automatic promotion write is performed by this report. Use `compounding_promote_candidate` or `openclaw engram compounding-promote` to persist one manually._");
      lines.push("");
    }
    if (this.config.continuityAuditEnabled) {
      lines.push("## Continuity Audits");
      if (continuity.weeklyPath) {
        lines.push(`- weekly: ${continuity.weeklyPath}`);
      } else {
        lines.push(`- weekly: (missing for ${weekId})`);
      }
      if (continuity.monthlyPath) {
        lines.push(`- monthly: ${continuity.monthlyPath}`);
      } else {
        lines.push(`- monthly: (missing for ${continuity.monthId})`);
      }
      lines.push("");
    }
    return lines.join("\n");
  }
  buildRubricSnapshot(entries, outcomeSummary) {
    const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
    const byAgent = /* @__PURE__ */ new Map();
    const byWorkflow = /* @__PURE__ */ new Map();
    for (const wrapped of entries) {
      const note = (wrapped.entry.learning && wrapped.entry.learning.trim().length > 0 ? wrapped.entry.learning : wrapped.entry.decision === "rejected" ? wrapped.entry.reason : "").trim();
      if (!note) continue;
      const provenance = `${path2.basename(wrapped.sourcePath)}:L${wrapped.sourceLine}#${wrapped.entryId}`;
      const agentEntry = byAgent.get(wrapped.entry.agent) ?? {
        id: stableRubricId("agent", wrapped.entry.agent),
        kind: "agent",
        subject: wrapped.entry.agent,
        observations: [],
        tags: [],
        provenance: [],
        observationEntries: [],
        updatedAt
      };
      this.addRubricObservation(agentEntry, note, provenance);
      agentEntry.tags = normalizeTags([...agentEntry.tags, ...normalizeTags(wrapped.entry.tags)]);
      byAgent.set(wrapped.entry.agent, agentEntry);
      const workflow = wrapped.entry.workflow?.trim();
      if (!workflow) continue;
      const workflowEntry = byWorkflow.get(workflow) ?? {
        id: stableRubricId("workflow", workflow),
        kind: "workflow",
        subject: workflow,
        observations: [],
        tags: [],
        provenance: [],
        observationEntries: [],
        updatedAt
      };
      this.addRubricObservation(workflowEntry, note, provenance);
      workflowEntry.tags = normalizeTags([...workflowEntry.tags, ...normalizeTags(wrapped.entry.tags)]);
      byWorkflow.set(workflow, workflowEntry);
    }
    for (const item of outcomeSummary) {
      const workflowEntry = byWorkflow.get(item.action) ?? {
        id: stableRubricId("workflow", item.action),
        kind: "workflow",
        subject: item.action,
        observations: [],
        tags: [],
        provenance: [],
        observationEntries: [],
        updatedAt
      };
      this.addRubricObservation(
        workflowEntry,
        `Outcome weight=${item.weightedScore} (applied=${item.counts.applied}, skipped=${item.counts.skipped}, failed=${item.counts.failed})`,
        ...item.provenance
      );
      byWorkflow.set(item.action, workflowEntry);
    }
    return {
      updatedAt,
      agents: [...byAgent.values()].sort((a, b) => a.subject.localeCompare(b.subject)),
      workflows: [...byWorkflow.values()].sort((a, b) => a.subject.localeCompare(b.subject))
    };
  }
  formatRubrics(outcomeSummary, snapshot) {
    const lines = [
      "# Compounding Rubrics",
      "",
      `Generated: ${snapshot.updatedAt}`,
      "",
      "Stable, deterministic rubric snapshot generated from weekly feedback + action outcomes.",
      ""
    ];
    lines.push("## Agent Rubrics");
    if (snapshot.agents.length === 0) {
      lines.push("- (none yet)");
    } else {
      for (const rubric of snapshot.agents) {
        lines.push(`### ${rubric.subject}`);
        const observations = this.getRubricObservationEntries(rubric).slice(0, 8);
        if (observations.length === 0) {
          lines.push("- No rubric deltas this week.");
        } else {
          for (const observation of observations) {
            const provenance = observation.provenance.join(", ");
            lines.push(`- ${observation.note}${provenance ? ` _(source: ${provenance})_` : ""}`);
          }
        }
        lines.push("");
      }
    }
    lines.push("## Workflow Rubrics");
    if (snapshot.workflows.length === 0) {
      lines.push("- (none yet)");
    } else {
      for (const rubric of snapshot.workflows) {
        lines.push(`### ${rubric.subject}`);
        for (const observation of this.getRubricObservationEntries(rubric).slice(0, 8)) {
          const provenance = observation.provenance.join(", ");
          lines.push(`- ${observation.note}${provenance ? ` _(source: ${provenance})_` : ""}`);
        }
        lines.push("");
      }
    }
    lines.push("## Action Outcome Signals");
    if (outcomeSummary.length === 0) {
      lines.push("- (none yet)");
    } else {
      for (const item of outcomeSummary.slice(0, 20)) {
        lines.push(
          `- ${item.action}: weight=${item.weightedScore} (applied=${item.counts.applied}, skipped=${item.counts.skipped}, failed=${item.counts.failed})`
        );
      }
    }
    lines.push("");
    return lines.join("\n");
  }
  async syncRubricArtifacts(snapshot) {
    await this.replaceRubricDirectory(this.rubricsAgentsDir, snapshot.agents);
    await this.replaceRubricDirectory(this.rubricsWorkflowsDir, snapshot.workflows);
  }
  async replaceRubricDirectory(dir, entries) {
    await mkdir2(dir, { recursive: true });
    try {
      const names = await readdir2(dir);
      await Promise.all(
        names.filter((name) => name.endsWith(".md")).map((name) => unlink(path2.join(dir, name)).catch(() => void 0))
      );
    } catch {
    }
    const slugCollisions = /* @__PURE__ */ new Map();
    for (const entry of entries) {
      const slug = stableSlug(entry.subject);
      slugCollisions.set(slug, (slugCollisions.get(slug) ?? 0) + 1);
    }
    await Promise.all(entries.map(async (entry) => {
      const observationEntries = this.getRubricObservationEntries(entry);
      const body = [
        `# ${entry.kind === "agent" ? "Agent" : "Workflow"} Rubric \u2014 ${entry.subject}`,
        "",
        `Updated: ${entry.updatedAt}`,
        "",
        "## Observations",
        ...observationEntries.length > 0 ? observationEntries.map((item) => `- ${item.note}`) : ["- (none yet)"],
        "",
        "## Provenance",
        ...entry.provenance.length > 0 ? entry.provenance.map((item) => `- ${item}`) : ["- (none yet)"],
        ""
      ].join("\n");
      const fileName = rubricArtifactFileName(entry, slugCollisions);
      await writeFile2(path2.join(dir, fileName), body, "utf-8");
    }));
  }
  scoreRubricForQuery(entry, queryTokens) {
    if (queryTokens.length === 0) return entry.observations.length;
    const haystack = [entry.subject, ...entry.observations, ...entry.tags].join(" ").toLowerCase();
    let score = 0;
    for (const token of queryTokens) {
      if (haystack.includes(token)) score += 2;
      if (entry.subject.toLowerCase().includes(token)) score += 2;
    }
    if (score === 0) return 0;
    return score + Math.min(entry.observations.length, 3);
  }
  normalizeRubricEntry(entry) {
    const normalizedEntries = this.getRubricObservationEntries(entry);
    return {
      ...entry,
      observations: normalizedEntries.map((item) => item.note),
      provenance: [...new Set(normalizedEntries.flatMap((item) => item.provenance))],
      observationEntries: normalizedEntries
    };
  }
  getRubricObservationEntries(entry) {
    if (Array.isArray(entry.observationEntries) && entry.observationEntries.length > 0) {
      return entry.observationEntries.map((item) => ({
        note: item.note,
        provenance: [...new Set(item.provenance)].sort()
      }));
    }
    return entry.observations.map((note, index) => ({
      note,
      provenance: entry.provenance[index] ? [entry.provenance[index]] : entry.provenance[0] ? [entry.provenance[0]] : []
    }));
  }
  isSyntheticOutcomeRubricObservation(note) {
    return note.trimStart().startsWith("Outcome weight=");
  }
  addRubricObservation(entry, note, ...provenance) {
    const normalized = this.normalizeRubricEntry(entry);
    const existing = normalized.observationEntries?.find((item) => item.note === note);
    if (existing) {
      existing.provenance = [.../* @__PURE__ */ new Set([...existing.provenance, ...provenance])].sort();
    } else {
      normalized.observationEntries?.push({
        note,
        provenance: [...new Set(provenance)].sort()
      });
    }
    entry.observationEntries = normalized.observationEntries;
    entry.observations = normalized.observationEntries?.map((item) => item.note) ?? [];
    entry.provenance = [...new Set((normalized.observationEntries ?? []).flatMap((item) => item.provenance))];
  }
  async readOptionalIdentityAnchorForAudit() {
    try {
      return await this.storage.readIdentityAnchor();
    } catch {
      return null;
    }
  }
  async readOptionalImprovementLoopsForAudit() {
    try {
      return await this.storage.readIdentityImprovementLoops();
    } catch {
      return null;
    }
  }
  async readContinuityIncidentsForAudit(limit, state) {
    try {
      return await this.storage.readContinuityIncidents(limit, state);
    } catch {
      return [];
    }
  }
  async readOptionalIdentityAuditForReference(period, key) {
    try {
      return await this.storage.readIdentityAudit(period, key);
    } catch {
      return null;
    }
  }
  async readContinuityAuditReferences(weekId) {
    const monthId = monthIdFromIsoWeek(weekId);
    const weeklyPath = path2.join(this.identityAuditWeeklyDir, `${weekId}.md`);
    const monthlyPath = path2.join(this.identityAuditMonthlyDir, `${monthId}.md`);
    const [weeklyAudit, monthlyAudit] = await Promise.all([
      this.readOptionalIdentityAuditForReference("weekly", weekId),
      this.readOptionalIdentityAuditForReference("monthly", monthId)
    ]);
    const weeklyExists = (weeklyAudit ?? "").trim().length > 0;
    const monthlyExists = (monthlyAudit ?? "").trim().length > 0;
    return {
      weekId,
      monthId,
      weeklyPath: weeklyExists ? weeklyPath : null,
      monthlyPath: monthlyExists ? monthlyPath : null
    };
  }
};

export {
  SharedContextManager,
  defaultTierMigrationCycleBudget,
  CompoundingEngine
};
//# sourceMappingURL=chunk-4DXC6HQQ.js.map