@joshuaswarren/openclaw-engram 9.1.19 → 9.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/storage.ts","../src/memory-cache.ts","../src/hygiene.ts","../src/sanitize.ts","../src/types.ts","../src/memory-projection-store.ts","../src/memory-lifecycle-ledger-utils.ts","../src/memory-projection-format.ts","../src/identity-continuity.ts"],"sourcesContent":["import { access, readdir, readFile, stat, writeFile, mkdir, unlink, rename, appendFile } from \"node:fs/promises\";\nimport { appendFileSync, mkdirSync, statSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { log } from \"./logger.js\";\nimport { getCachedEntities, setCachedEntities } from \"./memory-cache.js\";\nimport { rotateMarkdownFileToArchive } from \"./hygiene.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport type {\n AccessTrackingEntry,\n BufferState,\n ConfidenceTier,\n ContinuityIncidentCloseInput,\n ContinuityIncidentOpenInput,\n ContinuityIncidentRecord,\n ContinuityImprovementLoop,\n ContinuityLoopReviewInput,\n ContinuityLoopUpsertInput,\n EntityActivityEntry,\n EntityFile,\n EntityRelationship,\n ImportanceLevel,\n ImportanceScore,\n MemoryCategory,\n MemoryFile,\n MemoryFrontmatter,\n MemoryLink,\n LifecycleState,\n VerificationState,\n PolicyClass,\n MemoryStatus,\n MemoryActionEvent,\n MemoryLifecycleEvent,\n MemoryLifecycleEventType,\n MemoryLifecycleStateSummary,\n MemoryProjectionCurrentState,\n BehaviorSignalEvent,\n MemorySummary,\n MetaState,\n CompressionGuidelineOptimizerState,\n PluginConfig,\n ScoredEntity,\n TopicScore,\n FileHygieneConfig,\n} from \"./types.js\";\nimport { confidenceTier, SPECULATIVE_TTL_DAYS } from \"./types.js\";\nimport {\n type ProjectedMemoryBrowseOptions,\n type ProjectedMemoryBrowsePage,\n readProjectedMemoryState,\n readProjectedMemoryBrowse,\n readProjectedGovernanceRecord,\n readProjectedMemoryTimeline,\n} from \"./memory-projection-store.js\";\nimport {\n inferMemoryStatus,\n isArchivedMemoryPath,\n sortMemoryLifecycleEvents,\n toMemoryPathRel,\n} from \"./memory-lifecycle-ledger-utils.js\";\nimport {\n normalizeProjectionPreview,\n normalizeProjectionTags,\n} from \"./memory-projection-format.js\";\nimport {\n closeContinuityIncidentRecord,\n createContinuityIncidentRecord,\n parseContinuityIncident,\n parseContinuityImprovementLoops,\n reviewContinuityLoopInMarkdown,\n serializeContinuityIncident,\n upsertContinuityLoopInMarkdown,\n} from \"./identity-continuity.js\";\n\nconst ARTIFACT_SEARCH_STOPWORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"but\",\n \"by\",\n \"for\",\n \"from\",\n \"has\",\n \"have\",\n \"i\",\n \"in\",\n \"is\",\n \"it\",\n \"of\",\n \"on\",\n \"or\",\n \"that\",\n \"the\",\n \"this\",\n \"to\",\n \"was\",\n \"were\",\n \"with\",\n]);\n\nexport interface ReextractJobRequest {\n memoryId: string;\n model: string;\n requestedAt: string;\n source: \"cli-migrate\";\n}\n\nexport interface MemoryLifecycleEventWriteOptions {\n at?: Date;\n actor?: string;\n reasonCode?: string;\n ruleVersion?: string;\n relatedMemoryIds?: string[];\n correlationId?: string;\n}\n\nfunction tokenizeArtifactSearchText(input: string): string[] {\n return input\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 2)\n .filter((t) => !ARTIFACT_SEARCH_STOPWORDS.has(t));\n}\n\nfunction serializeFrontmatter(fm: MemoryFrontmatter): string {\n const lines = [\n \"---\",\n `id: ${fm.id}`,\n `category: ${fm.category}`,\n `created: ${fm.created}`,\n `updated: ${fm.updated}`,\n `source: ${fm.source}`,\n `confidence: ${fm.confidence}`,\n `confidenceTier: ${fm.confidenceTier}`,\n `tags: [${fm.tags.map((t) => `\"${t}\"`).join(\", \")}]`,\n ];\n if (fm.entityRef) lines.push(`entityRef: ${fm.entityRef}`);\n if (fm.supersedes) lines.push(`supersedes: ${fm.supersedes}`);\n if (fm.expiresAt) lines.push(`expiresAt: ${fm.expiresAt}`);\n if (fm.lineage && fm.lineage.length > 0) {\n lines.push(`lineage: [${fm.lineage.map((l) => `\"${l}\"`).join(\", \")}]`);\n }\n // Status management\n if (fm.status && fm.status !== \"active\") lines.push(`status: ${fm.status}`);\n if (fm.supersededBy) lines.push(`supersededBy: ${fm.supersededBy}`);\n if (fm.supersededAt) lines.push(`supersededAt: ${fm.supersededAt}`);\n if (fm.archivedAt) lines.push(`archivedAt: ${fm.archivedAt}`);\n // Lifecycle policy fields\n if (fm.lifecycleState) lines.push(`lifecycleState: ${fm.lifecycleState}`);\n if (fm.verificationState) lines.push(`verificationState: ${fm.verificationState}`);\n if (fm.policyClass) lines.push(`policyClass: ${fm.policyClass}`);\n if (fm.lastValidatedAt) lines.push(`lastValidatedAt: ${fm.lastValidatedAt}`);\n if (fm.decayScore !== undefined) lines.push(`decayScore: ${fm.decayScore}`);\n if (fm.heatScore !== undefined) lines.push(`heatScore: ${fm.heatScore}`);\n // Access tracking\n if (fm.accessCount !== undefined && fm.accessCount > 0) {\n lines.push(`accessCount: ${fm.accessCount}`);\n }\n if (fm.lastAccessed) lines.push(`lastAccessed: ${fm.lastAccessed}`);\n // Importance scoring\n if (fm.importance) {\n lines.push(`importanceScore: ${fm.importance.score}`);\n lines.push(`importanceLevel: ${fm.importance.level}`);\n if (fm.importance.reasons.length > 0) {\n lines.push(\n `importanceReasons: [${fm.importance.reasons\n .map((r) => `\"${r.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`)\n .join(\", \")}]`,\n );\n }\n if (fm.importance.keywords.length > 0) {\n lines.push(`importanceKeywords: [${fm.importance.keywords.map((k) => `\"${k}\"`).join(\", \")}]`);\n }\n }\n // Chunking (Phase 2A)\n if (fm.parentId) lines.push(`parentId: ${fm.parentId}`);\n if (fm.chunkIndex !== undefined) lines.push(`chunkIndex: ${fm.chunkIndex}`);\n if (fm.chunkTotal !== undefined) lines.push(`chunkTotal: ${fm.chunkTotal}`);\n // Memory Linking (Phase 3A)\n if (fm.links && fm.links.length > 0) {\n lines.push(\"links:\");\n for (const link of fm.links) {\n lines.push(` - targetId: ${link.targetId}`);\n lines.push(` linkType: ${link.linkType}`);\n lines.push(` strength: ${link.strength}`);\n if (link.reason) lines.push(` reason: ${JSON.stringify(link.reason)}`);\n }\n }\n if (fm.intentGoal) lines.push(`intentGoal: ${fm.intentGoal}`);\n if (fm.intentActionType) lines.push(`intentActionType: ${fm.intentActionType}`);\n if (fm.intentEntityTypes && fm.intentEntityTypes.length > 0) {\n lines.push(`intentEntityTypes: [${fm.intentEntityTypes.map((t) => `\"${t}\"`).join(\", \")}]`);\n }\n if (fm.artifactType) lines.push(`artifactType: ${fm.artifactType}`);\n if (fm.sourceMemoryId) lines.push(`sourceMemoryId: ${fm.sourceMemoryId}`);\n if (fm.sourceTurnId) lines.push(`sourceTurnId: ${fm.sourceTurnId}`);\n // v8.0 Phase 2B: HiMem episode/note classification\n if (fm.memoryKind) lines.push(`memoryKind: ${fm.memoryKind}`);\n // Structured attributes (stored as JSON on a single line)\n if (fm.structuredAttributes && Object.keys(fm.structuredAttributes).length > 0) {\n lines.push(`structuredAttributes: ${JSON.stringify(fm.structuredAttributes)}`);\n }\n lines.push(\"---\");\n return lines.join(\"\\n\");\n}\n\nfunction parseStructuredAttributes(raw: string | undefined): Record<string, string> | undefined {\n if (!raw || !raw.trim()) return undefined;\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n const result: Record<string, string> = {};\n for (const [k, v] of Object.entries(parsed)) {\n if (typeof k === \"string\" && typeof v === \"string\") {\n result[k] = v;\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n }\n } catch {\n // Not valid JSON — ignore\n }\n return undefined;\n}\n\nfunction parseLinkReasonValue(rawValue: string): string {\n const legacyValue = rawValue.replace(/\\\\\"/g, '\"');\n const looksLikeLegacyPath =\n !rawValue.includes(\"\\\\\\\\\") &&\n (/[A-Za-z]:\\\\[A-Za-z0-9._ -]+(?:\\\\[A-Za-z0-9._ -]+)*/.test(rawValue) ||\n /\\\\[A-Za-z0-9._ -]+\\\\[A-Za-z0-9._ -]+/.test(rawValue));\n\n if (looksLikeLegacyPath) {\n return legacyValue;\n }\n\n try {\n return JSON.parse(`\"${rawValue}\"`) as string;\n } catch {\n return legacyValue;\n }\n}\n\nfunction parseFrontmatter(\n raw: string,\n): { frontmatter: MemoryFrontmatter; content: string } | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (!match) return null;\n\n const fmBlock = match[1];\n const content = match[2].trim();\n const fm: Record<string, string> = {};\n\n for (const line of fmBlock.split(\"\\n\")) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx === -1) continue;\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n fm[key] = value;\n }\n\n let tags: string[] = [];\n const tagsStr = fm.tags ?? \"\";\n const tagMatch = tagsStr.match(/\\[(.*)]/);\n if (tagMatch) {\n tags = tagMatch[1]\n .split(\",\")\n .map((t) => t.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n let intentEntityTypes: string[] | undefined;\n const intentEntityTypesStr = fm.intentEntityTypes ?? \"\";\n const intentEntityTypesMatch = intentEntityTypesStr.match(/\\[(.*)]/);\n if (intentEntityTypesMatch) {\n intentEntityTypes = intentEntityTypesMatch[1]\n .split(\",\")\n .map((t) => t.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n const conf = parseFloat(fm.confidence ?? \"0.8\");\n\n // Parse lineage array if present\n let lineage: string[] | undefined;\n const lineageStr = fm.lineage ?? \"\";\n const lineageMatch = lineageStr.match(/\\[(.*)]/);\n if (lineageMatch) {\n lineage = lineageMatch[1]\n .split(\",\")\n .map((l) => l.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n // Parse accessCount\n const accessCount = fm.accessCount ? parseInt(fm.accessCount, 10) : undefined;\n const decayScore = fm.decayScore !== undefined ? parseFloat(fm.decayScore) : undefined;\n const heatScore = fm.heatScore !== undefined ? parseFloat(fm.heatScore) : undefined;\n\n // Parse importance\n let importance: ImportanceScore | undefined;\n if (fm.importanceScore) {\n const score = parseFloat(fm.importanceScore);\n const level = (fm.importanceLevel as ImportanceLevel) || \"normal\";\n\n // Parse importance reasons array\n let reasons: string[] = [];\n const reasonsStr = fm.importanceReasons ?? \"\";\n if (reasonsStr.trim().startsWith(\"[\") && reasonsStr.trim().endsWith(\"]\")) {\n const reasonMatches = reasonsStr.matchAll(/\"((?:\\\\.|[^\"\\\\])*)\"/g);\n for (const match of reasonMatches) {\n const reason = parseLinkReasonValue(match[1]);\n if (reason.length > 0) {\n reasons.push(reason);\n }\n }\n }\n\n // Parse importance keywords array\n let keywords: string[] = [];\n const keywordsStr = fm.importanceKeywords ?? \"\";\n const keywordsMatch = keywordsStr.match(/\\[(.*)]/);\n if (keywordsMatch) {\n keywords = keywordsMatch[1]\n .split(\",\")\n .map((k) => k.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n importance = { score, level, reasons, keywords };\n }\n\n const result: { frontmatter: MemoryFrontmatter; content: string } = {\n frontmatter: {\n id: fm.id ?? \"\",\n category: (fm.category ?? \"fact\") as MemoryCategory,\n created: fm.created ?? new Date().toISOString(),\n updated: fm.updated ?? new Date().toISOString(),\n source: fm.source ?? \"unknown\",\n confidence: conf,\n confidenceTier: (fm.confidenceTier as ConfidenceTier) || confidenceTier(conf),\n tags,\n entityRef: fm.entityRef || undefined,\n supersedes: fm.supersedes || undefined,\n expiresAt: fm.expiresAt || undefined,\n lineage: lineage && lineage.length > 0 ? lineage : undefined,\n // Status management\n status: (fm.status as MemoryStatus) || \"active\",\n supersededBy: fm.supersededBy || undefined,\n supersededAt: fm.supersededAt || undefined,\n archivedAt: fm.archivedAt || undefined,\n lifecycleState: (fm.lifecycleState as LifecycleState) || undefined,\n verificationState: (fm.verificationState as VerificationState) || undefined,\n policyClass: (fm.policyClass as PolicyClass) || undefined,\n lastValidatedAt: fm.lastValidatedAt || undefined,\n decayScore: Number.isFinite(decayScore) ? decayScore : undefined,\n heatScore: Number.isFinite(heatScore) ? heatScore : undefined,\n // Access tracking\n accessCount: accessCount && accessCount > 0 ? accessCount : undefined,\n lastAccessed: fm.lastAccessed || undefined,\n // Importance scoring\n importance,\n // Chunking\n parentId: fm.parentId || undefined,\n chunkIndex: fm.chunkIndex ? parseInt(fm.chunkIndex, 10) : undefined,\n chunkTotal: fm.chunkTotal ? parseInt(fm.chunkTotal, 10) : undefined,\n // Links are parsed separately below\n intentGoal: fm.intentGoal || undefined,\n intentActionType: fm.intentActionType || undefined,\n intentEntityTypes: intentEntityTypes && intentEntityTypes.length > 0 ? intentEntityTypes : undefined,\n artifactType: (fm.artifactType as MemoryFrontmatter[\"artifactType\"]) || undefined,\n sourceMemoryId: fm.sourceMemoryId || undefined,\n sourceTurnId: fm.sourceTurnId || undefined,\n // v8.0 Phase 2B: HiMem episode/note classification\n memoryKind: (fm.memoryKind as MemoryFrontmatter[\"memoryKind\"]) || undefined,\n // Structured attributes (JSON on a single line)\n structuredAttributes: parseStructuredAttributes(fm.structuredAttributes),\n },\n content,\n };\n\n // Parse links (YAML array format)\n // Note: Simple parsing - for full YAML we'd need a library.\n if (fmBlock.includes(\"links:\")) {\n const links: MemoryLink[] = [];\n const linkMatches = fmBlock.matchAll(\n /- targetId: (\\S+)\\s+linkType: (\\S+)\\s+strength: ([\\d.]+)(?:\\s+reason: \"((?:\\\\.|[^\"\\\\])*)\")?/g,\n );\n for (const match of linkMatches) {\n links.push({\n targetId: match[1],\n linkType: match[2] as MemoryLink[\"linkType\"],\n strength: parseFloat(match[3]),\n reason: match[4] ? parseLinkReasonValue(match[4]) : undefined,\n });\n }\n if (links.length > 0) {\n result.frontmatter.links = links;\n }\n }\n\n return result;\n}\n\nfunction normalizeFrontmatterForPath(frontmatter: MemoryFrontmatter, pathRel: string): MemoryFrontmatter {\n if (isArchivedMemoryPath(pathRel) && (!frontmatter.status || frontmatter.status === \"active\")) {\n return {\n ...frontmatter,\n status: \"archived\",\n };\n }\n\n return frontmatter;\n}\n\nfunction inferCurrentStateStatus(\n frontmatter: MemoryFrontmatter,\n pathRel: string,\n fallbackStatus: MemoryStatus,\n): MemoryStatus {\n return inferMemoryStatus(frontmatter, pathRel, fallbackStatus);\n}\n\n/**\n * Entity alias table loaded from the user's local config.\n * Populated by StorageManager.loadAliases() at startup.\n * Falls back to built-in structural aliases (e.g. \"open-claw\" → \"openclaw\").\n */\nlet userAliases: Record<string, string> = {};\n\n/** Built-in aliases for common structural normalizations (no personal data) */\nconst BUILTIN_ALIASES: Record<string, string> = {\n openclaw: \"openclaw\",\n \"open-claw\": \"openclaw\",\n};\n\n/**\n * Normalize an entity name to a canonical form.\n * Strips non-alphanumeric chars, collapses hyphens, removes type prefix duplication.\n * e.g. \"My Project\" → \"my-project\"\n *\n * Checks user-defined aliases (from config/aliases.json) first, then built-in aliases.\n */\nexport function normalizeEntityName(raw: string, type: string): string {\n // Strip type prefix if present (e.g. name=\"person-jane-doe\", type=\"person\")\n const rawStr = typeof raw === \"string\" ? raw : \"\";\n const typeStr = typeof type === \"string\" && type.trim().length > 0 ? type : \"entity\";\n\n let name = rawStr.toLowerCase().trim();\n const typePrefix = `${typeStr.toLowerCase()}-`;\n if (name.startsWith(typePrefix)) {\n name = name.slice(typePrefix.length);\n }\n\n // Replace non-alphanumeric with hyphens, collapse multiples, trim edges\n let normalized = name\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n // Check user aliases first, then built-in\n if (userAliases[normalized]) {\n normalized = userAliases[normalized];\n } else if (BUILTIN_ALIASES[normalized]) {\n normalized = BUILTIN_ALIASES[normalized];\n }\n\n return `${typeStr.toLowerCase()}-${normalized}`;\n}\n\n/**\n * Simple Levenshtein distance between two strings.\n */\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (m === 0) return n;\n if (n === 0) return m;\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\n/** Strip hyphens from a string for loose comparison */\nfunction dehyphenate(s: string): string {\n return s.replace(/-/g, \"\");\n}\n\n/**\n * Content-hash dedup index for facts.\n * Normalizes content (lowercase, strip punctuation, collapse whitespace),\n * computes SHA-256, and stores hashes in a line-delimited file.\n * Prevents writing semantically identical facts.\n */\nexport class ContentHashIndex {\n private hashes: Set<string> = new Set();\n private dirty = false;\n private readonly filePath: string;\n\n constructor(stateDir: string) {\n this.filePath = path.join(stateDir, \"fact-hashes.txt\");\n }\n\n /** Load existing hashes from disk. Safe to call multiple times. */\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.filePath, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.length > 0) {\n this.hashes.add(trimmed);\n }\n }\n log.debug(`content-hash index: loaded ${this.hashes.size} hashes`);\n } catch {\n log.debug(\"content-hash index: no existing index — starting fresh\");\n }\n }\n\n /** Check if content already exists in the index. */\n has(content: string): boolean {\n return this.hashes.has(ContentHashIndex.computeHash(content));\n }\n\n /** Add content hash to the index. */\n add(content: string): void {\n const hash = ContentHashIndex.computeHash(content);\n if (!this.hashes.has(hash)) {\n this.hashes.add(hash);\n this.dirty = true;\n }\n }\n\n get size(): number {\n return this.hashes.size;\n }\n\n /** Persist index to disk if changed. */\n async save(): Promise<void> {\n if (!this.dirty) return;\n await mkdir(path.dirname(this.filePath), { recursive: true });\n await writeFile(this.filePath, [...this.hashes].join(\"\\n\") + \"\\n\", \"utf-8\");\n this.dirty = false;\n log.debug(`content-hash index: saved ${this.hashes.size} hashes`);\n }\n\n /** Remove a hash from the index (used when archiving/deleting). */\n remove(content: string): void {\n const hash = ContentHashIndex.computeHash(content);\n if (this.hashes.delete(hash)) {\n this.dirty = true;\n }\n }\n\n /** Normalize content and compute SHA-256 hash. */\n static normalizeContent(content: string): string {\n return content\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n }\n\n /** Normalize content and compute SHA-256 hash. */\n static computeHash(content: string): string {\n const normalized = ContentHashIndex.normalizeContent(content);\n return createHash(\"sha256\").update(normalized).digest(\"hex\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Entity file parsing / serialization (Knowledge Graph v7.0)\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an entity markdown file into a structured EntityFile.\n * Backward compatible: old files without new sections get empty arrays.\n */\nexport function parseEntityFile(content: string): EntityFile {\n const lines = content.split(\"\\n\");\n\n // Header\n let name = \"\";\n let type = \"other\";\n let updated = \"\";\n let summary: string | undefined;\n const facts: string[] = [];\n const relationships: EntityRelationship[] = [];\n const activity: EntityActivityEntry[] = [];\n const aliases: string[] = [];\n\n // Parse name from first heading\n const headingLine = lines.find((l) => l.startsWith(\"# \"));\n if (headingLine) name = headingLine.slice(2).trim();\n\n // Parse type\n const typeLine = lines.find((l) => l.startsWith(\"**Type:**\"));\n if (typeLine) type = typeLine.replace(\"**Type:**\", \"\").trim();\n\n // Parse updated\n const updatedLine = lines.find((l) => l.startsWith(\"**Updated:**\"));\n if (updatedLine) updated = updatedLine.replace(\"**Updated:**\", \"\").trim();\n\n // Detect which section we're in\n let section = \"\";\n for (const line of lines) {\n if (line.startsWith(\"## \")) {\n section = line.slice(3).trim().toLowerCase();\n continue;\n }\n if (!line.startsWith(\"- \")) continue;\n\n const bullet = line.slice(2).trim();\n if (!bullet) continue;\n\n switch (section) {\n case \"facts\":\n facts.push(bullet);\n break;\n case \"summary\":\n // Summary is typically a single line after the heading, not a bullet\n break;\n case \"connected to\": {\n // Format: [[target-entity]] — relationship label\n const relMatch = bullet.match(/^\\[\\[([^\\]]+)\\]\\]\\s*[—–-]\\s*(.+)$/);\n if (relMatch) {\n relationships.push({ target: relMatch[1].trim(), label: relMatch[2].trim() });\n }\n break;\n }\n case \"activity\": {\n // Format: YYYY-MM-DD: note\n const actMatch = bullet.match(/^(\\d{4}-\\d{2}-\\d{2}):\\s*(.+)$/);\n if (actMatch) {\n activity.push({ date: actMatch[1], note: actMatch[2].trim() });\n }\n break;\n }\n case \"aliases\":\n aliases.push(bullet);\n break;\n }\n }\n\n // Parse summary: text between ## Summary heading and next ## heading (not bulleted)\n const summaryIdx = lines.findIndex((l) => l.startsWith(\"## Summary\"));\n if (summaryIdx !== -1) {\n const summaryLines: string[] = [];\n for (let i = summaryIdx + 1; i < lines.length; i++) {\n if (lines[i].startsWith(\"## \")) break;\n const trimmed = lines[i].trim();\n if (trimmed) summaryLines.push(trimmed);\n }\n if (summaryLines.length > 0) summary = summaryLines.join(\" \");\n }\n\n return { name, type, updated, facts, summary, relationships, activity, aliases };\n}\n\n/**\n * Serialize an EntityFile back to markdown.\n * Only emits sections that have content (except Facts which is always emitted).\n */\nexport function serializeEntityFile(entity: EntityFile): string {\n const lines: string[] = [\n `# ${entity.name}`,\n \"\",\n `**Type:** ${entity.type}`,\n `**Updated:** ${entity.updated || new Date().toISOString()}`,\n \"\",\n ];\n\n // Summary (optional)\n if (entity.summary) {\n lines.push(\"## Summary\", \"\", entity.summary, \"\");\n }\n\n // Facts (always emitted)\n lines.push(\"## Facts\", \"\");\n for (const f of entity.facts) {\n lines.push(`- ${f}`);\n }\n lines.push(\"\");\n\n // Connected to (optional)\n if (entity.relationships.length > 0) {\n lines.push(\"## Connected to\", \"\");\n for (const rel of entity.relationships) {\n lines.push(`- [[${rel.target}]] — ${rel.label}`);\n }\n lines.push(\"\");\n }\n\n // Activity (optional)\n if (entity.activity.length > 0) {\n lines.push(\"## Activity\", \"\");\n for (const act of entity.activity) {\n lines.push(`- ${act.date}: ${act.note}`);\n }\n lines.push(\"\");\n }\n\n // Aliases (optional)\n if (entity.aliases.length > 0) {\n lines.push(\"## Aliases\", \"\");\n for (const alias of entity.aliases) {\n lines.push(`- ${alias}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nexport class StorageManager {\n private knowledgeIndexCache: { result: string; builtAt: number } | null = null;\n private static readonly KNOWLEDGE_INDEX_CACHE_TTL_MS = 600_000; // 10 minutes (entity mutations invalidate)\n private artifactIndexCache: { memories: MemoryFile[]; loadedAtMs: number; writeVersion: number } | null = null;\n private static readonly ARTIFACT_INDEX_CACHE_TTL_MS = 60_000; // 1 minute\n private static readonly artifactWriteVersionByDir = new Map<string, number>();\n private static readonly memoryStatusVersionByDir = new Map<string, number>();\n\n // Module-level cache for readAllMemories() keyed by base directory.\n // Shared across all StorageManager instances to avoid duplicate I/O when\n // multiple concurrent callers (e.g. verifiedRecall + verifiedRules) read the\n // same directory simultaneously. In-flight deduplication prevents multiple\n // concurrent reads of the same directory.\n //\n // Stale-while-revalidate: once the cache has a value, subsequent reads after\n // TTL expiry return the stale cached data immediately and kick off a background\n // refresh. This eliminates the 13-60 s cold-scan penalty that would otherwise\n // block recall requests every 5 minutes on large memory collections (80k+ files).\n private static readonly allMemoriesInFlight = new Map<string, Promise<MemoryFile[]>>();\n\n // Cache for readQuestions() — avoids serially re-reading tens of thousands of\n // question files on every recall. 60-second TTL is intentionally short so that\n // newly written questions surface quickly.\n private static readonly QUESTIONS_CACHE_TTL_MS = 60_000; // 1 minute\n private static readonly questionsCache = new Map<\n string,\n {\n questions: Array<{\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n }>;\n loadedAt: number;\n }\n >();\n private factHashIndex: ContentHashIndex | null = null;\n private factHashIndexLoadPromise: Promise<ContentHashIndex> | null = null;\n private factHashIndexAuthoritative: boolean | null = null;\n private factHashIndexAuthoritativePromise: Promise<void> | null = null;\n\n constructor(private readonly baseDir: string) {}\n\n /** The root directory of this storage instance. */\n get dir(): string {\n return this.baseDir;\n }\n\n private identityFilePath(workspaceDir: string, namespace?: string): string {\n const rawNamespace = typeof namespace === \"string\" ? namespace.trim() : \"\";\n if (!rawNamespace) return path.join(workspaceDir, \"IDENTITY.md\");\n const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n return path.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);\n }\n\n private versionFilePath(kind: \"memory-status\" | \"artifact-write\"): string {\n const fileName =\n kind === \"memory-status\" ? \".memory-status-version.log\" : \".artifact-write-version.log\";\n return path.join(this.stateDir, fileName);\n }\n\n private bumpSharedVersion(\n kind: \"memory-status\" | \"artifact-write\",\n fallbackMap: Map<string, number>,\n ): number {\n const filePath = this.versionFilePath(kind);\n try {\n mkdirSync(this.stateDir, { recursive: true });\n appendFileSync(filePath, \"x\");\n const next = statSync(filePath).size;\n fallbackMap.set(this.baseDir, next);\n return next;\n } catch {\n const next = (fallbackMap.get(this.baseDir) ?? 0) + 1;\n fallbackMap.set(this.baseDir, next);\n return next;\n }\n }\n\n private readSharedVersion(\n kind: \"memory-status\" | \"artifact-write\",\n fallbackMap: Map<string, number>,\n ): number {\n const filePath = this.versionFilePath(kind);\n try {\n return statSync(filePath).size;\n } catch {\n return fallbackMap.get(this.baseDir) ?? 0;\n }\n }\n\n private bumpMemoryStatusVersion(): void {\n this.bumpSharedVersion(\"memory-status\", StorageManager.memoryStatusVersionByDir);\n }\n\n getMemoryStatusVersion(): number {\n return this.readSharedVersion(\"memory-status\", StorageManager.memoryStatusVersionByDir);\n }\n\n private bumpArtifactWriteVersion(): number {\n return this.bumpSharedVersion(\"artifact-write\", StorageManager.artifactWriteVersionByDir);\n }\n\n private getArtifactWriteVersion(): number {\n return this.readSharedVersion(\"artifact-write\", StorageManager.artifactWriteVersionByDir);\n }\n\n private get factsDir(): string {\n return path.join(this.baseDir, \"facts\");\n }\n private get correctionsDir(): string {\n return path.join(this.baseDir, \"corrections\");\n }\n private get entitiesDir(): string {\n return path.join(this.baseDir, \"entities\");\n }\n private get stateDir(): string {\n return path.join(this.baseDir, \"state\");\n }\n private get factHashIndexReadyPath(): string {\n return path.join(this.stateDir, \"fact-hashes.ready\");\n }\n\n private async getFactHashIndex(): Promise<ContentHashIndex> {\n if (this.factHashIndex) {\n return this.factHashIndex;\n }\n if (!this.factHashIndexLoadPromise) {\n const index = new ContentHashIndex(this.stateDir);\n this.factHashIndexLoadPromise = index\n .load()\n .then(() => {\n this.factHashIndex = index;\n return index;\n })\n .catch((err) => {\n this.factHashIndexLoadPromise = null;\n throw err;\n });\n }\n return this.factHashIndexLoadPromise;\n }\n\n private async ensureFactHashIndexAuthoritative(): Promise<void> {\n if (this.factHashIndexAuthoritative === true) {\n return;\n }\n if (this.factHashIndexAuthoritativePromise) {\n await this.factHashIndexAuthoritativePromise;\n return;\n }\n\n this.factHashIndexAuthoritativePromise = (async () => {\n try {\n await access(this.factHashIndexReadyPath);\n this.factHashIndexAuthoritative = true;\n return;\n } catch {\n // Fall through and backfill from the live fact corpus once.\n }\n\n const factHashIndex = await this.getFactHashIndex();\n const existing = await this.readAllMemories();\n for (const memory of existing) {\n if (memory.frontmatter.category !== \"fact\") continue;\n if (inferMemoryStatus(memory.frontmatter, memory.path) !== \"active\") continue;\n factHashIndex.add(memory.content);\n }\n await factHashIndex.save();\n await mkdir(path.dirname(this.factHashIndexReadyPath), { recursive: true });\n await writeFile(this.factHashIndexReadyPath, \"v1\\n\", \"utf-8\");\n this.factHashIndexAuthoritative = true;\n })().finally(() => {\n this.factHashIndexAuthoritativePromise = null;\n });\n await this.factHashIndexAuthoritativePromise;\n }\n private get questionsDir(): string {\n return path.join(this.baseDir, \"questions\");\n }\n private get artifactsDir(): string {\n return path.join(this.baseDir, \"artifacts\");\n }\n private get identityDir(): string {\n return path.join(this.baseDir, \"identity\");\n }\n private get identityAnchorPath(): string {\n return path.join(this.identityDir, \"identity-anchor.md\");\n }\n private get identityIncidentsDir(): string {\n return path.join(this.identityDir, \"incidents\");\n }\n private get identityAuditsWeeklyDir(): string {\n return path.join(this.identityDir, \"audits\", \"weekly\");\n }\n private get identityAuditsMonthlyDir(): string {\n return path.join(this.identityDir, \"audits\", \"monthly\");\n }\n private get identityImprovementLoopsPath(): string {\n return path.join(this.identityDir, \"improvement-loops.md\");\n }\n private get identityReflectionsPath(): string {\n return path.join(this.identityDir, \"reflections.md\");\n }\n private get profilePath(): string {\n return path.join(this.baseDir, \"profile.md\");\n }\n private get memoryActionsPath(): string {\n return path.join(this.stateDir, \"memory-actions.jsonl\");\n }\n private get memoryLifecycleLedgerPath(): string {\n return path.join(this.stateDir, \"memory-lifecycle-ledger.jsonl\");\n }\n private get compressionGuidelinesPath(): string {\n return path.join(this.stateDir, \"compression-guidelines.md\");\n }\n private get compressionGuidelineDraftPath(): string {\n return path.join(this.stateDir, \"compression-guidelines.draft.md\");\n }\n private get compressionGuidelineStatePath(): string {\n return path.join(this.stateDir, \"compression-guideline-state.json\");\n }\n private get compressionGuidelineDraftStatePath(): string {\n return path.join(this.stateDir, \"compression-guideline-draft-state.json\");\n }\n private get behaviorSignalsPath(): string {\n return path.join(this.stateDir, \"behavior-signals.jsonl\");\n }\n\n /**\n * Load user-defined entity aliases from config/aliases.json in the memory store.\n * File format: { \"variant\": \"canonical\", \"variant2\": \"canonical\", ... }\n * Call this once at startup (e.g. from orchestrator.initialize()).\n */\n async loadAliases(): Promise<void> {\n const aliasPath = path.join(this.baseDir, \"config\", \"aliases.json\");\n try {\n const raw = await readFile(aliasPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null) {\n userAliases = parsed as Record<string, string>;\n log.debug(`loaded ${Object.keys(userAliases).length} entity aliases from ${aliasPath}`);\n }\n } catch {\n // No aliases file — that's fine, use built-in only\n log.debug(\"no config/aliases.json found — using built-in aliases only\");\n }\n }\n\n async ensureDirectories(): Promise<void> {\n const today = new Date().toISOString().slice(0, 10);\n await mkdir(path.join(this.factsDir, today), { recursive: true });\n await mkdir(this.correctionsDir, { recursive: true });\n await mkdir(this.entitiesDir, { recursive: true });\n await mkdir(this.stateDir, { recursive: true });\n await mkdir(this.questionsDir, { recursive: true });\n await mkdir(this.artifactsDir, { recursive: true });\n await mkdir(this.identityDir, { recursive: true });\n await mkdir(this.identityIncidentsDir, { recursive: true });\n await mkdir(this.identityAuditsWeeklyDir, { recursive: true });\n await mkdir(this.identityAuditsMonthlyDir, { recursive: true });\n await mkdir(path.join(this.baseDir, \"config\"), { recursive: true });\n }\n\n async writeMemory(\n category: MemoryCategory,\n content: string,\n options: {\n actor?: string;\n confidence?: number;\n tags?: string[];\n entityRef?: string;\n source?: string;\n supersedes?: string;\n lineage?: string[];\n importance?: ImportanceScore;\n links?: MemoryLink[];\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n artifactType?: MemoryFrontmatter[\"artifactType\"];\n sourceMemoryId?: string;\n sourceTurnId?: string;\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n expiresAt?: string;\n structuredAttributes?: Record<string, string>;\n } = {},\n ): Promise<string> {\n await this.ensureDirectories();\n const now = new Date();\n const today = now.toISOString().slice(0, 10);\n const id = `${category}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n const conf = options.confidence ?? 0.8;\n const tier = confidenceTier(conf);\n\n // Auto-set TTL for speculative memories\n let expiresAt: string | undefined;\n if (typeof options.expiresAt === \"string\" && options.expiresAt.length > 0) {\n expiresAt = options.expiresAt;\n } else if (tier === \"speculative\") {\n const expiry = new Date(now.getTime() + SPECULATIVE_TTL_DAYS * 24 * 60 * 60 * 1000);\n expiresAt = expiry.toISOString();\n }\n\n const fm: MemoryFrontmatter = {\n id,\n category,\n created: now.toISOString(),\n updated: now.toISOString(),\n source: options.source ?? \"extraction\",\n confidence: conf,\n confidenceTier: tier,\n tags: options.tags ?? [],\n entityRef: options.entityRef,\n supersedes: options.supersedes,\n expiresAt,\n lineage: options.lineage,\n importance: options.importance,\n links: options.links,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n artifactType: options.artifactType,\n sourceMemoryId: options.sourceMemoryId,\n sourceTurnId: options.sourceTurnId,\n memoryKind: options.memoryKind,\n structuredAttributes: options.structuredAttributes,\n };\n\n // Append structured attributes as searchable suffix so QMD indexes them\n let enrichedContent = content;\n if (options.structuredAttributes && Object.keys(options.structuredAttributes).length > 0) {\n const attrLines = Object.entries(options.structuredAttributes)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n enrichedContent = `${content}\\n[Attributes: ${attrLines}]`;\n }\n\n const sanitized = sanitizeMemoryContent(enrichedContent);\n if (!sanitized.clean) {\n log.warn(`memory content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n const fileContent = `${serializeFrontmatter(fm)}\\n\\n${sanitized.text}\\n`;\n\n let filePath: string;\n if (category === \"correction\") {\n filePath = path.join(this.correctionsDir, `${id}.md`);\n } else {\n filePath = path.join(this.factsDir, today, `${id}.md`);\n }\n\n await writeFile(filePath, fileContent, \"utf-8\");\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.writeMemory\", {\n memoryId: id,\n eventType: \"created\",\n timestamp: fm.created,\n actor: options.actor ?? \"storage.writeMemory\",\n after: this.summarizeLifecycleState(fm, filePath),\n relatedMemoryIds: [\n ...(options.supersedes ? [options.supersedes] : []),\n ...((options.lineage ?? []).filter(Boolean)),\n ],\n });\n if (category === \"fact\") {\n try {\n const factHashIndex = await this.getFactHashIndex();\n factHashIndex.add(sanitized.text);\n await factHashIndex.save();\n } catch (err) {\n log.warn(`storage.writeMemory completed but failed to update fact hash index: ${err}`);\n }\n }\n log.debug(`wrote memory ${id} to ${filePath}`);\n return id;\n }\n\n async hasFactContentHash(content: string): Promise<boolean> {\n await this.ensureFactHashIndexAuthoritative();\n const factHashIndex = await this.getFactHashIndex();\n const sanitized = sanitizeMemoryContent(content);\n return factHashIndex.has(sanitized.text);\n }\n\n async isFactContentHashAuthoritative(): Promise<boolean> {\n await this.ensureFactHashIndexAuthoritative();\n return true;\n }\n\n async writeArtifact(\n quote: string,\n options: {\n actor?: string;\n tags?: string[];\n confidence?: number;\n artifactType?: MemoryFrontmatter[\"artifactType\"];\n sourceMemoryId?: string;\n sourceTurnId?: string;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n } = {},\n ): Promise<string> {\n await this.ensureDirectories();\n const now = new Date();\n const day = now.toISOString().slice(0, 10);\n const dir = path.join(this.artifactsDir, day);\n await mkdir(dir, { recursive: true });\n\n const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n const fm: MemoryFrontmatter = {\n id,\n category: \"fact\",\n created: now.toISOString(),\n updated: now.toISOString(),\n source: \"artifact\",\n confidence: options.confidence ?? 0.9,\n confidenceTier: confidenceTier(options.confidence ?? 0.9),\n tags: options.tags ?? [],\n artifactType: options.artifactType ?? \"fact\",\n sourceMemoryId: options.sourceMemoryId,\n sourceTurnId: options.sourceTurnId,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n };\n\n const sanitized = sanitizeMemoryContent(quote);\n if (!sanitized.clean) {\n log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(\", \")}`);\n return \"\";\n }\n const filePath = path.join(dir, `${id}.md`);\n await writeFile(filePath, `${serializeFrontmatter(fm)}\\n\\n${sanitized.text}\\n`, \"utf-8\");\n const actor =\n typeof options.actor === \"string\" && options.actor.length > 0\n ? options.actor\n : \"storage.writeArtifact\";\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.writeArtifact\", {\n memoryId: id,\n eventType: \"created\",\n timestamp: fm.created,\n actor,\n after: this.summarizeLifecycleState(fm, filePath),\n relatedMemoryIds: options.sourceMemoryId ? [options.sourceMemoryId] : [],\n });\n this.bumpArtifactWriteVersion();\n // Always invalidate on write. This avoids stale mixed snapshots when multiple\n // processes share the same memoryDir and write concurrently.\n this.artifactIndexCache = null;\n return id;\n }\n\n private async readAllArtifactsCached(): Promise<MemoryFile[]> {\n if (\n this.artifactIndexCache &&\n Date.now() - this.artifactIndexCache.loadedAtMs <= StorageManager.ARTIFACT_INDEX_CACHE_TTL_MS &&\n this.artifactIndexCache.writeVersion === this.getArtifactWriteVersion()\n ) {\n return this.artifactIndexCache.memories;\n }\n\n const scanArtifacts = async (): Promise<MemoryFile[]> => {\n const artifacts: MemoryFile[] = [];\n const readDir = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await readDir(fullPath);\n continue;\n }\n if (!entry.name.endsWith(\".md\")) continue;\n const memory = await this.readMemoryByPath(fullPath);\n if (!memory) continue;\n artifacts.push(memory);\n }\n } catch {\n // Directory doesn't exist yet\n }\n };\n await readDir(this.artifactsDir);\n return artifacts;\n };\n\n const MAX_REBUILD_RETRIES = 2;\n let latestArtifacts: MemoryFile[] = [];\n for (let attempt = 0; attempt <= MAX_REBUILD_RETRIES; attempt += 1) {\n const versionBefore = this.getArtifactWriteVersion();\n const artifacts = await scanArtifacts();\n const versionAfter = this.getArtifactWriteVersion();\n latestArtifacts = artifacts;\n if (versionAfter === versionBefore) {\n this.artifactIndexCache = { memories: artifacts, loadedAtMs: Date.now(), writeVersion: versionAfter };\n return artifacts;\n }\n }\n\n // Highly concurrent writer churn; keep cache invalid so next read retries a clean rebuild.\n // Return best-effort latest scan instead of an empty set to avoid dropping recall entirely.\n this.artifactIndexCache = null;\n return latestArtifacts;\n }\n\n async searchArtifacts(query: string, maxResults: number): Promise<MemoryFile[]> {\n const tokens = tokenizeArtifactSearchText(query);\n if (tokens.length === 0) return [];\n\n const artifacts = await this.readAllArtifactsCached();\n const hits: Array<{ score: number; memory: MemoryFile }> = [];\n for (const memory of artifacts) {\n const indexedTokens = new Set(\n tokenizeArtifactSearchText(`${memory.content} ${(memory.frontmatter.tags ?? []).join(\" \")}`),\n );\n const score = tokens.reduce((sum, t) => sum + (indexedTokens.has(t) ? 1 : 0), 0);\n if (score > 0) {\n hits.push({ score, memory });\n }\n }\n hits.sort((a, b) => b.score - a.score);\n return hits.slice(0, maxResults).map((h) => h.memory);\n }\n\n async writeEntity(\n name: string,\n type: string,\n facts: string[],\n ): Promise<string> {\n await this.ensureDirectories();\n if (typeof name !== \"string\" || !name.trim() || typeof type !== \"string\" || !type.trim()) {\n log.warn(\"writeEntity: invalid entity payload, skipping\", {\n nameType: typeof name,\n typeType: typeof type,\n });\n return \"\";\n }\n const safeFacts = Array.isArray(facts) ? facts.filter((f) => typeof f === \"string\") : [];\n let normalized = normalizeEntityName(name, type);\n\n // Check for fuzzy match against existing entities before creating a new file\n const match = await this.findMatchingEntity(name, type);\n if (match && match !== normalized) {\n log.debug(`fuzzy match: \"${normalized}\" → existing \"${match}\"`);\n normalized = match;\n }\n\n const filePath = path.join(this.entitiesDir, `${normalized}.md`);\n\n // Parse existing file to preserve relationships/activity/aliases/summary\n let entity: EntityFile = {\n name, type, updated: new Date().toISOString(),\n facts: [], summary: undefined, relationships: [], activity: [], aliases: [],\n };\n try {\n const existing = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(existing);\n } catch {\n // File doesn't exist yet\n }\n\n // Merge facts (dedup)\n entity.facts = [...new Set([...entity.facts, ...safeFacts])];\n entity.name = name;\n entity.type = type;\n entity.updated = new Date().toISOString();\n\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n this.bumpMemoryStatusVersion(); // invalidate entity cache\n log.debug(`wrote entity ${normalized}`);\n return normalized;\n }\n\n async readProfile(): Promise<string> {\n try {\n return await readFile(this.profilePath, \"utf-8\");\n } catch {\n return \"\";\n }\n }\n\n async writeProfile(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.profilePath, content, \"utf-8\");\n log.debug(\"updated profile.md\");\n }\n\n /**\n * Normalize a string for fuzzy profile dedup: lowercase, strip punctuation, collapse whitespace.\n */\n private static normalizeForDedup(s: string): string {\n if (typeof s !== \"string\") return \"\";\n return s\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n }\n\n /**\n * Check if a new bullet is a fuzzy duplicate of any existing bullet.\n * Returns true if the new bullet should be skipped.\n */\n private static isFuzzyDuplicate(newNorm: string, existingNorms: string[]): boolean {\n for (const existing of existingNorms) {\n // Exact normalized match\n if (newNorm === existing) return true;\n\n // Containment check: shorter must be >60% length of longer\n const shorter = newNorm.length <= existing.length ? newNorm : existing;\n const longer = newNorm.length > existing.length ? newNorm : existing;\n if (shorter.length > 20 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {\n return true;\n }\n }\n return false;\n }\n\n async appendToProfile(updates: string[]): Promise<void> {\n // Filter out non-string entries that the LLM may return\n updates = updates.filter((u) => typeof u === \"string\" && u.trim().length > 0);\n if (updates.length === 0) return;\n const existing = await this.readProfile();\n\n const lines = existing ? existing.split(\"\\n\") : [];\n const existingBulletRaw = lines\n .filter((l) => l.startsWith(\"- \"))\n .map((l) => l.slice(2).trim());\n const existingNorms = existingBulletRaw.map(StorageManager.normalizeForDedup);\n\n const newBullets = updates.filter((u) => {\n const norm = StorageManager.normalizeForDedup(u);\n return !StorageManager.isFuzzyDuplicate(norm, existingNorms);\n });\n if (newBullets.length === 0) return;\n\n if (!existing) {\n const content = [\n \"# Behavioral Profile\",\n \"\",\n `*Last updated: ${new Date().toISOString()}*`,\n \"\",\n ...newBullets.map((b) => `- ${b}`),\n \"\",\n ].join(\"\\n\");\n await this.writeProfile(content);\n } else {\n const updatedTimestamp = existing.replace(\n /\\*Last updated:.*\\*/,\n `*Last updated: ${new Date().toISOString()}*`,\n );\n const withBullets = updatedTimestamp.trimEnd() + \"\\n\" + newBullets.map((b) => `- ${b}`).join(\"\\n\") + \"\\n\";\n await this.writeProfile(withBullets);\n }\n }\n\n /** Check if profile.md exceeds the max line cap and needs LLM consolidation */\n async profileNeedsConsolidation(triggerLines?: number): Promise<boolean> {\n const profile = await this.readProfile();\n if (!profile) return false;\n const lineCount = profile.split(\"\\n\").length;\n const threshold = typeof triggerLines === \"number\"\n ? Math.max(0, Math.floor(triggerLines))\n : StorageManager.PROFILE_MAX_LINES;\n return lineCount > threshold;\n }\n\n async readAllMemories(): Promise<MemoryFile[]> {\n // Deduplicate concurrent reads for the same directory so multiple\n // callers in the same recall share one disk scan.\n const inFlight = StorageManager.allMemoriesInFlight.get(this.baseDir);\n if (inFlight) return inFlight;\n\n const readPromise = this._readAllMemoriesFromDisk();\n StorageManager.allMemoriesInFlight.set(this.baseDir, readPromise);\n try {\n return await readPromise;\n } finally {\n // Only delete if we still own the slot — invalidateAllMemoriesCache()\n // may have already cleared it and a new read may have claimed it.\n if (StorageManager.allMemoriesInFlight.get(this.baseDir) === readPromise) {\n StorageManager.allMemoriesInFlight.delete(this.baseDir);\n }\n }\n }\n\n /** Invalidate the readAllMemories() cache after writes that add/remove memories. */\n /** Public cache invalidation for callers that need authoritative disk reads\n * (e.g. projection verify/rebuild). */\n invalidateAllMemoriesCacheForDir(): void {\n this.invalidateAllMemoriesCache();\n }\n\n /** Clear ALL static caches. Use in tests that write files directly\n * (bypassing StorageManager.writeMemory) to avoid stale reads. */\n static clearAllStaticCaches(): void {\n StorageManager.allMemoriesInFlight.clear();\n StorageManager.questionsCache.clear();\n }\n\n /** Cancel any in-flight concurrent read so the next readAllMemories()\n * starts a fresh disk scan and sees the just-written data. */\n private invalidateAllMemoriesCache(): void {\n StorageManager.allMemoriesInFlight.delete(this.baseDir);\n }\n\n private async _readAllMemoriesFromDisk(): Promise<MemoryFile[]> {\n // Collect all .md file paths first (directory traversal is sequential but fast),\n // then read files in parallel batches to avoid O(N) sequential I/O.\n // With 80k+ memory files, sequential reads can take 60+ seconds under load.\n const filePaths: string[] = [];\n\n const collectPaths = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n const subdirs: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n subdirs.push(fullPath);\n } else if (entry.name.endsWith(\".md\")) {\n filePaths.push(fullPath);\n }\n }\n // Recurse into subdirectories sequentially (directory tree is shallow)\n for (const subdir of subdirs) {\n await collectPaths(subdir);\n }\n } catch {\n // Directory doesn't exist yet\n }\n };\n\n await collectPaths(this.factsDir);\n await collectPaths(this.correctionsDir);\n\n if (filePaths.length === 0) return [];\n\n // Read all files in parallel batches of 50 to balance throughput and I/O pressure.\n const BATCH_SIZE = 50;\n const memories: MemoryFile[] = [];\n for (let i = 0; i < filePaths.length; i += BATCH_SIZE) {\n const batch = filePaths.slice(i, i + BATCH_SIZE);\n const results = await Promise.all(\n batch.map(async (fullPath) => {\n try {\n const raw = await readFile(fullPath, \"utf-8\");\n const parsed = parseFrontmatter(raw);\n if (!parsed) return null;\n return {\n path: fullPath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, fullPath),\n ),\n content: parsed.content,\n } satisfies MemoryFile;\n } catch {\n return null;\n }\n }),\n );\n for (const m of results) {\n if (m !== null) memories.push(m);\n }\n }\n return memories;\n }\n\n /**\n * Read archived memory markdown files under archive/.\n * Used by long-term recall fallback when hot recall has no hits.\n */\n async readArchivedMemories(): Promise<MemoryFile[]> {\n const memories: MemoryFile[] = [];\n const root = this.archiveDir;\n\n const readDir = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await readDir(fullPath);\n } else if (entry.name.endsWith(\".md\")) {\n try {\n const raw = await readFile(fullPath, \"utf-8\");\n const parsed = parseFrontmatter(raw);\n if (parsed) {\n memories.push({\n path: fullPath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, fullPath),\n ),\n content: parsed.content,\n });\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n } catch {\n // Directory doesn't exist yet\n }\n };\n\n await readDir(root);\n return memories;\n }\n\n /** Read a single memory file by its absolute path. Returns null if unreadable. */\n async readMemoryByPath(filePath: string): Promise<MemoryFile | null> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = parseFrontmatter(raw);\n if (parsed) {\n return {\n path: filePath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, filePath),\n ),\n content: parsed.content,\n };\n }\n\n // Entity files use a `# Name` + `**Type:** ...` markdown format rather than\n // YAML frontmatter. Build a synthetic MemoryFile so entity files returned by\n // the direct retrieval agent participate in boostSearchResults and last-recall\n // tracking rather than being silently dropped.\n const normalizedPath = filePath.split(path.sep).join(\"/\");\n if (normalizedPath.includes(\"/entities/\") && filePath.endsWith(\".md\")) {\n const entity = parseEntityFile(raw);\n if (!entity.name) return null;\n const nameWithoutExt = path.basename(filePath, \".md\");\n // Fall back to file mtime rather than new Date() so that entities without\n // an explicit Updated: timestamp are not treated as freshly created on every\n // read. Using new Date() would inflate boostSearchResults recency scores for\n // every entity that lacks a timestamp.\n // Use epoch as the last-resort fallback so that entities without a\n // parseable timestamp don't appear as \"freshly created\" and inflate scores.\n const fileMtime = entity.updated\n || await stat(filePath).then((s) => s.mtime.toISOString()).catch(() => new Date(0).toISOString());\n return {\n path: filePath,\n frontmatter: {\n id: nameWithoutExt,\n category: \"entity\",\n created: fileMtime,\n updated: fileMtime,\n source: \"entity_extraction\",\n confidence: 0.9,\n confidenceTier: confidenceTier(0.9),\n tags: entity.type ? [entity.type] : [],\n },\n content: raw,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n private resolveTierRootDir(tier: \"hot\" | \"cold\"): string {\n return tier === \"cold\" ? path.join(this.baseDir, \"cold\") : this.baseDir;\n }\n\n private resolveMemoryDateDir(memory: MemoryFile): string {\n const preferred = memory.frontmatter.created || memory.frontmatter.updated;\n const dateToken = (preferred ?? \"\").slice(0, 10);\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(dateToken)\n ? dateToken\n : new Date().toISOString().slice(0, 10);\n }\n\n private isArtifactMemory(memory: MemoryFile): boolean {\n if (memory.frontmatter.source === \"artifact\") return true;\n if (memory.frontmatter.artifactType !== undefined) return true;\n return /[\\\\/]artifacts[\\\\/]/.test(memory.path);\n }\n\n buildTierMemoryPath(memory: MemoryFile, tier: \"hot\" | \"cold\"): string {\n const root = this.resolveTierRootDir(tier);\n if (this.isArtifactMemory(memory)) {\n return path.join(root, \"artifacts\", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);\n }\n if (memory.frontmatter.category === \"correction\") {\n return path.join(root, \"corrections\", `${memory.frontmatter.id}.md`);\n }\n return path.join(root, \"facts\", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);\n }\n\n private async writeMemoryFileAtomic(targetPath: string, memory: MemoryFile): Promise<void> {\n const fileContent = `${serializeFrontmatter(memory.frontmatter)}\\n\\n${memory.content}\\n`;\n await mkdir(path.dirname(targetPath), { recursive: true });\n const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;\n try {\n await writeFile(tempPath, fileContent, \"utf-8\");\n await rename(tempPath, targetPath);\n this.invalidateAllMemoriesCache();\n } catch (err) {\n try {\n await unlink(tempPath);\n } catch {\n // best-effort cleanup\n }\n throw err;\n }\n }\n\n async moveMemoryToPath(memory: MemoryFile, targetPath: string): Promise<void> {\n await this.writeMemoryFileAtomic(targetPath, memory);\n const sourcePath = path.resolve(memory.path);\n const destPath = path.resolve(targetPath);\n if (sourcePath !== destPath) {\n try {\n await unlink(memory.path);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (!message.includes(\"ENOENT\")) {\n throw err;\n }\n }\n // Re-invalidate after the unlink — writeMemoryFileAtomic already\n // invalidated, but a concurrent readAllMemories() may have re-populated\n // the cache between the write and the unlink.\n this.invalidateAllMemoriesCache();\n }\n }\n\n async migrateMemoryToTier(\n memory: MemoryFile,\n targetTier: \"hot\" | \"cold\",\n ): Promise<{ changed: boolean; targetPath: string }> {\n const targetPath = this.buildTierMemoryPath(memory, targetTier);\n const sourcePath = path.resolve(memory.path);\n const destPath = path.resolve(targetPath);\n if (sourcePath === destPath) {\n return { changed: false, targetPath };\n }\n\n const existing = await this.readMemoryByPath(targetPath);\n if (existing?.frontmatter.id === memory.frontmatter.id) {\n try {\n await unlink(memory.path);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (!message.includes(\"ENOENT\")) {\n throw err;\n }\n }\n this.bumpMemoryStatusVersion();\n return { changed: false, targetPath };\n }\n\n await this.moveMemoryToPath(memory, targetPath);\n this.invalidateAllMemoriesCache();\n this.bumpMemoryStatusVersion();\n return { changed: true, targetPath };\n }\n\n private get archiveDir(): string {\n return path.join(this.baseDir, \"archive\");\n }\n\n /**\n * Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.\n * Updates frontmatter with archived status before moving.\n * Returns the new file path on success, null on failure.\n */\n async archiveMemory(\n memory: MemoryFile,\n lifecycle?: MemoryLifecycleEventWriteOptions,\n ): Promise<string | null> {\n try {\n const now = lifecycle?.at ?? new Date();\n const today = now.toISOString().slice(0, 10);\n const destDir = path.join(this.archiveDir, today);\n await mkdir(destDir, { recursive: true });\n\n // Update frontmatter to reflect archived status\n const updatedFm: MemoryFrontmatter = {\n ...memory.frontmatter,\n status: \"archived\",\n archivedAt: now.toISOString(),\n updated: now.toISOString(),\n };\n\n const fileContent = `${serializeFrontmatter(updatedFm)}\\n\\n${memory.content}\\n`;\n const destPath = path.join(destDir, path.basename(memory.path));\n\n // Write to archive location first, then remove original\n await writeFile(destPath, fileContent, \"utf-8\");\n await unlink(memory.path);\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\n \"storage.archiveMemory\",\n {\n memoryId: memory.frontmatter.id,\n eventType: \"archived\",\n timestamp: updatedFm.archivedAt ?? updatedFm.updated,\n actor: lifecycle?.actor ?? \"storage.archiveMemory\",\n reasonCode: lifecycle?.reasonCode,\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updatedFm, destPath),\n relatedMemoryIds: lifecycle?.relatedMemoryIds,\n correlationId: lifecycle?.correlationId,\n },\n lifecycle?.ruleVersion,\n );\n this.bumpMemoryStatusVersion();\n\n log.debug(`archived memory ${memory.frontmatter.id} → ${destPath}`);\n return destPath;\n } catch (err) {\n log.warn(`failed to archive memory ${memory.frontmatter.id}: ${err}`);\n return null;\n }\n }\n\n async readEntities(): Promise<string[]> {\n try {\n const entries = await readdir(this.entitiesDir);\n return entries.filter((e) => e.endsWith(\".md\")).map((e) => e.replace(\".md\", \"\"));\n } catch {\n return [];\n }\n }\n\n async readEntity(name: string): Promise<string> {\n try {\n return await readFile(path.join(this.entitiesDir, `${name}.md`), \"utf-8\");\n } catch {\n return \"\";\n }\n }\n\n /** Return sorted list of entity filenames (without .md extension) */\n async listEntityNames(): Promise<string[]> {\n try {\n const entries = await readdir(this.entitiesDir);\n return entries\n .filter((e) => e.endsWith(\".md\"))\n .map((e) => e.replace(\".md\", \"\"))\n .sort();\n } catch {\n return [];\n }\n }\n\n /**\n * Find an existing entity that fuzzy-matches the proposed name.\n * Returns the existing entity filename (without .md) or null if no match.\n *\n * Matching priority:\n * 1. Exact normalized match (handled by normalizeEntityName already)\n * 2. Dehyphenated match: \"jane-doe\" vs \"janedoe\"\n * 3. Substring containment: \"handle-janedoe\" contains \"janedoe\"\n * 4. Levenshtein ≤ 2 on dehyphenated names\n */\n async findMatchingEntity(proposedName: string, type: string): Promise<string | null> {\n const existing = await this.listEntityNames();\n if (existing.length === 0) return null;\n\n const typePrefix = `${type.toLowerCase()}-`;\n // Extract the name part from the proposed normalized name\n const proposedFull = normalizeEntityName(proposedName, type);\n const proposedNamePart = proposedFull.startsWith(typePrefix)\n ? proposedFull.slice(typePrefix.length)\n : proposedFull;\n const proposedDehyph = dehyphenate(proposedNamePart);\n\n // Only compare against entities of the same type\n const sameType = existing.filter((e) => e.startsWith(typePrefix));\n\n for (const entity of sameType) {\n const entityNamePart = entity.slice(typePrefix.length);\n const entityDehyph = dehyphenate(entityNamePart);\n\n // Already the exact normalized form\n if (entity === proposedFull) return entity;\n\n // Dehyphenated exact match\n if (entityDehyph === proposedDehyph) return entity;\n\n // Substring containment (shorter must be >60% length of longer)\n const shorter = proposedDehyph.length <= entityDehyph.length ? proposedDehyph : entityDehyph;\n const longer = proposedDehyph.length > entityDehyph.length ? proposedDehyph : entityDehyph;\n if (shorter.length > 3 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {\n return entity;\n }\n\n // Levenshtein distance ≤ 2 (only for names of reasonable length)\n if (proposedDehyph.length >= 4 && entityDehyph.length >= 4) {\n const dist = levenshtein(proposedDehyph, entityDehyph);\n if (dist <= 2) return entity;\n }\n }\n\n return null;\n }\n\n async invalidateMemory(id: string): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === id);\n if (!memory) return false;\n\n try {\n await unlink(memory.path);\n this.invalidateAllMemoriesCache();\n this.bumpMemoryStatusVersion();\n log.debug(`invalidated memory ${id}`);\n return true;\n } catch {\n return false;\n }\n }\n\n async updateMemory(\n id: string,\n newContent: string,\n options?: { supersedes?: string; lineage?: string[]; actor?: string },\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === id);\n if (!memory) return false;\n\n const mergedLineage = [\n ...(memory.frontmatter.lineage ?? []),\n ...(options?.lineage ?? []),\n ].filter((v, i, a) => a.indexOf(v) === i); // dedupe\n\n const updated: MemoryFrontmatter = {\n ...memory.frontmatter,\n updated: new Date().toISOString(),\n supersedes: options?.supersedes ?? memory.frontmatter.supersedes,\n lineage: mergedLineage.length > 0 ? mergedLineage : undefined,\n };\n const sanitized = sanitizeMemoryContent(newContent);\n if (!sanitized.clean) {\n log.warn(`updated memory content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n const fileContent = `${serializeFrontmatter(updated)}\\n\\n${sanitized.text}\\n`;\n await writeFile(memory.path, fileContent, \"utf-8\");\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.updateMemory\", {\n memoryId: id,\n eventType: \"updated\",\n timestamp: updated.updated,\n actor: options?.actor ?? \"storage.updateMemory\",\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updated, memory.path),\n relatedMemoryIds: [\n ...(updated.supersedes ? [updated.supersedes] : []),\n ...((updated.lineage ?? []).filter(Boolean)),\n ],\n });\n log.debug(`updated memory ${id}`);\n return true;\n }\n\n /**\n * Update frontmatter fields without changing memory content.\n * Returns false when the memory is not found.\n */\n async writeMemoryFrontmatter(\n memory: MemoryFile,\n patch: Partial<MemoryFrontmatter>,\n lifecycle?: MemoryLifecycleEventWriteOptions,\n ): Promise<boolean> {\n const beforeStatus = memory.frontmatter.status ?? \"active\";\n const updated: MemoryFrontmatter = {\n ...memory.frontmatter,\n ...patch,\n };\n const afterStatus = updated.status ?? \"active\";\n\n const fileContent = `${serializeFrontmatter(updated)}\\n\\n${memory.content}\\n`;\n await writeFile(memory.path, fileContent, \"utf-8\");\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\n \"storage.writeMemoryFrontmatter\",\n {\n memoryId: updated.id,\n eventType: this.frontmatterPatchEventType(memory.frontmatter, updated),\n timestamp: updated.updated ?? new Date().toISOString(),\n actor: lifecycle?.actor ?? \"storage.writeMemoryFrontmatter\",\n reasonCode: lifecycle?.reasonCode,\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updated, memory.path),\n relatedMemoryIds: [\n ...(lifecycle?.relatedMemoryIds ?? []),\n ...(updated.supersededBy ? [updated.supersededBy] : []),\n ...(updated.supersedes ? [updated.supersedes] : []),\n ],\n correlationId: lifecycle?.correlationId,\n },\n lifecycle?.ruleVersion,\n );\n if (beforeStatus !== afterStatus) {\n this.bumpMemoryStatusVersion();\n }\n return true;\n }\n\n /**\n * Update frontmatter by memory ID.\n * Prefer writeMemoryFrontmatter(memory, patch) in batch loops to avoid full-corpus rescans.\n */\n async updateMemoryFrontmatter(\n id: string,\n patch: Partial<MemoryFrontmatter>,\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === id);\n if (!memory) return false;\n return this.writeMemoryFrontmatter(memory, patch);\n }\n\n /** Remove memories past their TTL expiresAt date */\n async cleanExpiredTTL(): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n const now = Date.now();\n const deleted: MemoryFile[] = [];\n\n for (const m of memories) {\n if (!m.frontmatter.expiresAt) continue;\n const expiresAt = new Date(m.frontmatter.expiresAt).getTime();\n if (expiresAt < now) {\n try {\n await unlink(m.path);\n deleted.push(m);\n log.debug(`cleaned expired memory ${m.frontmatter.id} (TTL expired)`);\n } catch {\n // Ignore\n }\n }\n }\n\n if (deleted.length > 0) {\n this.invalidateAllMemoriesCache();\n this.bumpMemoryStatusVersion();\n }\n\n return deleted;\n }\n\n async loadBuffer(): Promise<BufferState> {\n const bufferPath = path.join(this.stateDir, \"buffer.json\");\n try {\n const raw = await readFile(bufferPath, \"utf-8\");\n return JSON.parse(raw) as BufferState;\n } catch {\n return { turns: [], lastExtractionAt: null, extractionCount: 0 };\n }\n }\n\n async saveBuffer(state: BufferState): Promise<void> {\n await this.ensureDirectories();\n const bufferPath = path.join(this.stateDir, \"buffer.json\");\n await writeFile(bufferPath, JSON.stringify(state, null, 2), \"utf-8\");\n }\n\n async loadMeta(): Promise<MetaState> {\n const metaPath = path.join(this.stateDir, \"meta.json\");\n try {\n const raw = await readFile(metaPath, \"utf-8\");\n return JSON.parse(raw) as MetaState;\n } catch {\n return {\n extractionCount: 0,\n lastExtractionAt: null,\n lastConsolidationAt: null,\n totalMemories: 0,\n totalEntities: 0,\n };\n }\n }\n\n async saveMeta(state: MetaState): Promise<void> {\n await this.ensureDirectories();\n const metaPath = path.join(this.stateDir, \"meta.json\");\n await writeFile(metaPath, JSON.stringify(state, null, 2), \"utf-8\");\n }\n\n async appendMemoryActionEvents(events: MemoryActionEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n const nowIso = new Date().toISOString();\n const payload = events.map((event) => {\n const normalized: MemoryActionEvent = {\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n };\n return `${JSON.stringify(normalized)}\\n`;\n }).join(\"\");\n\n await appendFile(this.memoryActionsPath, payload, \"utf-8\");\n return events.length;\n }\n\n async appendMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n const nowIso = new Date().toISOString();\n const payload = events.map((event) => {\n const normalized: MemoryLifecycleEvent = {\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n };\n return `${JSON.stringify(normalized)}\\n`;\n }).join(\"\");\n\n await appendFile(this.memoryLifecycleLedgerPath, payload, \"utf-8\");\n return events.length;\n }\n\n async appendBehaviorSignals(events: BehaviorSignalEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n let existingKeys = new Set<string>();\n try {\n const raw = await readFile(this.behaviorSignalsPath, \"utf-8\");\n const lines = raw.split(\"\\n\");\n for (const line of lines) {\n const row = line.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<BehaviorSignalEvent>;\n if (typeof parsed.memoryId === \"string\" && typeof parsed.signalHash === \"string\") {\n existingKeys.add(`${parsed.memoryId}:${parsed.signalHash}`);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n } catch {\n existingKeys = new Set<string>();\n }\n\n const nowIso = new Date().toISOString();\n const deduped: BehaviorSignalEvent[] = [];\n for (const event of events) {\n const key = `${event.memoryId}:${event.signalHash}`;\n if (existingKeys.has(key)) continue;\n existingKeys.add(key);\n deduped.push({\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n });\n }\n\n if (deduped.length === 0) return 0;\n const payload = deduped.map((event) => `${JSON.stringify(event)}\\n`).join(\"\");\n await appendFile(this.behaviorSignalsPath, payload, \"utf-8\");\n return deduped.length;\n }\n\n async appendReextractJobs(events: ReextractJobRequest[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n const filePath = path.join(this.stateDir, \"reextract-jobs.jsonl\");\n const lines = events.map((event) => JSON.stringify(event)).join(\"\\n\") + \"\\n\";\n try {\n await appendFile(filePath, lines, \"utf-8\");\n return events.length;\n } catch {\n return 0;\n }\n }\n\n async readReextractJobs(limit: number = 200): Promise<ReextractJobRequest[]> {\n const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1000, Math.floor(limit))) : 200;\n const filePath = path.join(this.stateDir, \"reextract-jobs.jsonl\");\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const lines = raw.split(\"\\n\").filter((line) => line.trim().length > 0);\n const parsed: ReextractJobRequest[] = [];\n for (const line of lines) {\n try {\n const record = JSON.parse(line) as Partial<ReextractJobRequest>;\n if (\n typeof record.memoryId !== \"string\" ||\n record.memoryId.length === 0 ||\n typeof record.model !== \"string\" ||\n record.model.length === 0 ||\n typeof record.requestedAt !== \"string\" ||\n record.requestedAt.length === 0 ||\n record.source !== \"cli-migrate\"\n ) {\n continue;\n }\n parsed.push({\n memoryId: record.memoryId,\n model: record.model,\n requestedAt: record.requestedAt,\n source: \"cli-migrate\",\n });\n } catch {\n continue;\n }\n }\n return parsed.slice(-safeLimit);\n } catch {\n return [];\n }\n }\n\n async readBehaviorSignals(limit: number = 200): Promise<BehaviorSignalEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n try {\n const raw = await readFile(this.behaviorSignalsPath, \"utf-8\");\n const out: BehaviorSignalEvent[] = [];\n const lines = raw.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0 && out.length < cappedLimit; i -= 1) {\n const row = lines[i]?.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<BehaviorSignalEvent>;\n if (\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.namespace === \"string\" &&\n typeof parsed.memoryId === \"string\" &&\n typeof parsed.category === \"string\" &&\n typeof parsed.signalType === \"string\" &&\n typeof parsed.direction === \"string\" &&\n typeof parsed.confidence === \"number\" &&\n typeof parsed.signalHash === \"string\" &&\n typeof parsed.source === \"string\"\n ) {\n out.push(parsed as BehaviorSignalEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return out.reverse();\n } catch {\n return [];\n }\n }\n\n async readMemoryActionEvents(limit: number = 200): Promise<MemoryActionEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n try {\n const raw = await readFile(this.memoryActionsPath, \"utf-8\");\n const out: MemoryActionEvent[] = [];\n const lines = raw.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0 && out.length < cappedLimit; i -= 1) {\n const line = lines[i]?.trim();\n if (!line) continue;\n try {\n const parsed = JSON.parse(line) as Partial<MemoryActionEvent>;\n if (\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.action === \"string\" &&\n typeof parsed.outcome === \"string\"\n ) {\n out.push(parsed as MemoryActionEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return out.reverse();\n } catch {\n return [];\n }\n }\n\n async readAllMemoryLifecycleEvents(): Promise<MemoryLifecycleEvent[]> {\n try {\n const raw = await readFile(this.memoryLifecycleLedgerPath, \"utf-8\");\n const out: MemoryLifecycleEvent[] = [];\n const lines = raw.split(\"\\n\");\n for (const line of lines) {\n const row = line.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<MemoryLifecycleEvent>;\n if (\n typeof parsed.eventId === \"string\" &&\n typeof parsed.memoryId === \"string\" &&\n typeof parsed.eventType === \"string\" &&\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.actor === \"string\" &&\n typeof parsed.ruleVersion === \"string\"\n ) {\n out.push(parsed as MemoryLifecycleEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return sortMemoryLifecycleEvents(out);\n } catch {\n return [];\n }\n }\n\n async readMemoryLifecycleEvents(limit: number = 200): Promise<MemoryLifecycleEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n const events = await this.readAllMemoryLifecycleEvents();\n return events.slice(-cappedLimit);\n }\n\n async writeCompressionGuidelines(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelinesPath, content, \"utf-8\");\n }\n\n async readCompressionGuidelines(): Promise<string | null> {\n try {\n return await readFile(this.compressionGuidelinesPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeCompressionGuidelineDraft(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelineDraftPath, content, \"utf-8\");\n }\n\n async readCompressionGuidelineDraft(): Promise<string | null> {\n try {\n return await readFile(this.compressionGuidelineDraftPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeCompressionGuidelineOptimizerState(\n state: CompressionGuidelineOptimizerState,\n ): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelineStatePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n }\n\n async writeCompressionGuidelineDraftState(\n state: CompressionGuidelineOptimizerState,\n ): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelineDraftStatePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n }\n\n async readCompressionGuidelineOptimizerState(): Promise<CompressionGuidelineOptimizerState | null> {\n return this.readCompressionGuidelineStateFile(this.compressionGuidelineStatePath);\n }\n\n async readCompressionGuidelineDraftState(): Promise<CompressionGuidelineOptimizerState | null> {\n return this.readCompressionGuidelineStateFile(this.compressionGuidelineDraftStatePath);\n }\n\n async activateCompressionGuidelineDraft(options?: {\n expectedContentHash?: string;\n expectedGuidelineVersion?: number;\n }): Promise<boolean> {\n const [draftContent, draftState] = await Promise.all([\n this.readCompressionGuidelineDraft(),\n this.readCompressionGuidelineDraftState(),\n ]);\n if (!draftContent || !draftState) return false;\n if (\n typeof options?.expectedContentHash === \"string\" &&\n options.expectedContentHash.length > 0 &&\n draftState.contentHash !== options.expectedContentHash\n ) {\n return false;\n }\n if (\n typeof options?.expectedGuidelineVersion === \"number\" &&\n Number.isFinite(options.expectedGuidelineVersion) &&\n draftState.guidelineVersion !== options.expectedGuidelineVersion\n ) {\n return false;\n }\n if (draftState.contentHash) {\n const contentHash = createHash(\"sha256\").update(draftContent).digest(\"hex\");\n if (contentHash !== draftState.contentHash) return false;\n }\n\n await this.writeCompressionGuidelines(draftContent);\n await this.writeCompressionGuidelineOptimizerState({\n ...draftState,\n activationState: \"active\",\n });\n await Promise.all([\n unlink(this.compressionGuidelineDraftPath).catch(() => undefined),\n unlink(this.compressionGuidelineDraftStatePath).catch(() => undefined),\n ]);\n return true;\n }\n\n private async readCompressionGuidelineStateFile(\n filePath: string,\n ): Promise<CompressionGuidelineOptimizerState | null> {\n const isFiniteNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value) && Number.isInteger(value) && value >= 0;\n const isValidActionSummary = (\n value: unknown,\n ): value is NonNullable<CompressionGuidelineOptimizerState[\"actionSummaries\"]>[number] => {\n if (!value || typeof value !== \"object\") return false;\n const summary = value as NonNullable<CompressionGuidelineOptimizerState[\"actionSummaries\"]>[number];\n return (\n typeof summary.action === \"string\" &&\n isFiniteNonNegativeInteger(summary.total) &&\n summary.outcomes !== null &&\n typeof summary.outcomes === \"object\" &&\n isFiniteNonNegativeInteger(summary.outcomes.applied) &&\n isFiniteNonNegativeInteger(summary.outcomes.skipped) &&\n isFiniteNonNegativeInteger(summary.outcomes.failed) &&\n summary.quality !== null &&\n typeof summary.quality === \"object\" &&\n isFiniteNonNegativeInteger(summary.quality.good) &&\n isFiniteNonNegativeInteger(summary.quality.poor) &&\n isFiniteNonNegativeInteger(summary.quality.unknown)\n );\n };\n const isValidRuleUpdate = (\n value: unknown,\n ): value is NonNullable<CompressionGuidelineOptimizerState[\"ruleUpdates\"]>[number] => {\n if (!value || typeof value !== \"object\") return false;\n const rule = value as NonNullable<CompressionGuidelineOptimizerState[\"ruleUpdates\"]>[number];\n return (\n typeof rule.action === \"string\" &&\n typeof rule.delta === \"number\" &&\n Number.isFinite(rule.delta) &&\n (rule.direction === \"increase\" || rule.direction === \"decrease\" || rule.direction === \"hold\") &&\n (rule.confidence === \"low\" || rule.confidence === \"medium\" || rule.confidence === \"high\") &&\n Array.isArray(rule.notes) &&\n rule.notes.every((note) => typeof note === \"string\")\n );\n };\n\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<CompressionGuidelineOptimizerState>;\n const sourceWindow = parsed?.sourceWindow as Partial<CompressionGuidelineOptimizerState[\"sourceWindow\"]>;\n const eventCounts = parsed?.eventCounts as Partial<CompressionGuidelineOptimizerState[\"eventCounts\"]>;\n const activationState =\n parsed?.activationState === \"draft\" || parsed?.activationState === \"active\"\n ? parsed.activationState\n : undefined;\n const contentHash =\n typeof parsed?.contentHash === \"string\" && parsed.contentHash.length > 0\n ? parsed.contentHash\n : undefined;\n const actionSummaries = Array.isArray(parsed?.actionSummaries)\n ? parsed.actionSummaries.filter(isValidActionSummary)\n : undefined;\n const ruleUpdates = Array.isArray(parsed?.ruleUpdates)\n ? parsed.ruleUpdates.filter(isValidRuleUpdate)\n : undefined;\n if (\n !isFiniteNonNegativeInteger(parsed?.version) ||\n typeof parsed?.updatedAt !== \"string\" ||\n parsed.updatedAt.length === 0 ||\n !sourceWindow ||\n typeof sourceWindow.from !== \"string\" ||\n sourceWindow.from.length === 0 ||\n typeof sourceWindow.to !== \"string\" ||\n sourceWindow.to.length === 0 ||\n !eventCounts ||\n !isFiniteNonNegativeInteger(eventCounts.total) ||\n !isFiniteNonNegativeInteger(eventCounts.applied) ||\n !isFiniteNonNegativeInteger(eventCounts.skipped) ||\n !isFiniteNonNegativeInteger(eventCounts.failed) ||\n !isFiniteNonNegativeInteger(parsed?.guidelineVersion)\n ) {\n return null;\n }\n\n return {\n version: parsed.version,\n updatedAt: parsed.updatedAt,\n sourceWindow: {\n from: sourceWindow.from,\n to: sourceWindow.to,\n },\n eventCounts: {\n total: eventCounts.total,\n applied: eventCounts.applied,\n skipped: eventCounts.skipped,\n failed: eventCounts.failed,\n },\n guidelineVersion: parsed.guidelineVersion,\n ...(contentHash ? { contentHash } : {}),\n ...(activationState ? { activationState } : {}),\n ...(actionSummaries ? { actionSummaries } : {}),\n ...(ruleUpdates ? { ruleUpdates } : {}),\n };\n } catch {\n return null;\n }\n }\n\n async writeIdentityAnchor(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.identityAnchorPath, content, \"utf-8\");\n }\n\n async readIdentityAnchor(): Promise<string | null> {\n try {\n return await readFile(this.identityAnchorPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async appendContinuityIncident(input: ContinuityIncidentOpenInput): Promise<ContinuityIncidentRecord> {\n await this.ensureDirectories();\n const now = new Date();\n const nowIso = now.toISOString();\n const date = nowIso.slice(0, 10);\n const id = this.generateId(\"incident\");\n const incident = createContinuityIncidentRecord(id, input, nowIso);\n const filePath = path.join(this.identityIncidentsDir, `${date}-${id}.md`);\n await writeFile(filePath, serializeContinuityIncident(incident), \"utf-8\");\n return { ...incident, filePath };\n }\n\n async readContinuityIncidents(\n limit: number = 200,\n state: \"open\" | \"closed\" | \"all\" = \"all\",\n ): Promise<ContinuityIncidentRecord[]> {\n const normalizedLimit = Number.isFinite(limit) ? Math.floor(limit) : 0;\n const cappedLimit = Math.max(0, normalizedLimit);\n if (cappedLimit === 0) return [];\n\n try {\n const candidates = await this.readContinuityIncidentFileNames();\n const incidents: ContinuityIncidentRecord[] = [];\n\n for (const file of candidates) {\n if (incidents.length >= cappedLimit) break;\n const filePath = path.join(this.identityIncidentsDir, file);\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = parseContinuityIncident(raw);\n if (!parsed) continue;\n if (state !== \"all\" && parsed.state !== state) continue;\n incidents.push({ ...parsed, filePath });\n } catch {\n // Fail-open on malformed/missing files.\n }\n }\n return incidents;\n } catch {\n return [];\n }\n }\n\n async closeContinuityIncident(\n id: string,\n closure: ContinuityIncidentCloseInput,\n ): Promise<ContinuityIncidentRecord | null> {\n const directFilePath = await this.findContinuityIncidentFilePathById(id);\n const target = directFilePath ? await this.readContinuityIncidentFile(directFilePath) : null;\n if (!target || !directFilePath) return null;\n if (target.state === \"closed\") return target;\n\n const closed = closeContinuityIncidentRecord(target, closure, new Date().toISOString());\n await writeFile(directFilePath, serializeContinuityIncident(closed), \"utf-8\");\n return { ...closed, filePath: directFilePath };\n }\n\n async writeIdentityAudit(period: \"weekly\" | \"monthly\", key: string, content: string): Promise<string> {\n await this.ensureDirectories();\n const safeKey = this.sanitizeIdentityAuditKey(key);\n const dir = period === \"weekly\" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;\n const filePath = path.join(dir, `${safeKey}.md`);\n await writeFile(filePath, content, \"utf-8\");\n return filePath;\n }\n\n async readIdentityAudit(period: \"weekly\" | \"monthly\", key: string): Promise<string | null> {\n try {\n const safeKey = this.sanitizeIdentityAuditKey(key);\n const dir = period === \"weekly\" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;\n return await readFile(path.join(dir, `${safeKey}.md`), \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeIdentityImprovementLoops(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.identityImprovementLoopsPath, content, \"utf-8\");\n }\n\n async readIdentityImprovementLoops(): Promise<string | null> {\n try {\n return await readFile(this.identityImprovementLoopsPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async readIdentityImprovementLoopRegister(): Promise<ContinuityImprovementLoop[]> {\n const raw = await this.readIdentityImprovementLoops();\n if (!raw) return [];\n return parseContinuityImprovementLoops(raw);\n }\n\n async upsertIdentityImprovementLoop(input: ContinuityLoopUpsertInput): Promise<ContinuityImprovementLoop> {\n const nowIso = new Date().toISOString();\n const raw = await this.readIdentityImprovementLoops();\n const { markdown, loop } = upsertContinuityLoopInMarkdown(raw, input, nowIso);\n await this.writeIdentityImprovementLoops(markdown);\n return loop;\n }\n\n async reviewIdentityImprovementLoop(\n id: string,\n input: ContinuityLoopReviewInput,\n ): Promise<ContinuityImprovementLoop | null> {\n const raw = await this.readIdentityImprovementLoops();\n const { markdown, loop } = reviewContinuityLoopInMarkdown(raw, id, input, new Date().toISOString());\n if (!loop) return null;\n await this.writeIdentityImprovementLoops(markdown);\n return loop;\n }\n\n // ---------------------------------------------------------------------------\n // Question storage\n // ---------------------------------------------------------------------------\n\n private generateId(prefix: string = \"m\"): string {\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 4);\n return `${prefix}-${ts}-${rand}`;\n }\n\n private async readContinuityIncidentFileNames(): Promise<string[]> {\n const files = await readdir(this.identityIncidentsDir);\n return files\n .filter((file) => file.endsWith(\".md\"))\n .sort()\n .reverse();\n }\n\n private async readContinuityIncidentFile(filePath: string): Promise<ContinuityIncidentRecord | null> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = parseContinuityIncident(raw);\n return parsed ? { ...parsed, filePath } : null;\n } catch {\n return null;\n }\n }\n\n private async findContinuityIncidentFilePathById(id: string): Promise<string | null> {\n const fileNames = await this.readContinuityIncidentFileNames();\n const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));\n if (directMatch) {\n const directPath = path.join(this.identityIncidentsDir, directMatch);\n const parsed = await this.readContinuityIncidentFile(directPath);\n if (parsed?.id === id) return directPath;\n }\n\n for (const fileName of fileNames) {\n const filePath = path.join(this.identityIncidentsDir, fileName);\n const parsed = await this.readContinuityIncidentFile(filePath);\n if (parsed?.id === id) return filePath;\n }\n return null;\n }\n\n private sanitizeIdentityAuditKey(key: string): string {\n const trimmed = key.trim();\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(trimmed) || trimmed.includes(\"..\")) {\n throw new Error(\"Invalid identity audit key\");\n }\n return trimmed;\n }\n\n async writeQuestion(\n question: string,\n context: string,\n priority: number,\n ): Promise<string> {\n await mkdir(this.questionsDir, { recursive: true });\n\n const id = this.generateId(\"q\");\n const frontmatter = {\n id,\n created: new Date().toISOString(),\n priority,\n resolved: false,\n };\n\n const content = `---\\n${Object.entries(frontmatter).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(\"\\n\")}\\n---\\n\\n${question}\\n\\n**Context:** ${context}\\n`;\n\n const filePath = path.join(this.questionsDir, `${id}.md`);\n await writeFile(filePath, content, \"utf-8\");\n\n log.debug(`wrote question ${id} to ${filePath}`);\n this.invalidateQuestionsCache();\n return id;\n }\n\n async readQuestions(\n opts?: { unresolvedOnly?: boolean },\n ): Promise<\n Array<{\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n }>\n > {\n const cacheKey = this.questionsDir;\n const cached = StorageManager.questionsCache.get(cacheKey);\n if (cached && Date.now() - cached.loadedAt < StorageManager.QUESTIONS_CACHE_TTL_MS) {\n // Check dir mtime for cross-process invalidation — if another process\n // wrote/resolved a question, the directory mtime will be newer than loadedAt.\n try {\n const dirStat = await stat(this.questionsDir);\n if (dirStat.mtimeMs <= cached.loadedAt) {\n const all = cached.questions;\n return opts?.unresolvedOnly ? all.filter((q) => !q.resolved) : all;\n }\n } catch {\n // Dir doesn't exist — fall through to re-read\n }\n }\n\n try {\n const files = await readdir(this.questionsDir);\n const questions = [];\n for (const file of files) {\n if (!file.endsWith(\".md\")) continue;\n const filePath = path.join(this.questionsDir, file);\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = this.parseQuestionFile(raw, filePath);\n if (parsed) {\n questions.push(parsed);\n }\n }\n const sorted = questions.sort((a, b) => b.priority - a.priority);\n StorageManager.questionsCache.set(cacheKey, { questions: sorted, loadedAt: Date.now() });\n return opts?.unresolvedOnly ? sorted.filter((q) => !q.resolved) : sorted;\n } catch {\n return [];\n }\n }\n\n /** Invalidate the questions cache (call after writing a question). */\n invalidateQuestionsCache(): void {\n StorageManager.questionsCache.delete(this.questionsDir);\n }\n\n private parseQuestionFile(\n raw: string,\n filePath: string,\n ): {\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n } | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n\\n([\\s\\S]*)$/);\n if (!match) return null;\n\n const frontmatterStr = match[1];\n const body = match[2].trim();\n\n // Parse frontmatter\n const id =\n this.extractFrontmatterValue(frontmatterStr, \"id\") ??\n path.basename(filePath, \".md\");\n const created =\n this.extractFrontmatterValue(frontmatterStr, \"created\") ?? \"\";\n const priority = parseFloat(\n this.extractFrontmatterValue(frontmatterStr, \"priority\") ?? \"0.5\",\n );\n const resolved =\n this.extractFrontmatterValue(frontmatterStr, \"resolved\") === \"true\";\n\n // Extract question and context from body\n const contextMatch = body.match(/\\*\\*Context:\\*\\*\\s*(.*)/);\n const question = contextMatch\n ? body.slice(0, contextMatch.index).trim()\n : body;\n const context = contextMatch ? contextMatch[1].trim() : \"\";\n\n return { id, question, context, priority, resolved, created, filePath };\n }\n\n private extractFrontmatterValue(\n frontmatter: string,\n key: string,\n ): string | null {\n const match = frontmatter.match(\n new RegExp(`^${key}:\\\\s*\"?([^\"\\\\n]*)\"?`, \"m\"),\n );\n return match ? match[1] : null;\n }\n\n async resolveQuestion(id: string): Promise<boolean> {\n const questions = await this.readQuestions();\n const q = questions.find((q) => q.id === id);\n if (!q) return false;\n\n let raw = await readFile(q.filePath, \"utf-8\");\n raw = raw.replace(/resolved: false/, \"resolved: true\");\n raw = raw.replace(\n /---\\n\\n/,\n `resolvedAt: \"${new Date().toISOString()}\"\\n---\\n\\n`,\n );\n await writeFile(q.filePath, raw, \"utf-8\");\n log.debug(`resolved question ${id}`);\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Identity file\n // ---------------------------------------------------------------------------\n\n async readIdentity(workspaceDir: string, namespace?: string): Promise<string> {\n const identityPath = this.identityFilePath(workspaceDir, namespace);\n try {\n return await readFile(identityPath, \"utf-8\");\n } catch {\n return \"\";\n }\n }\n\n async writeIdentity(workspaceDir: string, content: string, namespace?: string): Promise<void> {\n const identityPath = this.identityFilePath(workspaceDir, namespace);\n await writeFile(identityPath, content, \"utf-8\");\n log.debug(`wrote consolidated IDENTITY.md (${content.length} chars)`);\n }\n\n /** Max size for IDENTITY.md before we stop appending reflections (15KB leaves room under 20KB gateway limit) */\n private static readonly IDENTITY_MAX_BYTES = 15_000;\n /** Minimum interval between reflections (1 hour) */\n private static readonly REFLECTION_COOLDOWN_MS = 60 * 60 * 1000;\n\n async appendToIdentity(\n workspaceDir: string,\n reflection: string,\n opts?: { hygiene?: FileHygieneConfig; namespace?: string },\n ): Promise<void> {\n const identityPath = this.identityFilePath(workspaceDir, opts?.namespace);\n\n let existing = \"\";\n try {\n existing = await readFile(identityPath, \"utf-8\");\n } catch {\n // File doesn't exist yet\n }\n\n const hygiene = opts?.hygiene;\n const rotateEnabled =\n hygiene?.enabled === true &&\n hygiene.rotateEnabled === true &&\n Array.isArray(hygiene.rotatePaths) &&\n hygiene.rotatePaths.includes(path.basename(identityPath));\n\n // Rotation/splitting: preserve full history, keep the bootstrap file small.\n if (rotateEnabled) {\n const maxBytes = hygiene.rotateMaxBytes;\n if (existing.length > maxBytes) {\n const archiveDir = path.join(workspaceDir, hygiene.archiveDir);\n const { newContent } = await rotateMarkdownFileToArchive({\n filePath: identityPath,\n archiveDir,\n archivePrefix: \"IDENTITY\",\n keepTailChars: hygiene.rotateKeepTailChars,\n });\n await writeFile(identityPath, newContent, \"utf-8\");\n existing = newContent;\n log.info(\n `rotated IDENTITY.md to archive (size=${existing.length} chars, maxBytes=${maxBytes})`,\n );\n }\n } else {\n // Legacy behavior: skip if file is too large\n if (existing.length > StorageManager.IDENTITY_MAX_BYTES) {\n log.debug(`IDENTITY.md is ${existing.length} chars (limit ${StorageManager.IDENTITY_MAX_BYTES}); skipping reflection`);\n return;\n }\n }\n\n // Rate-limit: skip if last reflection was less than 1 hour ago\n const lastMatch = existing.match(/## Reflection — (\\S+)\\s*$/m);\n if (lastMatch) {\n // Find the LAST reflection timestamp\n const allMatches = [...existing.matchAll(/## Reflection — (\\S+)/g)];\n if (allMatches.length > 0) {\n const lastTimestamp = allMatches[allMatches.length - 1][1];\n const elapsed = Date.now() - new Date(lastTimestamp).getTime();\n if (elapsed < StorageManager.REFLECTION_COOLDOWN_MS) {\n log.debug(`reflection cooldown: ${Math.round(elapsed / 1000)}s since last (need ${StorageManager.REFLECTION_COOLDOWN_MS / 1000}s)`);\n return;\n }\n }\n }\n\n const timestamp = new Date().toISOString();\n const section = `\\n\\n## Reflection — ${timestamp}\\n\\n${reflection}\\n`;\n\n await writeFile(identityPath, existing + section, \"utf-8\");\n log.debug(`appended reflection to ${identityPath}`);\n }\n\n async readIdentityReflections(): Promise<string | null> {\n try {\n return await readFile(this.identityReflectionsPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeIdentityReflections(content: string): Promise<void> {\n await mkdir(this.identityDir, { recursive: true });\n await writeFile(this.identityReflectionsPath, content, \"utf-8\");\n }\n\n async appendIdentityReflection(reflection: string): Promise<void> {\n let existing = \"\";\n try {\n existing = await readFile(this.identityReflectionsPath, \"utf-8\");\n } catch {\n // File doesn't exist yet.\n }\n\n if (existing.length > StorageManager.IDENTITY_MAX_BYTES) {\n log.debug(\n `identity/reflections.md is ${existing.length} chars (limit ${StorageManager.IDENTITY_MAX_BYTES}); skipping reflection`,\n );\n return;\n }\n\n const allMatches = [...existing.matchAll(/## Reflection — (\\S+)/g)];\n if (allMatches.length > 0) {\n const lastTimestamp = allMatches[allMatches.length - 1][1];\n const elapsed = Date.now() - new Date(lastTimestamp).getTime();\n if (elapsed < StorageManager.REFLECTION_COOLDOWN_MS) {\n log.debug(\n `reflection cooldown: ${Math.round(elapsed / 1000)}s since last (need ${StorageManager.REFLECTION_COOLDOWN_MS / 1000}s)`,\n );\n return;\n }\n }\n\n const timestamp = new Date().toISOString();\n const section = `${existing.trimEnd().length > 0 ? \"\\n\\n\" : \"\"}## Reflection — ${timestamp}\\n\\n${reflection}\\n`;\n await mkdir(this.identityDir, { recursive: true });\n await writeFile(this.identityReflectionsPath, `${existing.trimEnd()}${section}`, \"utf-8\");\n log.debug(`appended namespace-local reflection to ${this.identityReflectionsPath}`);\n }\n\n // ---------------------------------------------------------------------------\n // Entity mutation helpers (Knowledge Graph v7.0)\n // ---------------------------------------------------------------------------\n\n /**\n * Add a relationship to an entity file.\n * Deduplicates by target+label.\n */\n async addEntityRelationship(name: string, rel: EntityRelationship): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`addEntityRelationship: entity file ${name}.md not found`);\n return;\n }\n\n // Dedupe by target+label\n const exists = entity.relationships.some(\n (r) => r.target === rel.target && r.label === rel.label,\n );\n if (exists) return;\n\n entity.relationships.push(rel);\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n }\n\n /**\n * Add an activity entry to an entity file.\n * Prepends to the beginning, prunes oldest entries beyond maxEntries.\n */\n async addEntityActivity(\n name: string,\n entry: EntityActivityEntry,\n maxEntries: number,\n ): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`addEntityActivity: entity file ${name}.md not found`);\n return;\n }\n\n entity.activity.unshift(entry);\n if (entity.activity.length > maxEntries) {\n entity.activity = entity.activity.slice(0, maxEntries);\n }\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n }\n\n /**\n * Add an alias to an entity file. Deduplicates.\n */\n async addEntityAlias(name: string, alias: string): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`addEntityAlias: entity file ${name}.md not found`);\n return;\n }\n\n if (entity.aliases.includes(alias)) return;\n entity.aliases.push(alias);\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n }\n\n /**\n * Set or update the summary of an entity file.\n */\n async updateEntitySummary(name: string, summary: string): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`updateEntitySummary: entity file ${name}.md not found`);\n return;\n }\n\n entity.summary = summary;\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n this.bumpMemoryStatusVersion(); // invalidate entity cache\n }\n\n // ---------------------------------------------------------------------------\n // Scoring + Knowledge Index (Knowledge Graph v7.0)\n // ---------------------------------------------------------------------------\n\n /**\n * Read all entity files and return lightweight EntityFile objects.\n * Parsing is fast (~50-100ms for ~1,800 files) since entity files are small.\n */\n async readAllEntityFiles(): Promise<EntityFile[]> {\n const currentVersion = this.getMemoryStatusVersion();\n const cached = getCachedEntities(this.baseDir, currentVersion);\n if (cached) return cached;\n\n try {\n const entries = await readdir(this.entitiesDir);\n const mdFiles = entries.filter((e) => e.endsWith(\".md\"));\n if (mdFiles.length === 0) return [];\n\n // Read all entity files in parallel batches to avoid O(N) sequential I/O.\n // With 3000+ entity files, sequential reads can take 15-20s under load.\n // Batching at 100 keeps file-descriptor pressure manageable while staying fast.\n const BATCH_SIZE = 100;\n const entities: EntityFile[] = [];\n for (let i = 0; i < mdFiles.length; i += BATCH_SIZE) {\n const batch = mdFiles.slice(i, i + BATCH_SIZE);\n const results = await Promise.all(\n batch.map((entry) =>\n readFile(path.join(this.entitiesDir, entry), \"utf-8\").catch(() => null),\n ),\n );\n for (const content of results) {\n if (content !== null) entities.push(parseEntityFile(content));\n }\n }\n\n setCachedEntities(this.baseDir, entities, currentVersion);\n return entities;\n } catch {\n // Directory doesn't exist yet\n return [];\n }\n }\n\n /**\n * Score an entity based on recency, frequency, activity, type priority,\n * and relationship density.\n *\n * score = recency*0.40 + frequency*0.25 + activity*0.15 + typePriority*0.10 + relationshipDensity*0.10\n */\n static scoreEntity(entity: EntityFile, now: Date): number {\n // Recency: 1 / (1 + daysSince/7) — 7-day half-life\n const updated = entity.updated ? new Date(entity.updated).getTime() : 0;\n const daysSince = Math.max(0, (now.getTime() - updated) / (1000 * 60 * 60 * 24));\n const recency = 1 / (1 + daysSince / 7);\n\n // Frequency: min(facts.length / 20, 1.0)\n const frequency = Math.min(entity.facts.length / 20, 1.0);\n\n // Activity: min(activity.length / 10, 1.0)\n const activityScore = Math.min(entity.activity.length / 10, 1.0);\n\n // Type priority\n const TYPE_PRIORITY: Record<string, number> = {\n person: 1.0,\n project: 0.8,\n company: 0.7,\n tool: 0.6,\n place: 0.5,\n other: 0.3,\n };\n const typePriority = TYPE_PRIORITY[entity.type.toLowerCase()] ?? 0.3;\n\n // Relationship density: min(relationships.length / 8, 1.0)\n const relDensity = Math.min(entity.relationships.length / 8, 1.0);\n\n return (\n recency * 0.40 +\n frequency * 0.25 +\n activityScore * 0.15 +\n typePriority * 0.10 +\n relDensity * 0.10\n );\n }\n\n /**\n * Build the Knowledge Index: a compact markdown table of top-scored entities.\n * Respects maxEntities and maxChars limits from config.\n */\n async buildKnowledgeIndex(\n config: PluginConfig,\n overrides?: { maxEntities?: number; maxChars?: number },\n ): Promise<{ result: string; cached: boolean }> {\n const useDefaultLimits =\n overrides?.maxEntities === undefined &&\n overrides?.maxChars === undefined;\n // Return cached index if still fresh\n if (\n useDefaultLimits &&\n this.knowledgeIndexCache &&\n Date.now() - this.knowledgeIndexCache.builtAt < StorageManager.KNOWLEDGE_INDEX_CACHE_TTL_MS\n ) {\n return { result: this.knowledgeIndexCache.result, cached: true };\n }\n\n const entities = await this.readAllEntityFiles();\n if (entities.length === 0) {\n if (useDefaultLimits) this.knowledgeIndexCache = { result: \"\", builtAt: Date.now() };\n return { result: \"\", cached: false };\n }\n\n const now = new Date();\n const scored: ScoredEntity[] = entities.map((e) => ({\n name: e.name,\n type: e.type,\n score: StorageManager.scoreEntity(e, now),\n factCount: e.facts.length,\n summary: e.summary,\n topRelationships: e.relationships.slice(0, 3).map((r) => r.target),\n }));\n\n // Sort by score descending, take top N\n scored.sort((a, b) => b.score - a.score);\n const maxEntities = typeof overrides?.maxEntities === \"number\"\n ? Math.max(0, Math.floor(overrides.maxEntities))\n : config.knowledgeIndexMaxEntities;\n const topN = scored.slice(0, maxEntities);\n\n if (topN.length === 0) {\n if (useDefaultLimits) this.knowledgeIndexCache = { result: \"\", builtAt: Date.now() };\n return { result: \"\", cached: false };\n }\n\n // Build markdown table\n const header = \"## Knowledge Index\\n\\n| Entity | Type | Summary | Connected to |\\n|--------|------|---------|-------------|\";\n const rows: string[] = [];\n let totalChars = header.length;\n const maxChars = typeof overrides?.maxChars === \"number\"\n ? Math.max(0, Math.floor(overrides.maxChars))\n : config.knowledgeIndexMaxChars;\n\n for (const entity of topN) {\n const summary = entity.summary || `${entity.factCount} facts`;\n const connected = entity.topRelationships.length > 0\n ? entity.topRelationships.join(\", \")\n : \"—\";\n const row = `| ${entity.name} | ${entity.type} | ${summary} | ${connected} |`;\n\n if (totalChars + row.length + 1 > maxChars) break;\n rows.push(row);\n totalChars += row.length + 1;\n }\n\n const result = rows.length === 0 ? \"\" : `${header}\\n${rows.join(\"\\n\")}\\n`;\n if (useDefaultLimits) this.knowledgeIndexCache = { result, builtAt: Date.now() };\n return { result, cached: false };\n }\n\n /** Invalidate the Knowledge Index cache (call after entity mutations). */\n invalidateKnowledgeIndexCache(): void {\n this.knowledgeIndexCache = null;\n }\n\n // ---------------------------------------------------------------------------\n // Commitment decay\n // ---------------------------------------------------------------------------\n\n /** Max lines for profile.md before LLM consolidation triggers */\n private static readonly PROFILE_MAX_LINES = 300;\n\n /**\n * Merge fragmented entity files that resolve to the same canonical name.\n * Preserves relationships, activity, aliases, and summary from all fragments.\n * Returns count of files merged.\n */\n async mergeFragmentedEntities(): Promise<number> {\n let merged = 0;\n try {\n const entries = await readdir(this.entitiesDir);\n const mdFiles = entries.filter((e) => e.endsWith(\".md\"));\n\n // Group files by their canonical name\n const groups = new Map<string, string[]>();\n for (const file of mdFiles) {\n const baseName = file.replace(\".md\", \"\");\n // Extract type and name from filename (type-rest-of-name)\n const dashIdx = baseName.indexOf(\"-\");\n if (dashIdx === -1) continue;\n const type = baseName.slice(0, dashIdx);\n const restOfName = baseName.slice(dashIdx + 1);\n const canonical = normalizeEntityName(restOfName, type);\n\n if (!groups.has(canonical)) groups.set(canonical, []);\n groups.get(canonical)!.push(file);\n }\n\n // Merge groups with more than one file\n for (const [canonical, files] of groups) {\n if (files.length <= 1) continue;\n\n // Parse all files and merge into a single EntityFile\n const mergedEntity: EntityFile = {\n name: \"\",\n type: \"other\",\n updated: \"\",\n facts: [],\n summary: undefined,\n relationships: [],\n activity: [],\n aliases: [],\n };\n\n for (const file of files) {\n const filePath = path.join(this.entitiesDir, file);\n try {\n const content = await readFile(filePath, \"utf-8\");\n const parsed = parseEntityFile(content);\n\n // Prefer specific types over \"other\"\n if (!mergedEntity.type || mergedEntity.type === \"other\") {\n mergedEntity.type = parsed.type;\n }\n\n // Keep latest update time\n if (!mergedEntity.updated || parsed.updated > mergedEntity.updated) {\n mergedEntity.updated = parsed.updated;\n }\n\n // Keep longest/best name\n if (parsed.name.length > mergedEntity.name.length) {\n mergedEntity.name = parsed.name;\n }\n\n // Keep first non-empty summary\n if (!mergedEntity.summary && parsed.summary) {\n mergedEntity.summary = parsed.summary;\n }\n\n // Collect all facts\n mergedEntity.facts.push(...parsed.facts);\n\n // Collect relationships (dedup later)\n mergedEntity.relationships.push(...parsed.relationships);\n\n // Collect activity entries\n mergedEntity.activity.push(...parsed.activity);\n\n // Collect aliases\n mergedEntity.aliases.push(...parsed.aliases);\n } catch {\n // Skip unreadable\n }\n }\n\n // Deduplicate facts\n mergedEntity.facts = [...new Set(mergedEntity.facts)];\n\n // Deduplicate relationships by target+label\n const relKeys = new Set<string>();\n mergedEntity.relationships = mergedEntity.relationships.filter((r) => {\n const key = `${r.target}::${r.label}`;\n if (relKeys.has(key)) return false;\n relKeys.add(key);\n return true;\n });\n\n // Sort activity by date descending, deduplicate by date+note\n const actKeys = new Set<string>();\n mergedEntity.activity = mergedEntity.activity\n .filter((a) => {\n const key = `${a.date}::${a.note}`;\n if (actKeys.has(key)) return false;\n actKeys.add(key);\n return true;\n })\n .sort((a, b) => b.date.localeCompare(a.date));\n\n // Deduplicate aliases\n mergedEntity.aliases = [...new Set(mergedEntity.aliases)];\n\n // Fallback name from canonical\n if (!mergedEntity.name) {\n const dashIdx = canonical.indexOf(\"-\");\n mergedEntity.name = dashIdx !== -1 ? canonical.slice(dashIdx + 1) : canonical;\n }\n\n mergedEntity.updated = mergedEntity.updated || new Date().toISOString();\n\n const canonicalPath = path.join(this.entitiesDir, `${canonical}.md`);\n await writeFile(canonicalPath, serializeEntityFile(mergedEntity), \"utf-8\");\n\n // Remove non-canonical files\n for (const file of files) {\n const filePath = path.join(this.entitiesDir, file);\n if (filePath !== canonicalPath) {\n try {\n await unlink(filePath);\n merged++;\n log.debug(`merged entity ${file} → ${canonical}.md`);\n } catch {\n // Ignore\n }\n }\n }\n }\n } catch {\n // Directory doesn't exist yet\n }\n\n return merged;\n }\n\n async cleanExpiredCommitments(decayDays: number): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n const cutoff = Date.now() - decayDays * 24 * 60 * 60 * 1000;\n const deleted: MemoryFile[] = [];\n\n for (const m of memories) {\n if (m.frontmatter.category !== \"commitment\") continue;\n // Only decay commitments that have been marked as resolved/expired\n // (indicated by tags containing \"fulfilled\" or \"expired\")\n const isResolved = m.frontmatter.tags.some(\n (t) => t === \"fulfilled\" || t === \"expired\",\n );\n if (!isResolved) continue;\n\n const updatedAt = new Date(m.frontmatter.updated).getTime();\n if (updatedAt < cutoff) {\n // Remove the file\n try {\n await unlink(m.path);\n deleted.push(m);\n log.debug(`cleaned expired commitment ${m.frontmatter.id}`);\n } catch {\n // Ignore\n }\n }\n }\n\n if (deleted.length > 0) {\n this.bumpMemoryStatusVersion();\n }\n\n return deleted;\n }\n\n // ---------------------------------------------------------------------------\n // Access Tracking (Phase 1A)\n // ---------------------------------------------------------------------------\n\n /**\n * Flush batched access tracking updates to disk.\n * Called during consolidation or when buffer exceeds max size.\n */\n async flushAccessTracking(entries: AccessTrackingEntry[]): Promise<number> {\n if (entries.length === 0) return 0;\n\n const memories = await this.readAllMemories();\n const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));\n let updated = 0;\n\n for (const entry of entries) {\n const memory = memoryMap.get(entry.memoryId);\n if (!memory) continue;\n\n const newFm: MemoryFrontmatter = {\n ...memory.frontmatter,\n accessCount: entry.newCount,\n lastAccessed: entry.lastAccessed,\n };\n\n const fileContent = `${serializeFrontmatter(newFm)}\\n\\n${memory.content}\\n`;\n try {\n await writeFile(memory.path, fileContent, \"utf-8\");\n updated++;\n } catch (err) {\n log.debug(`failed to update access tracking for ${entry.memoryId}: ${err}`);\n }\n }\n\n if (updated > 0) {\n log.debug(`flushed access tracking for ${updated} memories`);\n }\n return updated;\n }\n\n /**\n * Get a memory by its ID.\n */\n async getMemoryById(id: string): Promise<MemoryFile | null> {\n const memories = await this.readAllMemories();\n return memories.find((m) => m.frontmatter.id === id) ?? null;\n }\n\n async getProjectedMemoryState(id: string): Promise<MemoryProjectionCurrentState | null> {\n const projected = readProjectedMemoryState(this.baseDir, id);\n if (projected) return projected;\n\n const active = await this.getMemoryById(id);\n if (active) return this.toProjectedCurrentState(active, \"active\");\n\n const archived = (await this.readArchivedMemories()).find((memory) => memory.frontmatter.id === id);\n if (!archived) return null;\n\n return this.toProjectedCurrentState(archived, \"archived\");\n }\n\n async browseProjectedMemories(\n options: ProjectedMemoryBrowseOptions,\n ): Promise<ProjectedMemoryBrowsePage | null> {\n return readProjectedMemoryBrowse(this.baseDir, options);\n }\n\n async getProjectedGovernanceRecord(): Promise<ReturnType<typeof readProjectedGovernanceRecord>> {\n return readProjectedGovernanceRecord(this.baseDir);\n }\n\n private toProjectedCurrentState(\n memory: MemoryFile,\n fallbackStatus: MemoryStatus,\n ): MemoryProjectionCurrentState {\n const pathRel = toMemoryPathRel(this.baseDir, memory.path);\n return {\n memoryId: memory.frontmatter.id,\n category: memory.frontmatter.category,\n status: inferCurrentStateStatus(memory.frontmatter, pathRel, fallbackStatus),\n lifecycleState: memory.frontmatter.lifecycleState,\n path: memory.path,\n pathRel,\n created: memory.frontmatter.created,\n updated: memory.frontmatter.updated,\n archivedAt: memory.frontmatter.archivedAt,\n supersededAt: memory.frontmatter.supersededAt,\n entityRef: memory.frontmatter.entityRef,\n source: memory.frontmatter.source,\n confidence: memory.frontmatter.confidence,\n confidenceTier: memory.frontmatter.confidenceTier,\n memoryKind: memory.frontmatter.memoryKind,\n accessCount: memory.frontmatter.accessCount,\n lastAccessed: memory.frontmatter.lastAccessed,\n tags: normalizeProjectionTags(memory.frontmatter.tags),\n preview: normalizeProjectionPreview(memory.content),\n };\n }\n\n async getMemoryTimeline(memoryId: string, limit: number = 200): Promise<MemoryLifecycleEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n const projected = readProjectedMemoryTimeline(this.baseDir, memoryId, cappedLimit);\n if (projected && projected.length > 0) return projected;\n\n const events = await this.readAllMemoryLifecycleEvents();\n return events.filter((event) => event.memoryId === memoryId).slice(-cappedLimit);\n }\n\n // ---------------------------------------------------------------------------\n // Chunking (Phase 2A)\n // ---------------------------------------------------------------------------\n\n /**\n * Write a memory chunk with parent reference.\n * Chunk IDs follow format: {parentId}-chunk-{index}\n */\n async writeChunk(\n parentId: string,\n chunkIndex: number,\n chunkTotal: number,\n category: MemoryCategory,\n content: string,\n options: {\n confidence?: number;\n tags?: string[];\n entityRef?: string;\n source?: string;\n importance?: ImportanceScore;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n } = {},\n ): Promise<string> {\n await this.ensureDirectories();\n const now = new Date();\n const today = now.toISOString().slice(0, 10);\n const id = `${parentId}-chunk-${chunkIndex}`;\n const conf = options.confidence ?? 0.8;\n const tier = confidenceTier(conf);\n\n const fm: MemoryFrontmatter = {\n id,\n category,\n created: now.toISOString(),\n updated: now.toISOString(),\n source: options.source ?? \"chunking\",\n confidence: conf,\n confidenceTier: tier,\n tags: options.tags ?? [],\n entityRef: options.entityRef,\n importance: options.importance,\n parentId,\n chunkIndex,\n chunkTotal,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n memoryKind: options.memoryKind,\n };\n\n const sanitized = sanitizeMemoryContent(content);\n if (!sanitized.clean) {\n log.warn(`chunk content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n const fileContent = `${serializeFrontmatter(fm)}\\n\\n${sanitized.text}\\n`;\n\n let filePath: string;\n if (category === \"correction\") {\n filePath = path.join(this.correctionsDir, `${id}.md`);\n } else {\n filePath = path.join(this.factsDir, today, `${id}.md`);\n }\n\n await writeFile(filePath, fileContent, \"utf-8\");\n log.debug(`wrote chunk ${id} (${chunkIndex + 1}/${chunkTotal}) to ${filePath}`);\n return id;\n }\n\n /**\n * Get all chunks for a given parent memory ID.\n * Returns chunks sorted by chunkIndex.\n */\n async getChunksForParent(parentId: string): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n return memories\n .filter((m) => m.frontmatter.parentId === parentId)\n .sort((a, b) => (a.frontmatter.chunkIndex ?? 0) - (b.frontmatter.chunkIndex ?? 0));\n }\n\n // ---------------------------------------------------------------------------\n // Contradiction Detection (Phase 2B)\n // ---------------------------------------------------------------------------\n\n /**\n * Mark a memory as superseded by another.\n * Updates the old memory's status and adds the supersededBy link.\n */\n async supersedeMemory(\n oldMemoryId: string,\n newMemoryId: string,\n reason: string,\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const oldMemory = memories.find((m) => m.frontmatter.id === oldMemoryId);\n if (!oldMemory) return false;\n\n const now = new Date().toISOString();\n const updatedFm: MemoryFrontmatter = {\n ...oldMemory.frontmatter,\n status: \"superseded\",\n supersededBy: newMemoryId,\n supersededAt: now,\n updated: now,\n };\n\n const fileContent = `${serializeFrontmatter(updatedFm)}\\n\\n${oldMemory.content}\\n`;\n\n try {\n await writeFile(oldMemory.path, fileContent, \"utf-8\");\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.supersedeMemory\", {\n memoryId: oldMemoryId,\n eventType: \"superseded\",\n timestamp: now,\n actor: \"storage.supersedeMemory\",\n reasonCode: reason,\n before: this.summarizeLifecycleState(oldMemory.frontmatter, oldMemory.path),\n after: this.summarizeLifecycleState(updatedFm, oldMemory.path),\n relatedMemoryIds: [newMemoryId],\n });\n this.bumpMemoryStatusVersion();\n log.debug(`superseded memory ${oldMemoryId} by ${newMemoryId}: ${reason}`);\n\n // Also write a correction entry for the audit trail\n await this.writeMemory(\"correction\", `Superseded: ${oldMemory.content}\\n\\nReason: ${reason}`, {\n confidence: 1.0,\n tags: [\"supersession\", \"auto-resolved\"],\n source: \"contradiction-detection\",\n lineage: [oldMemoryId, newMemoryId],\n });\n\n return true;\n } catch (err) {\n log.error(`failed to supersede memory ${oldMemoryId}:`, err);\n return false;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Memory Summarization (Phase 4A)\n // ---------------------------------------------------------------------------\n\n private get summariesDir(): string {\n return path.join(this.baseDir, \"summaries\");\n }\n\n /**\n * Write a memory summary.\n */\n async writeSummary(summary: MemorySummary): Promise<void> {\n await mkdir(this.summariesDir, { recursive: true });\n const filePath = path.join(this.summariesDir, `${summary.id}.json`);\n await writeFile(filePath, JSON.stringify(summary, null, 2), \"utf-8\");\n log.debug(`wrote summary ${summary.id}`);\n }\n\n /**\n * Get all summaries.\n */\n async readSummaries(): Promise<MemorySummary[]> {\n try {\n const files = await readdir(this.summariesDir);\n const summaries: MemorySummary[] = [];\n\n for (const file of files) {\n if (!file.endsWith(\".json\")) continue;\n const filePath = path.join(this.summariesDir, file);\n const raw = await readFile(filePath, \"utf-8\");\n summaries.push(JSON.parse(raw) as MemorySummary);\n }\n\n return summaries;\n } catch {\n return [];\n }\n }\n\n /**\n * Archive memories (mark as archived, not delete).\n */\n async archiveMemories(memoryIds: string[], summaryId: string): Promise<number> {\n const memories = await this.readAllMemories();\n const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));\n let archived = 0;\n\n for (const id of memoryIds) {\n const memory = memoryMap.get(id);\n if (!memory) continue;\n\n const now = new Date().toISOString();\n const updatedFm: MemoryFrontmatter = {\n ...memory.frontmatter,\n status: \"archived\",\n archivedAt: now,\n updated: now,\n };\n\n const fileContent = `${serializeFrontmatter(updatedFm)}\\n\\n${memory.content}\\n`;\n\n try {\n await writeFile(memory.path, fileContent, \"utf-8\");\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.archiveMemories\", {\n memoryId: id,\n eventType: \"archived\",\n timestamp: updatedFm.archivedAt ?? updatedFm.updated,\n actor: \"storage.archiveMemories\",\n reasonCode: `summary:${summaryId}`,\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updatedFm, memory.path),\n relatedMemoryIds: [summaryId],\n });\n archived++;\n } catch {\n // Ignore individual failures\n }\n }\n\n if (archived > 0) {\n this.bumpMemoryStatusVersion();\n log.debug(`archived ${archived} memories for summary ${summaryId}`);\n }\n return archived;\n }\n\n // ---------------------------------------------------------------------------\n // Topic Extraction (Phase 4B)\n // ---------------------------------------------------------------------------\n\n /**\n * Save topic scores to meta.json.\n */\n async saveTopics(topics: TopicScore[]): Promise<void> {\n const metaPath = path.join(this.stateDir, \"topics.json\");\n await mkdir(this.stateDir, { recursive: true });\n await writeFile(metaPath, JSON.stringify({ topics, updatedAt: new Date().toISOString() }, null, 2), \"utf-8\");\n log.debug(`saved ${topics.length} topic scores`);\n }\n\n /**\n * Load topic scores from meta.json.\n */\n async loadTopics(): Promise<{ topics: TopicScore[]; updatedAt: string | null }> {\n const metaPath = path.join(this.stateDir, \"topics.json\");\n try {\n const raw = await readFile(metaPath, \"utf-8\");\n return JSON.parse(raw) as { topics: TopicScore[]; updatedAt: string | null };\n } catch {\n return { topics: [], updatedAt: null };\n }\n }\n\n /**\n * Add links to an existing memory.\n */\n async addLinksToMemory(\n memoryId: string,\n links: MemoryLink[],\n lifecycle?: MemoryLifecycleEventWriteOptions,\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === memoryId);\n if (!memory) return false;\n\n const existingLinks = memory.frontmatter.links ?? [];\n const mergedLinks = [...existingLinks];\n\n // Add new links, avoiding duplicates\n for (const link of links) {\n if (!mergedLinks.some((l) => l.targetId === link.targetId && l.linkType === link.linkType)) {\n mergedLinks.push(link);\n }\n }\n\n try {\n await this.writeMemoryFrontmatter(\n memory,\n {\n links: mergedLinks,\n updated: new Date().toISOString(),\n },\n lifecycle,\n );\n log.debug(`added ${links.length} links to memory ${memoryId}`);\n return true;\n } catch (err) {\n log.error(`failed to add links to memory ${memoryId}:`, err);\n return false;\n }\n }\n\n private summarizeLifecycleState(\n frontmatter: MemoryFrontmatter,\n filePath: string,\n ): MemoryLifecycleStateSummary {\n return {\n category: frontmatter.category,\n path: filePath,\n status: frontmatter.status ?? \"active\",\n lifecycleState: frontmatter.lifecycleState,\n };\n }\n\n private frontmatterPatchEventType(\n before: MemoryFrontmatter,\n after: MemoryFrontmatter,\n ): MemoryLifecycleEventType {\n const beforeStatus = before.status ?? \"active\";\n const afterStatus = after.status ?? \"active\";\n if (beforeStatus !== \"archived\" && afterStatus === \"archived\") return \"archived\";\n if (beforeStatus !== \"superseded\" && afterStatus === \"superseded\") return \"superseded\";\n if (beforeStatus !== \"rejected\" && afterStatus === \"rejected\") return \"rejected\";\n if (beforeStatus !== \"active\" && afterStatus === \"active\") {\n return \"restored\";\n }\n return \"updated\";\n }\n\n private async appendGeneratedMemoryLifecycleEvent(\n input: Omit<MemoryLifecycleEvent, \"eventId\" | \"ruleVersion\">,\n ruleVersion = \"memory-lifecycle-ledger.v1\",\n ): Promise<void> {\n await this.appendMemoryLifecycleEvents([\n {\n ...input,\n eventId: this.generateId(\"mle\"),\n ruleVersion,\n },\n ]);\n }\n\n private async appendGeneratedMemoryLifecycleEventFailOpen(\n operation: string,\n input: Omit<MemoryLifecycleEvent, \"eventId\" | \"ruleVersion\">,\n ruleVersion?: string,\n ): Promise<void> {\n try {\n await this.appendGeneratedMemoryLifecycleEvent(input, ruleVersion);\n } catch (appendErr) {\n log.warn(`${operation} completed but failed to append lifecycle event: ${appendErr}`);\n }\n }\n}\n","import type { EntityFile, MemoryFile } from \"./types.js\";\n\ninterface CacheEntry {\n memories: Map<string, MemoryFile>; // keyed by file path\n version: number;\n loadedAt: number;\n}\n\n// Module-level singleton — shared across all StorageManager instances and sessions\nconst hotCacheByDir = new Map<string, CacheEntry>();\nconst archiveCacheByDir = new Map<string, CacheEntry>();\n\nexport function getCachedMemories(baseDir: string, currentVersion: number): MemoryFile[] | null {\n // Don't serve from cache when version tracking is unavailable (version=0).\n // This ensures tests and fresh installs without a version file always read disk.\n if (currentVersion === 0) return null;\n const entry = hotCacheByDir.get(baseDir);\n if (!entry || entry.version !== currentVersion) return null;\n return [...entry.memories.values()];\n}\n\nexport function setCachedMemories(baseDir: string, memories: MemoryFile[], version: number): void {\n const map = new Map<string, MemoryFile>();\n for (const m of memories) map.set(m.path, m);\n hotCacheByDir.set(baseDir, { memories: map, version, loadedAt: Date.now() });\n}\n\nexport function updateCacheOnWrite(baseDir: string, memory: MemoryFile): void {\n const entry = hotCacheByDir.get(baseDir);\n if (entry) entry.memories.set(memory.path, memory);\n}\n\nexport function updateCacheOnDelete(baseDir: string, filePath: string): void {\n const entry = hotCacheByDir.get(baseDir);\n if (entry) entry.memories.delete(filePath);\n}\n\n// Archive cache — same pattern, separate store\nexport function getCachedArchivedMemories(baseDir: string, currentVersion: number): MemoryFile[] | null {\n if (currentVersion === 0) return null;\n const entry = archiveCacheByDir.get(baseDir);\n if (!entry || entry.version !== currentVersion) return null;\n return [...entry.memories.values()];\n}\n\nexport function setCachedArchivedMemories(baseDir: string, memories: MemoryFile[], version: number): void {\n const map = new Map<string, MemoryFile>();\n for (const m of memories) map.set(m.path, m);\n archiveCacheByDir.set(baseDir, { memories: map, version, loadedAt: Date.now() });\n}\n\n// Entity cache — same pattern as memory cache\nconst entityCacheByDir = new Map<string, { entities: EntityFile[]; version: number; loadedAt: number }>();\n\nexport function getCachedEntities(baseDir: string, currentVersion: number): EntityFile[] | null {\n if (currentVersion === 0) return null;\n const entry = entityCacheByDir.get(baseDir);\n if (!entry || entry.version !== currentVersion) return null;\n return entry.entities;\n}\n\nexport function setCachedEntities(baseDir: string, entities: EntityFile[], version: number): void {\n entityCacheByDir.set(baseDir, { entities, version, loadedAt: Date.now() });\n}\n\n// Derived caches — pre-filtered views invalidated alongside the main cache.\n// These avoid O(146K) filter+map on every verified recall/rules call.\ninterface DerivedCacheEntry<T> {\n data: T;\n sourceVersion: number; // matches the hot cache version it was derived from\n}\n\nconst episodeMapByDir = new Map<string, DerivedCacheEntry<Map<string, MemoryFile>>>();\nconst ruleMemoriesByDir = new Map<string, DerivedCacheEntry<{ all: MemoryFile[]; byId: Map<string, MemoryFile> }>>();\n\n/** Get a pre-filtered Map of episode memories (keyed by ID). Derived from hot cache. */\nexport function getCachedEpisodeMap(baseDir: string, currentVersion: number): Map<string, MemoryFile> | null {\n if (currentVersion === 0) return null;\n const entry = episodeMapByDir.get(baseDir);\n if (!entry || entry.sourceVersion !== currentVersion) return null;\n return entry.data;\n}\n\n/** Build and cache the episode memory map from the full memory list. */\nexport function setCachedEpisodeMap(baseDir: string, memories: MemoryFile[], version: number): Map<string, MemoryFile> {\n const map = new Map<string, MemoryFile>();\n for (const m of memories) {\n if (m.frontmatter.status === \"archived\") continue;\n if (m.frontmatter.memoryKind !== \"episode\") continue;\n map.set(m.frontmatter.id, m);\n }\n episodeMapByDir.set(baseDir, { data: map, sourceVersion: version });\n return map;\n}\n\n/** Get pre-filtered rule memories. Derived from hot cache. */\nexport function getCachedRuleMemories(baseDir: string, currentVersion: number): { all: MemoryFile[]; byId: Map<string, MemoryFile> } | null {\n if (currentVersion === 0) return null;\n const entry = ruleMemoriesByDir.get(baseDir);\n if (!entry || entry.sourceVersion !== currentVersion) return null;\n return entry.data;\n}\n\n/** Build and cache the rule memories from the full memory list. */\nexport function setCachedRuleMemories(baseDir: string, memories: MemoryFile[], version: number): { all: MemoryFile[]; byId: Map<string, MemoryFile> } {\n const byId = new Map<string, MemoryFile>();\n const all: MemoryFile[] = [];\n for (const m of memories) {\n byId.set(m.frontmatter.id, m);\n if (m.frontmatter.category === \"rule\" && m.frontmatter.status !== \"archived\") {\n all.push(m);\n }\n }\n const result = { all, byId };\n ruleMemoriesByDir.set(baseDir, { data: result, sourceVersion: version });\n return result;\n}\n\n// QMD search result cache — short-lived (60s TTL) to avoid stale results\n// while reducing redundant daemon calls for repeated/similar queries.\ninterface QmdCacheEntry {\n results: unknown[];\n cachedAt: number;\n}\nconst QMD_CACHE_TTL_MS = 60_000;\nconst qmdSearchCache = new Map<string, QmdCacheEntry>();\n\nexport function getCachedQmdSearch(cacheKey: string): unknown[] | null {\n const entry = qmdSearchCache.get(cacheKey);\n if (!entry) return null;\n if (Date.now() - entry.cachedAt > QMD_CACHE_TTL_MS) {\n qmdSearchCache.delete(cacheKey);\n return null;\n }\n return entry.results;\n}\n\nexport function setCachedQmdSearch(cacheKey: string, results: unknown[]): void {\n qmdSearchCache.set(cacheKey, { results, cachedAt: Date.now() });\n // Evict old entries to prevent unbounded growth\n if (qmdSearchCache.size > 200) {\n const now = Date.now();\n for (const [key, entry] of qmdSearchCache) {\n if (now - entry.cachedAt > QMD_CACHE_TTL_MS) qmdSearchCache.delete(key);\n }\n }\n}\n\nexport function clearMemoryCache(baseDir?: string): void {\n if (baseDir) {\n hotCacheByDir.delete(baseDir);\n archiveCacheByDir.delete(baseDir);\n entityCacheByDir.delete(baseDir);\n episodeMapByDir.delete(baseDir);\n ruleMemoriesByDir.delete(baseDir);\n } else {\n hotCacheByDir.clear();\n archiveCacheByDir.clear();\n entityCacheByDir.clear();\n episodeMapByDir.clear();\n ruleMemoriesByDir.clear();\n qmdSearchCache.clear();\n }\n}\n\nexport function getMemoryCacheStats(baseDir: string): {\n hotSize: number;\n archiveSize: number;\n hotVersion: number | null;\n archiveVersion: number | null;\n} {\n const hot = hotCacheByDir.get(baseDir);\n const archive = archiveCacheByDir.get(baseDir);\n return {\n hotSize: hot?.memories.size ?? 0,\n archiveSize: archive?.memories.size ?? 0,\n hotVersion: hot?.version ?? null,\n archiveVersion: archive?.version ?? null,\n };\n}\n","import { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type HygieneWarning = {\n path: string;\n bytes: number;\n budgetBytes: number;\n warnAtBytes: number;\n message: string;\n};\n\nfunction toSafeTimestamp(ts: Date): string {\n // filesystem-safe, deterministic-ish, UTC\n return ts.toISOString().replace(/[:.]/g, \"\");\n}\n\nexport async function lintWorkspaceFiles(opts: {\n workspaceDir: string;\n paths: string[];\n budgetBytes: number;\n warnRatio: number;\n}): Promise<HygieneWarning[]> {\n const warnings: HygieneWarning[] = [];\n const warnAtBytes = Math.floor(opts.budgetBytes * opts.warnRatio);\n\n for (const p of opts.paths) {\n const abs = path.isAbsolute(p) ? p : path.join(opts.workspaceDir, p);\n try {\n const st = await stat(abs);\n if (!st.isFile()) continue;\n const bytes = st.size;\n if (bytes >= warnAtBytes) {\n warnings.push({\n path: p,\n bytes,\n budgetBytes: opts.budgetBytes,\n warnAtBytes,\n message: `Bootstrap file '${p}' is approaching its budget (${bytes} bytes >= ${warnAtBytes} bytes). Consider splitting/archiving it to avoid silent truncation.`,\n });\n }\n } catch {\n // ignore missing files\n }\n }\n\n return warnings;\n}\n\nexport async function rotateMarkdownFileToArchive(opts: {\n filePath: string;\n archiveDir: string;\n archivePrefix: string;\n keepTailChars: number;\n}): Promise<{ archivedPath: string; newContent: string }> {\n const existing = await readFile(opts.filePath, \"utf-8\");\n const ts = toSafeTimestamp(new Date());\n const archiveName = `${opts.archivePrefix}-${ts}.md`;\n await mkdir(opts.archiveDir, { recursive: true });\n const archivedPath = path.join(opts.archiveDir, archiveName);\n await writeFile(archivedPath, existing, \"utf-8\");\n\n const tail =\n opts.keepTailChars > 0 && existing.length > opts.keepTailChars\n ? existing.slice(-opts.keepTailChars)\n : existing;\n\n const relLink = path.relative(path.dirname(opts.filePath), archivedPath);\n\n const newContent = [\n \"# Index\",\n \"\",\n \"This file is kept intentionally small to reduce the risk of silent truncation when OpenClaw bootstraps workspace files into the prompt.\",\n \"\",\n \"## Archives\",\n `- [${archiveName}](${relLink})`,\n \"\",\n \"## Recent Tail (for continuity)\",\n \"\",\n \"```md\",\n tail.trim(),\n \"```\",\n \"\",\n ].join(\"\\n\");\n\n return { archivedPath, newContent };\n}\n\n","const INJECTION_PATTERNS: RegExp[] = [\n /ignore\\s+(all\\s+)?(previous|prior|above)\\s+(instructions?|prompts?|context)/i,\n /forget\\s+(everything|all|previous|what)/i,\n /new\\s+(system\\s+)?prompt:/i,\n /\\[system\\]/i,\n /<\\s*system\\s*>/i,\n /you\\s+are\\s+now\\s+(?!called|named)/i,\n /disregard\\s+(all\\s+)?(previous|prior)/i,\n /override\\s+(previous\\s+)?(instructions?|prompt)/i,\n /act\\s+as\\s+(?:an?\\s+)?(?:AI|assistant|ChatGPT|GPT|Claude|LLM)\\s+(?:without|that\\s+ignores)/i,\n /do\\s+not\\s+(?:follow|obey)\\s+(?:previous|prior|your)\\s+instructions/i,\n /pretend\\s+(?:you\\s+)?(?:have\\s+no|you\\s+don.?t\\s+have)\\s+(restrictions|guidelines|rules)/i,\n];\n\nexport type SanitizeResult = {\n clean: boolean;\n text: string;\n violations: string[];\n};\n\nconst REDACTED_PLACEHOLDER = \"[content removed: possible prompt injection]\";\n\nexport function sanitizeMemoryContent(text: string): SanitizeResult {\n const source = typeof text === \"string\" ? text : \"\";\n const violations: string[] = [];\n\n for (const pattern of INJECTION_PATTERNS) {\n if (pattern.test(source)) {\n violations.push(pattern.source);\n }\n }\n\n if (violations.length === 0) {\n return { clean: true, text: source, violations: [] };\n }\n\n return {\n clean: false,\n text: REDACTED_PLACEHOLDER,\n violations,\n };\n}\n\nexport function isSafeMemoryContent(text: string): boolean {\n return sanitizeMemoryContent(text).clean;\n}\n\n","export type ReasoningEffort = \"none\" | \"low\" | \"medium\" | \"high\";\nexport type TriggerMode = \"smart\" | \"every_n\" | \"time_based\";\nexport type SignalLevel = \"none\" | \"low\" | \"medium\" | \"high\";\nexport type MemoryCategory = \"fact\" | \"preference\" | \"correction\" | \"entity\" | \"decision\" | \"relationship\" | \"principle\" | \"commitment\" | \"moment\" | \"skill\" | \"rule\";\nexport type ConsolidationAction = \"ADD\" | \"MERGE\" | \"UPDATE\" | \"INVALIDATE\" | \"SKIP\";\nexport type ConfidenceTier = \"explicit\" | \"implied\" | \"inferred\" | \"speculative\";\nexport type PrincipalFromSessionKeyMode = \"map\" | \"prefix\" | \"regex\";\nexport type RecallPlanMode = \"no_recall\" | \"minimal\" | \"full\" | \"graph_mode\";\nexport type CronRecallMode = \"all\" | \"none\" | \"allowlist\";\nexport type CronConversationRecallMode = \"auto\" | \"always\" | \"never\";\nexport type IdentityInjectionMode = \"recovery_only\" | \"minimal\" | \"full\";\nexport type CaptureMode = \"implicit\" | \"explicit\" | \"hybrid\";\nexport type MemoryOsPresetName = \"conservative\" | \"balanced\" | \"research-max\" | \"local-llm-heavy\";\nexport type ExtractionPassSource = \"base\" | \"proactive\";\n\nexport interface RecallSectionConfig {\n id: string;\n enabled?: boolean;\n maxChars?: number | null;\n maxHints?: number;\n maxSupportingFacts?: number;\n maxRelatedEntities?: number;\n consolidateTriggerLines?: number;\n consolidateTargetLines?: number;\n maxEntities?: number;\n maxResults?: number;\n recentTurns?: number;\n maxTurns?: number;\n maxTokens?: number;\n lookbackHours?: number;\n maxCount?: number;\n topK?: number;\n timeoutMs?: number;\n maxPatterns?: number;\n maxRubrics?: number;\n}\n\nexport interface RecallPipelineConfig {\n recallBudgetChars: number;\n pipeline: RecallSectionConfig[];\n}\n\nexport interface SessionObserverBandConfig {\n maxBytes: number;\n triggerDeltaBytes: number;\n triggerDeltaTokens: number;\n}\n\nexport interface FileHygieneConfig {\n enabled: boolean;\n // Lint (warn before truncation risk)\n lintEnabled: boolean;\n lintBudgetBytes: number;\n lintWarnRatio: number;\n lintPaths: string[];\n // Rotation/splitting\n rotateEnabled: boolean;\n rotateMaxBytes: number;\n rotateKeepTailChars: number;\n rotatePaths: string[];\n archiveDir: string;\n // Cadence\n runMinIntervalMs: number;\n // Optional warnings log (future-proofed)\n warningsLogEnabled: boolean;\n warningsLogPath: string;\n // Optional index file (future-proofed)\n indexEnabled: boolean;\n indexPath: string;\n}\n\nexport interface NativeKnowledgeConfig {\n enabled: boolean;\n includeFiles: string[];\n maxChunkChars: number;\n maxResults: number;\n maxChars: number;\n stateDir: string;\n obsidianVaults: NativeKnowledgeObsidianVaultConfig[];\n openclawWorkspace?: NativeKnowledgeOpenClawWorkspaceConfig;\n}\n\nexport interface NativeKnowledgeFolderRuleConfig {\n pathPrefix: string;\n namespace?: string;\n privacyClass?: string;\n}\n\nexport interface NativeKnowledgeObsidianVaultConfig {\n id: string;\n rootDir: string;\n includeGlobs: string[];\n excludeGlobs: string[];\n namespace?: string;\n privacyClass?: string;\n folderRules: NativeKnowledgeFolderRuleConfig[];\n dailyNotePatterns: string[];\n materializeBacklinks: boolean;\n}\n\nexport interface NativeKnowledgeOpenClawWorkspaceConfig {\n enabled: boolean;\n bootstrapFiles: string[];\n handoffGlobs: string[];\n dailySummaryGlobs: string[];\n automationNoteGlobs: string[];\n workspaceDocGlobs: string[];\n excludeGlobs: string[];\n sharedSafeGlobs: string[];\n}\n\nexport interface AgentAccessHttpConfig {\n enabled: boolean;\n host: string;\n port: number;\n authToken?: string;\n principal?: string;\n maxBodyBytes: number;\n}\n\nexport function confidenceTier(score: number): ConfidenceTier {\n if (score >= 0.95) return \"explicit\";\n if (score >= 0.70) return \"implied\";\n if (score >= 0.40) return \"inferred\";\n return \"speculative\";\n}\n\n/** Default TTL in days for speculative memories (auto-expire if unconfirmed) */\nexport const SPECULATIVE_TTL_DAYS = 30;\n\nexport interface PluginConfig {\n openaiApiKey: string | undefined;\n openaiBaseUrl: string | undefined;\n model: string;\n reasoningEffort: ReasoningEffort;\n triggerMode: TriggerMode;\n bufferMaxTurns: number;\n bufferMaxMinutes: number;\n consolidateEveryN: number;\n highSignalPatterns: string[];\n maxMemoryTokens: number;\n memoryOsPreset?: MemoryOsPresetName;\n qmdEnabled: boolean;\n qmdCollection: string;\n qmdMaxResults: number;\n qmdColdTierEnabled?: boolean;\n qmdColdCollection?: string;\n qmdColdMaxResults?: number;\n qmdTierMigrationEnabled: boolean;\n qmdTierDemotionMinAgeDays: number;\n qmdTierDemotionValueThreshold: number;\n qmdTierPromotionValueThreshold: number;\n qmdTierParityGraphEnabled: boolean;\n qmdTierParityHiMemEnabled: boolean;\n qmdTierAutoBackfillEnabled: boolean;\n embeddingFallbackEnabled: boolean;\n embeddingFallbackProvider: \"auto\" | \"openai\" | \"local\";\n /** Optional absolute path to qmd binary. If unset, PATH/fallback discovery is used. */\n qmdPath?: string;\n memoryDir: string;\n debug: boolean;\n identityEnabled: boolean;\n identityContinuityEnabled: boolean;\n identityInjectionMode: IdentityInjectionMode;\n identityMaxInjectChars: number;\n continuityIncidentLoggingEnabled: boolean;\n continuityAuditEnabled: boolean;\n sessionObserverEnabled?: boolean;\n sessionObserverDebounceMs?: number;\n sessionObserverBands?: SessionObserverBandConfig[];\n injectQuestions: boolean;\n commitmentDecayDays: number;\n workspaceDir: string;\n captureMode: CaptureMode;\n fileHygiene?: FileHygieneConfig;\n nativeKnowledge?: NativeKnowledgeConfig;\n agentAccessHttp: AgentAccessHttpConfig;\n // Access tracking (Phase 1A)\n accessTrackingEnabled: boolean;\n accessTrackingBufferMaxSize: number;\n // Retrieval options\n recencyWeight: number;\n boostAccessCount: boolean;\n /** Record empty recall impressions (memoryIds: []) when no memories are injected. Disabled by default. */\n recordEmptyRecallImpressions: boolean;\n // v2.2 Advanced Retrieval\n queryExpansionEnabled: boolean;\n queryExpansionMaxQueries: number;\n /** Minimum token length to consider for query expansion. */\n queryExpansionMinTokenLen: number;\n rerankEnabled: boolean;\n /** Rerank provider. \"local\" uses Local LLM only; \"cloud\" uses gateway fallback chain. */\n rerankProvider: \"local\" | \"cloud\";\n rerankMaxCandidates: number;\n rerankTimeoutMs: number;\n rerankCacheEnabled: boolean;\n rerankCacheTtlMs: number;\n feedbackEnabled: boolean;\n // v2.2 Negative Examples (safe defaults: off unless enabled)\n /** If true, allow recording negative examples and apply a soft penalty during ranking. */\n negativeExamplesEnabled: boolean;\n /** Score penalty per \"not useful\" hit (typical QMD scores ~0-1). Keep small. */\n negativeExamplesPenaltyPerHit: number;\n /** Maximum penalty applied from negative examples. */\n negativeExamplesPenaltyCap: number;\n // Chunking (Phase 2A)\n chunkingEnabled: boolean;\n chunkingTargetTokens: number;\n chunkingMinTokens: number;\n chunkingOverlapSentences: number;\n // Contradiction Detection (Phase 2B)\n contradictionDetectionEnabled: boolean;\n contradictionSimilarityThreshold: number;\n contradictionMinConfidence: number;\n contradictionAutoResolve: boolean;\n // Memory Linking (Phase 3A)\n memoryLinkingEnabled: boolean;\n // Conversation Threading (Phase 3B)\n threadingEnabled: boolean;\n threadingGapMinutes: number;\n // Memory Summarization (Phase 4A)\n summarizationEnabled: boolean;\n summarizationTriggerCount: number;\n summarizationRecentToKeep: number;\n summarizationImportanceThreshold: number;\n summarizationProtectedTags: string[];\n // Topic Extraction (Phase 4B)\n topicExtractionEnabled: boolean;\n topicExtractionTopN: number;\n // Transcript & Context Preservation (v2.0)\n // Transcript archive\n transcriptEnabled: boolean;\n transcriptRetentionDays: number;\n /** Channel types to skip from transcript logging (e.g., [\"cron\"]) */\n transcriptSkipChannelTypes: string[];\n // Transcript injection\n transcriptRecallHours: number;\n maxTranscriptTurns: number;\n maxTranscriptTokens: number;\n // Checkpoint\n checkpointEnabled: boolean;\n checkpointTurns: number;\n // Compaction reset: trigger session reset after compaction instead of continuing degraded.\n // Requires OC fork with PR #29985 (api.resetSession).\n compactionResetEnabled: boolean;\n // Hourly summaries\n hourlySummariesEnabled: boolean;\n daySummaryEnabled: boolean;\n /** If true, Engram may attempt to auto-register an hourly summary cron job (default off). */\n hourlySummaryCronAutoRegister: boolean;\n summaryRecallHours: number;\n maxSummaryCount: number;\n summaryModel: string;\n // v2.4 Extended hourly summaries\n hourlySummariesExtendedEnabled: boolean;\n hourlySummariesIncludeToolStats: boolean;\n hourlySummariesIncludeSystemMessages: boolean;\n hourlySummariesMaxTurnsPerRun: number;\n // v2.4 Conversation index (optional)\n conversationIndexEnabled: boolean;\n conversationIndexBackend: \"qmd\" | \"faiss\";\n conversationIndexQmdCollection: string;\n conversationIndexRetentionDays: number;\n conversationIndexMinUpdateIntervalMs: number;\n conversationIndexEmbedOnUpdate: boolean;\n conversationIndexFaissScriptPath?: string;\n conversationIndexFaissPythonBin?: string;\n conversationIndexFaissModelId: string;\n conversationIndexFaissIndexDir: string;\n conversationIndexFaissUpsertTimeoutMs: number;\n conversationIndexFaissSearchTimeoutMs: number;\n conversationIndexFaissHealthTimeoutMs: number;\n conversationIndexFaissMaxBatchSize: number;\n conversationIndexFaissMaxSearchK: number;\n conversationRecallTopK: number;\n conversationRecallMaxChars: number;\n conversationRecallTimeoutMs: number;\n // Evaluation harness foundation\n evalHarnessEnabled: boolean;\n evalShadowModeEnabled: boolean;\n benchmarkBaselineSnapshotsEnabled: boolean;\n benchmarkDeltaReporterEnabled: boolean;\n benchmarkStoredBaselineEnabled: boolean;\n evalStoreDir: string;\n // Objective-state memory foundation\n objectiveStateMemoryEnabled: boolean;\n objectiveStateSnapshotWritesEnabled: boolean;\n objectiveStateRecallEnabled: boolean;\n objectiveStateStoreDir: string;\n // Causal trajectory memory foundation\n causalTrajectoryMemoryEnabled: boolean;\n causalTrajectoryStoreDir: string;\n causalTrajectoryRecallEnabled: boolean;\n actionGraphRecallEnabled: boolean;\n // Trust-zone memory foundation\n trustZonesEnabled: boolean;\n quarantinePromotionEnabled: boolean;\n trustZoneStoreDir: string;\n trustZoneRecallEnabled: boolean;\n memoryPoisoningDefenseEnabled: boolean;\n memoryRedTeamBenchEnabled: boolean;\n // Harmonic retrieval foundation\n harmonicRetrievalEnabled: boolean;\n abstractionAnchorsEnabled: boolean;\n abstractionNodeStoreDir: string;\n // Episodic/semantic split foundation\n verifiedRecallEnabled: boolean;\n semanticRulePromotionEnabled: boolean;\n semanticRuleVerificationEnabled: boolean;\n semanticConsolidationEnabled: boolean;\n semanticConsolidationModel: string;\n semanticConsolidationThreshold: number;\n semanticConsolidationMinClusterSize: number;\n semanticConsolidationExcludeCategories: string[];\n semanticConsolidationIntervalHours: number;\n semanticConsolidationMaxPerRun: number;\n // Creation-memory foundation\n creationMemoryEnabled: boolean;\n memoryUtilityLearningEnabled: boolean;\n promotionByOutcomeEnabled: boolean;\n commitmentLedgerEnabled: boolean;\n commitmentLifecycleEnabled: boolean;\n commitmentStaleDays: number;\n commitmentLedgerDir: string;\n resumeBundlesEnabled: boolean;\n resumeBundleDir: string;\n workProductRecallEnabled: boolean;\n workProductLedgerDir: string;\n workTasksEnabled: boolean;\n workProjectsEnabled: boolean;\n workTasksDir: string;\n workProjectsDir: string;\n workIndexEnabled: boolean;\n workIndexDir: string;\n workTaskIndexEnabled: boolean;\n workProjectIndexEnabled: boolean;\n workIndexAutoRebuildEnabled: boolean;\n workIndexAutoRebuildDebounceMs: number;\n // Local LLM Provider (v2.1)\n localLlmEnabled: boolean;\n localLlmUrl: string;\n localLlmModel: string;\n /** Optional API key for authenticated OpenAI-compatible endpoints. */\n localLlmApiKey?: string;\n /** Additional headers for local/compatible endpoint requests. */\n localLlmHeaders?: Record<string, string>;\n /** If false, do not send Authorization header even when localLlmApiKey is set. */\n localLlmAuthHeader: boolean;\n localLlmFallback: boolean;\n /** Optional home directory override for local LLM helpers (LM Studio settings, CLI PATH). */\n localLlmHomeDir?: string;\n /** Optional absolute path to LMS CLI binary (preferred over auto-detection). */\n localLmsCliPath?: string;\n /** Optional bin directory prepended to PATH for LMS CLI execution. */\n localLmsBinDir?: string;\n /** Hard timeout for local LLM requests (ms). */\n localLlmTimeoutMs: number;\n /** Max context window for local LLM (override auto-detection). Set lower if your LLM server defaults to smaller contexts. */\n localLlmMaxContext?: number;\n // Observability\n /** If true, log slow operations (local LLM + related I/O) with durations and metadata (no content). */\n slowLogEnabled: boolean;\n /**\n * If true, include the full recalled memory text in `RecallTraceEvent.recalledContent`.\n * Disabled by default — enable only when you want external trace subscribers (e.g. Langfuse)\n * to see the exact memory context injected into each conversation turn.\n * This adds payload to trace events but does not log to files or the gateway log.\n */\n traceRecallContent: boolean;\n /** Threshold for slow operation logging (ms). */\n slowLogThresholdMs: number;\n // Extraction stability guards (P0/P1)\n extractionDedupeEnabled: boolean;\n extractionDedupeWindowMs: number;\n extractionMinChars: number;\n extractionMinUserTurns: number;\n extractionMaxTurnChars: number;\n extractionMaxFactsPerRun: number;\n extractionMaxEntitiesPerRun: number;\n extractionMaxQuestionsPerRun: number;\n extractionMaxProfileUpdatesPerRun: number;\n consolidationRequireNonZeroExtraction: boolean;\n consolidationMinIntervalMs: number;\n // QMD maintenance (debounced singleflight)\n qmdMaintenanceEnabled: boolean;\n qmdMaintenanceDebounceMs: number;\n qmdAutoEmbedEnabled: boolean;\n qmdEmbedMinIntervalMs: number;\n qmdUpdateTimeoutMs: number;\n qmdUpdateMinIntervalMs: number;\n // Local LLM resilience\n localLlmRetry5xxCount: number;\n localLlmRetryBackoffMs: number;\n localLlm400TripThreshold: number;\n localLlm400CooldownMs: number;\n // Local LLM fast tier (v9.1) — smaller model for quick ops\n localLlmFastEnabled: boolean;\n localLlmFastModel: string;\n localLlmFastUrl: string;\n localLlmFastTimeoutMs: number;\n // Gateway config for fallback AI\n gatewayConfig?: GatewayConfig;\n // Gateway model source (v9.2) — route LLM calls through gateway agent model chain\n modelSource: \"plugin\" | \"gateway\";\n gatewayAgentId: string;\n fastGatewayAgentId: string;\n\n // v3.0 Multi-agent memory (namespaces)\n namespacesEnabled: boolean;\n defaultNamespace: string;\n sharedNamespace: string;\n principalFromSessionKeyMode: PrincipalFromSessionKeyMode;\n principalFromSessionKeyRules: PrincipalRule[];\n namespacePolicies: NamespacePolicy[];\n defaultRecallNamespaces: Array<\"self\" | \"shared\">;\n cronRecallMode: CronRecallMode;\n cronRecallAllowlist: string[];\n cronRecallPolicyEnabled: boolean;\n cronRecallNormalizedQueryMaxChars: number;\n cronRecallInstructionHeavyTokenCap: number;\n cronConversationRecallMode: CronConversationRecallMode;\n autoPromoteToSharedEnabled: boolean;\n autoPromoteToSharedCategories: Array<\"fact\" | \"correction\" | \"decision\" | \"preference\">;\n autoPromoteMinConfidenceTier: ConfidenceTier;\n routingRulesEnabled: boolean;\n routingRulesStateFile: string;\n\n // v4.0 Shared-context (cross-agent shared intelligence)\n sharedContextEnabled: boolean;\n sharedContextDir?: string;\n sharedContextMaxInjectChars: number;\n crossSignalsSemanticEnabled: boolean;\n crossSignalsSemanticTimeoutMs: number;\n sharedCrossSignalSemanticEnabled?: boolean;\n sharedCrossSignalSemanticTimeoutMs?: number;\n sharedCrossSignalSemanticMaxCandidates?: number;\n\n // v5.0 Compounding engine\n compoundingEnabled: boolean;\n compoundingWeeklyCronEnabled: boolean;\n compoundingSemanticEnabled: boolean;\n compoundingSynthesisTimeoutMs: number;\n compoundingInjectEnabled: boolean;\n\n // IRC (Inductive Rule Consolidation) — preference synthesis\n ircEnabled: boolean;\n ircMaxPreferences: number;\n ircIncludeCorrections: boolean;\n ircMinConfidence: number;\n\n // CMC (Causal Memory Consolidation) — cross-session causal reasoning\n cmcEnabled: boolean;\n cmcStitchLookbackDays: number;\n cmcStitchMinScore: number;\n cmcStitchMaxEdgesPerTrajectory: number;\n cmcConsolidationEnabled: boolean;\n cmcConsolidationMinRecurrence: number;\n cmcConsolidationMinSessions: number;\n cmcConsolidationSuccessThreshold: number;\n cmcRetrievalEnabled: boolean;\n cmcRetrievalMaxDepth: number;\n cmcRetrievalMaxChars: number;\n cmcRetrievalCounterfactualBoost: number;\n cmcBehaviorLearningEnabled: boolean;\n cmcBehaviorMinFrequency: number;\n cmcBehaviorMinSessions: number;\n cmcBehaviorConfidenceThreshold: number;\n cmcLifecycleCausalImpactWeight: number;\n\n // PEDC (Prediction-Error-Driven Calibration) — model-user alignment\n calibrationEnabled: boolean;\n calibrationMaxRulesPerRecall: number;\n calibrationMaxChars: number;\n\n // Search backend abstraction\n searchBackend?: \"qmd\" | \"remote\" | \"noop\" | \"lancedb\" | \"meilisearch\" | \"orama\";\n remoteSearchBaseUrl?: string;\n remoteSearchApiKey?: string;\n remoteSearchTimeoutMs?: number;\n\n // LanceDB backend\n lancedbEnabled: boolean;\n lanceDbPath?: string;\n lanceEmbeddingDimension?: number;\n\n // Meilisearch backend\n meilisearchEnabled: boolean;\n meilisearchHost?: string;\n meilisearchApiKey?: string;\n meilisearchTimeoutMs?: number;\n meilisearchAutoIndex?: boolean;\n\n // Orama backend\n oramaEnabled: boolean;\n oramaDbPath?: string;\n oramaEmbeddingDimension?: number;\n\n // QMD daemon mode\n qmdDaemonEnabled: boolean;\n qmdDaemonUrl: string;\n qmdDaemonRecheckIntervalMs: number;\n qmdIntentHintsEnabled: boolean;\n qmdExplainEnabled: boolean;\n\n // v7.0 Knowledge Graph Enhancement\n knowledgeIndexEnabled: boolean;\n knowledgeIndexMaxEntities: number;\n knowledgeIndexMaxChars: number;\n entityRetrievalEnabled: boolean;\n entityRetrievalMaxChars: number;\n entityRetrievalMaxHints: number;\n entityRetrievalMaxSupportingFacts: number;\n entityRetrievalMaxRelatedEntities: number;\n entityRetrievalRecentTurns: number;\n // Recall assembly controls\n recallBudgetChars: number;\n recallOuterTimeoutMs: number;\n recallCoreDeadlineMs: number;\n recallEnrichmentDeadlineMs: number;\n recallPipeline: RecallSectionConfig[];\n qmdRecallCacheTtlMs: number;\n qmdRecallCacheStaleTtlMs: number;\n qmdRecallCacheMaxEntries: number;\n entityRelationshipsEnabled: boolean;\n entityActivityLogEnabled: boolean;\n entityActivityLogMaxEntries: number;\n entityAliasesEnabled: boolean;\n entitySummaryEnabled: boolean;\n\n // v6.0 Fact deduplication & archival\n /** Enable content-hash deduplication to prevent storing semantically identical facts. */\n factDeduplicationEnabled: boolean;\n /** Enable automatic archival of old, low-importance, rarely-accessed facts. */\n factArchivalEnabled: boolean;\n /** Minimum age in days before a fact is eligible for archival. */\n factArchivalAgeDays: number;\n /** Maximum importance score for archival eligibility (0-1). Only facts below this are archived. */\n factArchivalMaxImportance: number;\n /** Maximum access count for archival eligibility. Only rarely-accessed facts are archived. */\n factArchivalMaxAccessCount: number;\n /** Tags that protect a fact from archival regardless of other criteria. */\n factArchivalProtectedCategories: string[];\n // v8.3 Lifecycle policy engine\n lifecyclePolicyEnabled: boolean;\n lifecycleFilterStaleEnabled: boolean;\n lifecyclePromoteHeatThreshold: number;\n lifecycleStaleDecayThreshold: number;\n lifecycleArchiveDecayThreshold: number;\n lifecycleProtectedCategories: MemoryCategory[];\n lifecycleMetricsEnabled: boolean;\n // v8.3 proactive + policy learning\n proactiveExtractionEnabled: boolean;\n contextCompressionActionsEnabled: boolean;\n compressionGuidelineLearningEnabled: boolean;\n compressionGuidelineSemanticRefinementEnabled: boolean;\n compressionGuidelineSemanticTimeoutMs: number;\n maxProactiveQuestionsPerExtraction: number;\n proactiveExtractionTimeoutMs: number;\n proactiveExtractionMaxTokens: number;\n extractionMaxOutputTokens: number;\n proactiveExtractionCategoryAllowlist?: MemoryCategory[];\n maxCompressionTokensPerHour: number;\n behaviorLoopAutoTuneEnabled: boolean;\n behaviorLoopLearningWindowDays: number;\n behaviorLoopMinSignalCount: number;\n behaviorLoopMaxDeltaPerCycle: number;\n behaviorLoopProtectedParams: string[];\n // v8.0 Phase 1: recall planner + intent routing + verbatim artifacts\n recallPlannerEnabled: boolean;\n recallPlannerModel: string;\n recallPlannerTimeoutMs: number;\n recallPlannerUseResponsesApi: boolean;\n recallPlannerMaxPromptChars: number;\n recallPlannerMaxMemoryHints: number;\n recallPlannerShadowMode: boolean;\n recallPlannerTelemetryEnabled: boolean;\n recallPlannerMaxQmdResultsMinimal: number;\n recallPlannerMaxQmdResultsFull: number;\n intentRoutingEnabled: boolean;\n intentRoutingBoost: number;\n verbatimArtifactsEnabled: boolean;\n verbatimArtifactsMinConfidence: number;\n verbatimArtifactsMaxRecall: number;\n verbatimArtifactCategories: MemoryCategory[];\n // v8.0 Phase 2A: Memory Boxes + Trace Weaving\n memoryBoxesEnabled: boolean;\n /** Jaccard overlap threshold below which a topic shift triggers box sealing (0-1, default 0.35) */\n boxTopicShiftThreshold: number;\n /** Time gap in ms before an open box is sealed (default 30 min) */\n boxTimeGapMs: number;\n /** Max memories per box before forced seal */\n boxMaxMemories: number;\n traceWeaverEnabled: boolean;\n /** Days back to search for trace links */\n traceWeaverLookbackDays: number;\n /** Minimum Jaccard overlap to assign the same traceId (0-1, default 0.4) */\n traceWeaverOverlapThreshold: number;\n /** Number of recent days of boxes to inject during recall */\n boxRecallDays: number;\n // v8.0 Phase 2B: Episode/Note dual store (HiMem)\n /** Classify extracted memories as episode or note and tag with memoryKind */\n episodeNoteModeEnabled: boolean;\n // v8.1 Temporal + Tag Indexes (SwiftMem-inspired)\n /** Build and maintain temporal (state/index_time.json) and tag (state/index_tags.json) indexes */\n queryAwareIndexingEnabled: boolean;\n /** Max candidate paths returned from index prefilter (0 = no cap) */\n queryAwareIndexingMaxCandidates: number;\n temporalIndexWindowDays: number;\n temporalIndexMaxEntries: number;\n temporalBoostRecentDays: number;\n temporalBoostScore: number;\n temporalDecayEnabled: boolean;\n tagMemoryEnabled: boolean;\n tagMaxPerMemory: number;\n tagIndexMaxEntries: number;\n tagRecallBoost: number;\n tagRecallMaxMatches: number;\n // v8.2 multi-graph memory (PR 18)\n multiGraphMemoryEnabled: boolean;\n // v8.2 PR 19A: graph recall planner gating\n graphRecallEnabled: boolean;\n graphRecallMaxExpansions: number;\n graphRecallMaxPerSeed: number;\n graphRecallMinEdgeWeight: number;\n graphRecallShadowEnabled: boolean;\n graphRecallSnapshotEnabled: boolean;\n graphRecallShadowSampleRate: number;\n graphRecallExplainToolEnabled: boolean;\n graphRecallStoreColdMirror: boolean;\n graphRecallColdMirrorCollection?: string;\n graphRecallColdMirrorMinAgeDays: number;\n graphRecallUseEntityPriors: boolean;\n graphRecallEntityPriorBoost: number;\n graphRecallPreferHubSeeds: boolean;\n graphRecallHubBias: number;\n graphRecallRecencyHalfLifeDays: number;\n graphRecallDampingFactor: number;\n graphRecallMaxSeedNodes: number;\n graphRecallMaxExpandedNodes: number;\n graphRecallMaxTrailPerNode: number;\n graphRecallMinSeedScore: number;\n graphRecallExpansionScoreThreshold: number;\n graphRecallExplainMaxPaths: number;\n graphRecallExplainMaxChars: number;\n graphRecallExplainEdgeLimit: number;\n graphRecallExplainEnabled: boolean;\n graphRecallEntityHintsEnabled: boolean;\n graphRecallEntityHintMax: number;\n graphRecallEntityHintMaxChars: number;\n graphRecallSnapshotDir: string;\n graphRecallEnableTrace: boolean;\n graphRecallEnableDebug: boolean;\n /** Allow graph_mode escalation for broader causal/timeline phrasing beyond strict keywords. */\n graphExpandedIntentEnabled?: boolean;\n /** Run bounded graph expansion in full mode when enough recall seeds exist. */\n graphAssistInFullModeEnabled?: boolean;\n /** In full mode, compute graph assist for telemetry/snapshotting but do not inject merged results. */\n graphAssistShadowEvalEnabled?: boolean;\n /** Minimum seed results required before full-mode graph assist runs. */\n graphAssistMinSeedResults?: number;\n entityGraphEnabled: boolean;\n timeGraphEnabled: boolean;\n /** When true, write fallback temporal adjacency edges for consecutive extracted memories. */\n graphWriteSessionAdjacencyEnabled?: boolean;\n causalGraphEnabled: boolean;\n maxGraphTraversalSteps: number;\n graphActivationDecay: number;\n /** Weight of graph activation score when blending with seed QMD score (0-1). */\n graphExpansionActivationWeight: number;\n /** Lower bound for blended graph-expanded recall scores (0-1). */\n graphExpansionBlendMin: number;\n /** Upper bound for blended graph-expanded recall scores (0-1). */\n graphExpansionBlendMax: number;\n maxEntityGraphEdgesPerMemory: number;\n /** SimpleMem-inspired de-linearization: resolve pronouns and anchor relative dates after extraction. */\n delinearizeEnabled: boolean;\n /** Synapse-inspired confidence gate — skip memory injection when top score is below threshold. */\n recallConfidenceGateEnabled: boolean;\n recallConfidenceGateThreshold: number;\n /** PlugMem-inspired causal rule extraction: mine IF→THEN rules during consolidation. */\n causalRuleExtractionEnabled: boolean;\n /** E-Mem-inspired memory reconstruction: targeted retrieval for missing entity context. */\n memoryReconstructionEnabled: boolean;\n /** Maximum number of entity expansions per recall. */\n memoryReconstructionMaxExpansions: number;\n /** Synapse-inspired lateral inhibition to suppress hub-node dominance. */\n graphLateralInhibitionEnabled: boolean;\n /** Inhibition strength (default 0.15). Higher = more suppression. */\n graphLateralInhibitionBeta: number;\n /** Number of top competing nodes considered for inhibition (default 7). */\n graphLateralInhibitionTopM: number;\n // v8.2: Temporal Memory Tree\n temporalMemoryTreeEnabled: boolean;\n tmtHourlyMinMemories: number;\n tmtSummaryMaxTokens: number;\n // Lossless Context Management (LCM)\n lcmEnabled: boolean;\n lcmLeafBatchSize: number;\n lcmRollupFanIn: number;\n lcmFreshTailTurns: number;\n lcmMaxDepth: number;\n lcmRecallBudgetShare: number;\n lcmDeterministicMaxTokens: number;\n lcmArchiveRetentionDays: number;\n\n // v9.1 Parallel Specialized Retrieval (ASMR-inspired)\n /** Enable three-agent parallel retrieval (DirectFact + Contextual + Temporal). Default false. */\n parallelRetrievalEnabled: boolean;\n /** Per-agent source weights for score blending during merge. */\n parallelAgentWeights: { direct: number; contextual: number; temporal: number };\n /** Max results fetched per agent before merge. */\n parallelMaxResultsPerAgent: number;\n}\n\nexport interface BootstrapOptions {\n dryRun?: boolean;\n sessionsDir?: string;\n limit?: number;\n since?: Date;\n}\n\nexport interface BootstrapResult {\n sessionsScanned: number;\n turnsProcessed: number;\n highSignalTurns: number;\n memoriesCreated: number;\n skipped: number;\n}\n\nexport interface PrincipalRule {\n match: string;\n principal: string;\n}\n\nexport interface NamespacePolicy {\n name: string;\n readPrincipals: string[];\n writePrincipals: string[];\n includeInRecallByDefault?: boolean;\n}\n\nexport interface RelevanceFeedback {\n up: number;\n down: number;\n lastUpdatedAt: string;\n notes?: string[];\n}\n\nexport interface BufferTurn {\n role: \"user\" | \"assistant\";\n content: string;\n timestamp: string;\n sessionKey?: string;\n}\n\nexport interface BufferState {\n turns: BufferTurn[];\n lastExtractionAt: string | null;\n extractionCount: number;\n}\n\nexport interface BehaviorLoopAdjustment {\n parameter: string;\n previousValue: number;\n nextValue: number;\n delta: number;\n evidenceCount: number;\n confidence: number;\n reason: string;\n appliedAt: string;\n}\n\nexport interface BehaviorLoopPolicyState {\n version: number;\n windowDays: number;\n minSignalCount: number;\n maxDeltaPerCycle: number;\n protectedParams: string[];\n adjustments: BehaviorLoopAdjustment[];\n updatedAt: string;\n}\n\nexport type BehaviorSignalType = \"correction_override\" | \"preference_affinity\" | \"topic_revisitation\" | \"action_pattern\" | \"outcome_preference\" | \"phrasing_style\";\nexport type BehaviorSignalDirection = \"positive\" | \"negative\";\n\nexport interface BehaviorSignalEvent {\n timestamp: string;\n namespace: string;\n memoryId: string;\n category: Extract<MemoryCategory, \"correction\" | \"preference\">;\n signalType: BehaviorSignalType;\n direction: BehaviorSignalDirection;\n confidence: number;\n signalHash: string;\n source: \"extraction\" | \"correction\";\n}\n\n/** Memory status for lifecycle management */\nexport type MemoryStatus = \"active\" | \"pending_review\" | \"rejected\" | \"quarantined\" | \"superseded\" | \"archived\";\nexport type LifecycleState = \"candidate\" | \"validated\" | \"active\" | \"stale\" | \"archived\";\nexport type VerificationState = \"unverified\" | \"user_confirmed\" | \"system_inferred\" | \"disputed\";\nexport type PolicyClass = \"ephemeral\" | \"durable\" | \"protected\";\n\n/** Importance level tiers */\nexport type ImportanceLevel = \"critical\" | \"high\" | \"normal\" | \"low\" | \"trivial\";\n\n/** Importance scoring result */\nexport interface ImportanceScore {\n /** Numeric score 0-1 */\n score: number;\n /** Tier level */\n level: ImportanceLevel;\n /** Reasons for this score */\n reasons: string[];\n /** Salient keywords extracted */\n keywords: string[];\n}\n\nexport interface MemoryFrontmatter {\n id: string;\n category: MemoryCategory;\n created: string;\n updated: string;\n source: string;\n confidence: number;\n confidenceTier: ConfidenceTier;\n tags: string[];\n entityRef?: string;\n supersedes?: string;\n /** ISO 8601 date — memory expires and gets cleaned up after this date */\n expiresAt?: string;\n /** IDs of parent memories this was derived from (lineage tracking) */\n lineage?: string[];\n /** Memory status: active (default), pending_review, rejected, quarantined, superseded, or archived */\n status?: MemoryStatus;\n /** ID of memory that superseded this one */\n supersededBy?: string;\n /** Timestamp when superseded */\n supersededAt?: string;\n /** Timestamp when archived */\n archivedAt?: string;\n /** Policy-driven lifecycle state used for retrieval eligibility/ranking. */\n lifecycleState?: LifecycleState;\n /** Verification provenance used by lifecycle policy. */\n verificationState?: VerificationState;\n /** Policy class used by lifecycle guardrails. */\n policyClass?: PolicyClass;\n /** Last lifecycle validation timestamp (ISO 8601). */\n lastValidatedAt?: string;\n /** Lifecycle decay score in [0,1]. */\n decayScore?: number;\n /** Lifecycle heat score in [0,1]. */\n heatScore?: number;\n // Access tracking (Phase 1A)\n /** Number of times this memory has been retrieved */\n accessCount?: number;\n /** Last time this memory was accessed (ISO 8601) */\n lastAccessed?: string;\n // Importance scoring (Phase 1B)\n /** Importance score with level, reasons, and keywords */\n importance?: ImportanceScore;\n // Chunking (Phase 2A)\n /** Parent memory ID if this is a chunk */\n parentId?: string;\n /** Chunk index within parent (0-based) */\n chunkIndex?: number;\n /** Total number of chunks for this parent */\n chunkTotal?: number;\n // Memory Linking (Phase 3A)\n /** Links to other memories */\n links?: MemoryLink[];\n // Intent-grounded memory routing (v8.0 phase 1)\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n // Verbatim artifact lineage (v8.0 phase 1)\n artifactType?: \"decision\" | \"constraint\" | \"todo\" | \"definition\" | \"commitment\" | \"correction\" | \"fact\";\n sourceMemoryId?: string;\n sourceTurnId?: string;\n // v8.0 Phase 2B: HiMem episode/note classification\n /** episode = time-specific event; note = stable belief/preference/decision */\n memoryKind?: \"episode\" | \"note\";\n /** Structured key-value attributes extracted from the content (e.g., product attributes, dates, quantities). */\n structuredAttributes?: Record<string, string>;\n}\n\n/** Memory link relationship types */\nexport type MemoryLinkType = \"follows\" | \"references\" | \"contradicts\" | \"supports\" | \"related\";\n\n/** A link between memories */\nexport interface MemoryLink {\n targetId: string;\n linkType: MemoryLinkType;\n strength: number;\n reason?: string;\n}\n\n// Conversation Threading (Phase 3B)\nexport interface ConversationThread {\n id: string;\n title: string;\n createdAt: string;\n updatedAt: string;\n sessionKey?: string;\n episodeIds: string[];\n linkedThreadIds: string[];\n}\n\n// Memory Summarization (Phase 4A)\nexport interface MemorySummary {\n id: string;\n createdAt: string;\n timeRangeStart: string;\n timeRangeEnd: string;\n summaryText: string;\n keyFacts: string[];\n keyEntities: string[];\n sourceEpisodeIds: string[];\n}\n\nexport interface DaySummaryResult {\n summary: string;\n bullets: string[];\n next_actions: string[];\n risks_or_open_loops: string[];\n}\n\n// Topic Extraction (Phase 4B)\nexport interface TopicScore {\n term: string;\n score: number;\n count: number;\n}\n\nexport interface MemoryFile {\n path: string;\n frontmatter: MemoryFrontmatter;\n content: string;\n}\n\nexport interface ExtractedFact {\n category: MemoryCategory;\n content: string;\n confidence: number;\n tags: string[];\n entityRef?: string;\n source?: ExtractionPassSource;\n promptedByQuestion?: string;\n /** Structured key-value attributes extracted from the content (e.g., product attributes, dates, quantities). */\n structuredAttributes?: Record<string, string>;\n}\n\nexport interface MemoryIntent {\n goal: string;\n actionType: string;\n entityTypes: string[];\n}\n\nexport interface ExtractedQuestion {\n question: string;\n context: string;\n priority: number;\n}\n\nexport interface QuestionEntry {\n id: string;\n question: string;\n context: string;\n priority: number; // 0-1, higher = more important\n created: string;\n resolved: boolean;\n resolvedAt?: string;\n}\n\nexport interface ExtractionResult {\n facts: ExtractedFact[];\n profileUpdates: string[];\n entities: EntityMention[];\n questions: ExtractedQuestion[];\n identityReflection?: string;\n relationships?: ExtractedRelationship[];\n}\n\nexport interface EntityMention {\n name: string;\n type: \"person\" | \"project\" | \"tool\" | \"company\" | \"place\" | \"other\";\n facts: string[];\n source?: ExtractionPassSource;\n promptedByQuestion?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Knowledge Graph Enhancement (Entity Relationships, Activity, Scoring)\n// ---------------------------------------------------------------------------\n\nexport interface EntityRelationship {\n target: string;\n label: string;\n}\n\nexport interface EntityActivityEntry {\n date: string;\n note: string;\n}\n\nexport interface EntityFile {\n name: string;\n type: string;\n updated: string;\n facts: string[];\n summary?: string;\n relationships: EntityRelationship[];\n activity: EntityActivityEntry[];\n aliases: string[];\n}\n\nexport interface ScoredEntity {\n name: string;\n type: string;\n score: number;\n factCount: number;\n summary?: string;\n topRelationships: string[];\n}\n\nexport interface ExtractedRelationship {\n source: string;\n target: string;\n label: string;\n extractionSource?: ExtractionPassSource;\n promptedByQuestion?: string;\n}\n\nexport interface ConsolidationItem {\n existingId: string;\n action: ConsolidationAction;\n mergeWith?: string;\n updatedContent?: string;\n reason: string;\n}\n\nexport interface ConsolidationResult {\n items: ConsolidationItem[];\n profileUpdates: string[];\n entityUpdates: EntityMention[];\n}\n\nexport interface QmdSearchResult {\n docid: string;\n path: string;\n snippet: string;\n score: number;\n explain?: QmdSearchExplain;\n transport?: \"daemon\" | \"subprocess\" | \"hybrid\" | \"scoped_prefilter\";\n}\n\nexport interface QmdSearchExplain {\n ftsScores?: number[];\n vectorScores?: number[];\n rrf?: number;\n rerankScore?: number;\n blendedScore?: number;\n}\n\nexport interface MetaState {\n extractionCount: number;\n lastExtractionAt: string | null;\n lastConsolidationAt: string | null;\n totalMemories: number;\n totalEntities: number;\n}\n\nexport type MemoryActionType =\n | \"store_episode\"\n | \"store_note\"\n | \"update_note\"\n | \"create_artifact\"\n | \"summarize_node\"\n | \"discard\"\n | \"link_graph\";\n\nexport type MemoryActionOutcome = \"applied\" | \"skipped\" | \"failed\";\n\nexport type MemoryActionPolicyDecision = \"allow\" | \"defer\" | \"deny\";\n\nexport type MemoryActionStatus = \"validated\" | \"applied\" | \"rejected\";\n\nexport type MemoryActionEligibilitySource =\n | \"extraction\"\n | \"consolidation\"\n | \"replay\"\n | \"manual\"\n | \"unknown\";\n\nexport interface MemoryActionEligibilityContext {\n confidence: number;\n lifecycleState: LifecycleState;\n importance: number;\n source: MemoryActionEligibilitySource;\n}\n\nexport interface MemoryActionPolicyResult {\n action: MemoryActionType;\n decision: MemoryActionPolicyDecision;\n rationale: string;\n eligibility: MemoryActionEligibilityContext;\n}\n\nexport interface MemoryActionEvent {\n schemaVersion?: number;\n actionId?: string;\n timestamp: string;\n action: MemoryActionType;\n outcome: MemoryActionOutcome;\n status?: MemoryActionStatus;\n actor?: string;\n subsystem?: string;\n reason?: string;\n memoryId?: string;\n namespace?: string;\n sessionKey?: string;\n sourceSessionKey?: string;\n checkpointCapturedAt?: string;\n checkpointTtl?: string;\n checkpointTurnCount?: number;\n inputSummary?: string;\n outputMemoryIds?: string[];\n dryRun?: boolean;\n policyVersion?: string;\n promptHash?: string;\n policyDecision?: MemoryActionPolicyDecision;\n policyRationale?: string;\n policyEligibility?: MemoryActionEligibilityContext;\n}\n\nexport type MemoryLifecycleEventType =\n | \"created\"\n | \"updated\"\n | \"superseded\"\n | \"archived\"\n | \"rejected\"\n | \"restored\"\n | \"merged\"\n | \"imported\"\n | \"promoted\"\n | \"explicit_capture_accepted\"\n | \"explicit_capture_queued\";\n\nexport interface MemoryLifecycleStateSummary {\n category?: MemoryCategory;\n path?: string;\n status?: MemoryStatus;\n lifecycleState?: LifecycleState;\n}\n\nexport interface MemoryLifecycleEvent {\n eventId: string;\n memoryId: string;\n eventType: MemoryLifecycleEventType;\n timestamp: string;\n actor: string;\n reasonCode?: string;\n ruleVersion: string;\n relatedMemoryIds?: string[];\n before?: MemoryLifecycleStateSummary;\n after?: MemoryLifecycleStateSummary;\n correlationId?: string;\n}\n\nexport interface MemoryProjectionCurrentState {\n memoryId: string;\n category: MemoryCategory;\n status: MemoryStatus;\n lifecycleState?: LifecycleState;\n path: string;\n pathRel: string;\n created: string;\n updated: string;\n archivedAt?: string;\n supersededAt?: string;\n entityRef?: string;\n source: string;\n confidence: number;\n confidenceTier: ConfidenceTier;\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n accessCount?: number;\n lastAccessed?: string;\n tags?: string[];\n preview?: string;\n}\n\nexport interface CompressionGuidelineOptimizerSourceWindow {\n from: string;\n to: string;\n}\n\nexport interface CompressionGuidelineOptimizerEventCounts {\n total: number;\n applied: number;\n skipped: number;\n failed: number;\n}\n\nexport type CompressionGuidelineActivationState = \"draft\" | \"active\";\n\nexport interface CompressionGuidelineOptimizerActionSummary {\n action: MemoryActionType;\n total: number;\n outcomes: Record<MemoryActionOutcome, number>;\n quality: {\n good: number;\n poor: number;\n unknown: number;\n };\n}\n\nexport interface CompressionGuidelineOptimizerRuleUpdate {\n action: MemoryActionType;\n delta: number;\n direction: \"increase\" | \"decrease\" | \"hold\";\n confidence: \"low\" | \"medium\" | \"high\";\n notes: string[];\n}\n\nexport interface CompressionGuidelineOptimizerState {\n version: number;\n updatedAt: string;\n sourceWindow: CompressionGuidelineOptimizerSourceWindow;\n eventCounts: CompressionGuidelineOptimizerEventCounts;\n guidelineVersion: number;\n contentHash?: string;\n activationState?: CompressionGuidelineActivationState;\n actionSummaries?: CompressionGuidelineOptimizerActionSummary[];\n ruleUpdates?: CompressionGuidelineOptimizerRuleUpdate[];\n}\n\nexport type ContinuityIncidentState = \"open\" | \"closed\";\n\nexport interface ContinuityIncidentRecord {\n id: string;\n state: ContinuityIncidentState;\n openedAt: string;\n updatedAt: string;\n triggerWindow?: string;\n symptom: string;\n suspectedCause?: string;\n fixApplied?: string;\n verificationResult?: string;\n preventiveRule?: string;\n closedAt?: string;\n filePath?: string;\n}\n\nexport interface ContinuityIncidentOpenInput {\n triggerWindow?: string;\n symptom: string;\n suspectedCause?: string;\n}\n\nexport interface ContinuityIncidentCloseInput {\n fixApplied: string;\n verificationResult: string;\n preventiveRule?: string;\n}\n\nexport type ContinuityLoopCadence = \"daily\" | \"weekly\" | \"monthly\" | \"quarterly\";\nexport type ContinuityLoopStatus = \"active\" | \"paused\" | \"retired\";\n\nexport interface ContinuityImprovementLoop {\n id: string;\n cadence: ContinuityLoopCadence;\n purpose: string;\n status: ContinuityLoopStatus;\n killCondition: string;\n lastReviewed: string;\n notes?: string;\n}\n\nexport interface ContinuityLoopUpsertInput {\n id: string;\n cadence: ContinuityLoopCadence;\n purpose: string;\n status: ContinuityLoopStatus;\n killCondition: string;\n lastReviewed?: string;\n notes?: string;\n}\n\nexport interface ContinuityLoopReviewInput {\n status?: ContinuityLoopStatus;\n notes?: string;\n reviewedAt?: string;\n}\n\n/** Entry in the access tracking buffer (batched updates) */\nexport interface AccessTrackingEntry {\n memoryId: string;\n newCount: number;\n lastAccessed: string;\n}\n\nexport interface SignalScanResult {\n level: SignalLevel;\n patterns: string[];\n}\n\n// ============================================================================\n// LLM Trace Callback (for external observability plugins)\n// ============================================================================\n\nexport interface LlmTraceEvent {\n kind: \"llm_start\" | \"llm_end\" | \"llm_error\";\n traceId: string;\n model: string;\n operation: \"extraction\" | \"consolidation\" | \"profile_consolidation\" | \"identity_consolidation\" | \"day_summary\";\n input?: string;\n output?: string;\n durationMs?: number;\n error?: string;\n tokenUsage?: { input?: number; output?: number; total?: number };\n}\n\nexport interface RecallTraceEvent {\n kind: \"recall_summary\";\n traceId: string;\n operation: \"recall\";\n sessionKey?: string;\n promptHash: string;\n promptLength: number;\n retrievalQueryHash: string;\n retrievalQueryLength: number;\n recallMode: RecallPlanMode;\n recallResultLimit: number;\n qmdEnabled: boolean;\n qmdAvailable: boolean;\n recallNamespaces: string[];\n source: \"none\" | \"hot_qmd\" | \"hot_embedding\" | \"cold_fallback\" | \"recent_scan\";\n recalledMemoryCount: number;\n injected: boolean;\n contextChars: number;\n policyVersion?: string;\n identityInjectionMode?: IdentityInjectionMode | \"none\";\n identityInjectedChars?: number;\n identityInjectionTruncated?: boolean;\n durationMs: number;\n timings?: Record<string, string>;\n /**\n * The full recalled memory context injected into the system prompt.\n * Only populated when `traceRecallContent` config option is `true`.\n * Omitted by default to avoid sending potentially sensitive memory content\n * to external trace collectors unless explicitly opted in.\n */\n recalledContent?: string;\n}\n\nexport type EngramTraceEvent = LlmTraceEvent | RecallTraceEvent;\nexport type LlmTraceCallback = (event: EngramTraceEvent) => void;\n\n// ============================================================================\n// Gateway Configuration Types (for fallback AI)\n// ============================================================================\n\nexport type ModelApi = \"openai-completions\" | \"anthropic-messages\" | \"google-generative\" | string;\n\nexport type ModelProviderAuthMode = \"bearer\" | \"header\" | \"query\";\n\nexport interface ModelDefinitionConfig {\n id: string;\n name?: string;\n contextWindow?: number;\n maxOutputTokens?: number;\n costPer1MInput?: number;\n costPer1MOutput?: number;\n aliases?: string[];\n}\n\nexport interface ModelProviderConfig {\n baseUrl: string;\n apiKey?: string | Record<string, unknown>;\n auth?: ModelProviderAuthMode;\n api?: ModelApi;\n headers?: Record<string, string>;\n authHeader?: boolean;\n models: ModelDefinitionConfig[];\n}\n\nexport interface AgentDefaultsConfig {\n model?: {\n primary?: string;\n backup?: string;\n fallbacks?: string[];\n };\n thinking?: {\n mode?: \"off\" | \"on\" | \"adaptive\";\n budget?: number;\n };\n}\n\nexport interface AgentPersonaModelConfig {\n primary?: string;\n fallbacks?: string[];\n}\n\nexport interface AgentPersona {\n id: string;\n name?: string;\n model?: AgentPersonaModelConfig;\n}\n\nexport interface GatewayConfig {\n agents?: {\n defaults?: AgentDefaultsConfig;\n list?: AgentPersona[];\n };\n models?: {\n providers?: Record<string, ModelProviderConfig>;\n };\n auth?: {\n profiles?: Record<string, unknown>;\n };\n}\n\n// ============================================================================\n// Transcript & Context Preservation (v2.0)\n// ============================================================================\n\nexport interface TranscriptEntry {\n timestamp: string;\n role: \"user\" | \"assistant\";\n content: string;\n sessionKey: string;\n turnId: string;\n metadata?: {\n compactAfter?: boolean;\n compactionId?: string | null;\n };\n}\n\nexport interface Checkpoint {\n sessionKey: string;\n capturedAt: string;\n turns: TranscriptEntry[];\n ttl: string; // ISO timestamp when checkpoint expires\n}\n\nexport interface HourlySummary {\n hour: string; // \"2026-02-08T14:00:00Z\"\n sessionKey: string;\n bullets: string[];\n turnCount: number;\n generatedAt: string;\n}\n","import path from \"node:path\";\nimport { readFileSync } from \"node:fs\";\nimport Database from \"better-sqlite3\";\nimport type {\n MemoryGovernanceAppliedAction,\n MemoryGovernanceMetrics,\n MemoryGovernanceReviewQueueEntry,\n MemoryGovernanceSummary,\n} from \"./maintenance/memory-governance.js\";\nimport type {\n MemoryCategory,\n MemoryLifecycleEvent,\n MemoryProjectionCurrentState,\n MemoryStatus,\n} from \"./types.js\";\n\nexport const MEMORY_PROJECTION_SCHEMA_VERSION = 2;\n\nexport interface ProjectedMemoryBrowseOptions {\n query?: string;\n status?: string;\n category?: string;\n sort?: \"updated_desc\" | \"updated_asc\" | \"created_desc\" | \"created_asc\";\n limit: number;\n offset: number;\n}\n\nexport interface ProjectedMemoryBrowseRow {\n id: string;\n path: string;\n category: MemoryCategory;\n status: MemoryStatus;\n created?: string;\n updated?: string;\n tags: string[];\n entityRef?: string;\n preview: string;\n}\n\nexport interface ProjectedMemoryBrowsePage {\n total: number;\n memories: ProjectedMemoryBrowseRow[];\n}\n\nexport interface ProjectedEntityMentionRow {\n memoryId: string;\n entityRef: string;\n mentionSource: string;\n created: string;\n updated: string;\n}\n\nexport interface ProjectedNativeKnowledgeChunkRow {\n chunkId: string;\n sourcePath: string;\n title: string;\n sourceKind: string;\n startLine: number;\n endLine: number;\n derivedDate?: string;\n sessionKey?: string;\n workflowKey?: string;\n author?: string;\n agent?: string;\n namespace?: string;\n privacyClass?: string;\n sourceHash?: string;\n preview: string;\n}\n\nexport interface MemoryProjectionGovernanceReviewQueueRow {\n runId: string;\n entryId: string;\n memoryId: string;\n path: string;\n reasonCode: MemoryGovernanceReviewQueueEntry[\"reasonCode\"];\n severity: MemoryGovernanceReviewQueueEntry[\"severity\"];\n suggestedAction: MemoryGovernanceReviewQueueEntry[\"suggestedAction\"];\n suggestedStatus?: MemoryGovernanceReviewQueueEntry[\"suggestedStatus\"];\n relatedMemoryIds: string[];\n}\n\nexport interface MemoryProjectionGovernanceAppliedActionRow {\n runId: string;\n rowKey: string;\n action: MemoryGovernanceAppliedAction[\"action\"];\n memoryId: string;\n reasonCode: MemoryGovernanceAppliedAction[\"reasonCode\"];\n beforeStatus: MemoryGovernanceAppliedAction[\"beforeStatus\"];\n afterStatus?: MemoryGovernanceAppliedAction[\"afterStatus\"];\n originalPath: string;\n currentPath: string;\n}\n\nexport interface ProjectedReviewQueueSnapshot {\n found: boolean;\n runId?: string;\n summary?: MemoryGovernanceSummary;\n metrics?: MemoryGovernanceMetrics;\n reviewQueue?: MemoryGovernanceReviewQueueEntry[];\n appliedActions?: MemoryGovernanceAppliedAction[];\n report?: string;\n}\n\nexport function getMemoryProjectionPath(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"memory-projection.sqlite\");\n}\n\nfunction listTableColumns(db: Database.Database, tableName: string): Set<string> {\n try {\n const rows = db.prepare(`PRAGMA table_info(${tableName})`).all() as Array<{ name?: unknown }>;\n return new Set(rows.map((row) => row.name).filter((name): name is string => typeof name === \"string\"));\n } catch {\n return new Set<string>();\n }\n}\n\nfunction migrateMemoryCurrentTable(db: Database.Database): void {\n const columns = listTableColumns(db, \"memory_current\");\n if (columns.size === 0) return;\n\n if (!columns.has(\"tags_json\")) {\n db.exec(`ALTER TABLE memory_current ADD COLUMN tags_json TEXT NOT NULL DEFAULT '[]'`);\n }\n if (!columns.has(\"preview_text\")) {\n db.exec(`ALTER TABLE memory_current ADD COLUMN preview_text TEXT NOT NULL DEFAULT ''`);\n }\n}\n\nfunction memoryCurrentRequiresMigration(db: Database.Database): boolean {\n const columns = listTableColumns(db, \"memory_current\");\n return columns.size > 0 && (!columns.has(\"tags_json\") || !columns.has(\"preview_text\"));\n}\n\nfunction migrateProjectionSchemaIfNeeded(memoryDir: string): void {\n const dbPath = getMemoryProjectionPath(memoryDir);\n try {\n const db = new Database(dbPath, { fileMustExist: true });\n try {\n if (!memoryCurrentRequiresMigration(db)) return;\n initializeMemoryProjectionDb(db);\n } finally {\n db.close();\n }\n } catch {\n // Fail open on migration attempts so readonly consumers can still use legacy rows.\n }\n}\n\nexport function memoryCurrentSelectExpressions(db: Database.Database): {\n tagsJson: string;\n previewText: string;\n} {\n const columns = listTableColumns(db, \"memory_current\");\n return {\n tagsJson: columns.has(\"tags_json\") ? \"tags_json\" : `'[]' AS tags_json`,\n previewText: columns.has(\"preview_text\") ? \"preview_text\" : `'' AS preview_text`,\n };\n}\n\nexport function initializeMemoryProjectionDb(db: Database.Database): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS memory_current (\n memory_id TEXT PRIMARY KEY,\n category TEXT NOT NULL,\n status TEXT NOT NULL,\n lifecycle_state TEXT,\n path_rel TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n archived_at TEXT,\n superseded_at TEXT,\n entity_ref TEXT,\n source TEXT NOT NULL,\n confidence REAL NOT NULL,\n confidence_tier TEXT NOT NULL,\n memory_kind TEXT,\n access_count INTEGER,\n last_accessed TEXT,\n tags_json TEXT NOT NULL DEFAULT '[]',\n preview_text TEXT NOT NULL DEFAULT ''\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_current_status\n ON memory_current(status);\n\n CREATE INDEX IF NOT EXISTS idx_memory_current_category\n ON memory_current(category);\n\n CREATE INDEX IF NOT EXISTS idx_memory_current_updated\n ON memory_current(updated_at DESC);\n\n CREATE TABLE IF NOT EXISTS memory_timeline (\n event_id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL,\n event_type TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n event_order INTEGER NOT NULL,\n actor TEXT NOT NULL,\n reason_code TEXT,\n rule_version TEXT NOT NULL,\n related_memory_ids_json TEXT,\n before_json TEXT,\n after_json TEXT,\n correlation_id TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_timeline_memory_ts\n ON memory_timeline(memory_id, timestamp, event_order);\n\n CREATE TABLE IF NOT EXISTS memory_entity_mentions (\n memory_id TEXT NOT NULL,\n entity_ref TEXT NOT NULL,\n mention_source TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (memory_id, entity_ref, mention_source)\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_entity_mentions_entity\n ON memory_entity_mentions(entity_ref, updated_at DESC);\n\n CREATE TABLE IF NOT EXISTS native_knowledge_chunks (\n chunk_id TEXT PRIMARY KEY,\n source_path TEXT NOT NULL,\n title TEXT NOT NULL,\n source_kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n derived_date TEXT,\n session_key TEXT,\n workflow_key TEXT,\n author TEXT,\n agent TEXT,\n namespace TEXT,\n privacy_class TEXT,\n source_hash TEXT,\n preview_text TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_native_knowledge_source_kind\n ON native_knowledge_chunks(source_kind);\n\n CREATE INDEX IF NOT EXISTS idx_native_knowledge_namespace\n ON native_knowledge_chunks(namespace);\n\n CREATE TABLE IF NOT EXISTS memory_review_runs (\n run_id TEXT PRIMARY KEY,\n created_at TEXT NOT NULL,\n mode TEXT NOT NULL,\n summary_json TEXT NOT NULL,\n metrics_json TEXT NOT NULL,\n applied_actions_json TEXT NOT NULL,\n report_markdown TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_review_runs_created\n ON memory_review_runs(created_at DESC);\n\n CREATE TABLE IF NOT EXISTS memory_review_queue (\n entry_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n memory_id TEXT NOT NULL,\n path TEXT NOT NULL,\n reason_code TEXT NOT NULL,\n severity TEXT NOT NULL,\n suggested_action TEXT NOT NULL,\n suggested_status TEXT,\n related_memory_ids_json TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_review_queue_run\n ON memory_review_queue(run_id, reason_code, memory_id);\n\n CREATE TABLE IF NOT EXISTS memory_review_actions (\n row_key TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n action TEXT NOT NULL,\n memory_id TEXT NOT NULL,\n reason_code TEXT NOT NULL,\n before_status TEXT NOT NULL,\n after_status TEXT,\n original_path TEXT NOT NULL,\n current_path TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_review_actions_run\n ON memory_review_actions(run_id, memory_id);\n `);\n\n migrateMemoryCurrentTable(db);\n db.prepare(\"INSERT OR REPLACE INTO meta(key, value) VALUES (?, ?)\")\n .run(\"schemaVersion\", String(MEMORY_PROJECTION_SCHEMA_VERSION));\n}\n\nfunction openProjectionReadonly(memoryDir: string): Database.Database | null {\n const dbPath = getMemoryProjectionPath(memoryDir);\n try {\n return new Database(dbPath, { readonly: true, fileMustExist: true });\n } catch {\n return null;\n }\n}\n\nfunction withProjectionReadonly<T>(\n memoryDir: string,\n reader: (db: Database.Database) => T,\n): T | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n let needsMigration = false;\n try {\n needsMigration = memoryCurrentRequiresMigration(db);\n return reader(db);\n } catch {\n return null;\n } finally {\n db.close();\n if (needsMigration) {\n migrateProjectionSchemaIfNeeded(memoryDir);\n }\n }\n}\n\nfunction parseStringArray(value: unknown): string[] {\n if (typeof value !== \"string\" || value.length === 0) return [];\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed) ? parsed.filter((entry): entry is string => typeof entry === \"string\") : [];\n } catch {\n return [];\n }\n}\n\nfunction parseJsonObject<T>(value: unknown): T | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n try {\n return JSON.parse(value) as T;\n } catch {\n return undefined;\n }\n}\n\nexport function parseCurrentRow(\n memoryDir: string,\n row: Record<string, unknown> | undefined,\n): MemoryProjectionCurrentState | null {\n if (!row) return null;\n if (\n typeof row.memory_id !== \"string\" ||\n typeof row.category !== \"string\" ||\n typeof row.status !== \"string\" ||\n typeof row.path_rel !== \"string\" ||\n typeof row.created_at !== \"string\" ||\n typeof row.updated_at !== \"string\" ||\n typeof row.source !== \"string\" ||\n typeof row.confidence !== \"number\" ||\n typeof row.confidence_tier !== \"string\"\n ) {\n return null;\n }\n\n return {\n memoryId: row.memory_id,\n category: row.category as MemoryProjectionCurrentState[\"category\"],\n status: row.status as MemoryStatus,\n lifecycleState:\n typeof row.lifecycle_state === \"string\"\n ? (row.lifecycle_state as MemoryProjectionCurrentState[\"lifecycleState\"])\n : undefined,\n path: path.join(memoryDir, row.path_rel),\n pathRel: row.path_rel,\n created: row.created_at,\n updated: row.updated_at,\n archivedAt: typeof row.archived_at === \"string\" ? row.archived_at : undefined,\n supersededAt: typeof row.superseded_at === \"string\" ? row.superseded_at : undefined,\n entityRef: typeof row.entity_ref === \"string\" ? row.entity_ref : undefined,\n source: row.source,\n confidence: row.confidence,\n confidenceTier: row.confidence_tier as MemoryProjectionCurrentState[\"confidenceTier\"],\n memoryKind:\n typeof row.memory_kind === \"string\"\n ? (row.memory_kind as MemoryProjectionCurrentState[\"memoryKind\"])\n : undefined,\n accessCount: typeof row.access_count === \"number\" ? row.access_count : undefined,\n lastAccessed: typeof row.last_accessed === \"string\" ? row.last_accessed : undefined,\n tags: parseStringArray(row.tags_json),\n preview: typeof row.preview_text === \"string\" ? row.preview_text : \"\",\n };\n}\n\nexport function parseTimelineRows(rows: Array<Record<string, unknown>>): MemoryLifecycleEvent[] {\n const out: MemoryLifecycleEvent[] = [];\n for (const row of rows) {\n if (\n typeof row.event_id !== \"string\" ||\n typeof row.memory_id !== \"string\" ||\n typeof row.event_type !== \"string\" ||\n typeof row.timestamp !== \"string\" ||\n typeof row.actor !== \"string\" ||\n typeof row.rule_version !== \"string\"\n ) {\n continue;\n }\n\n out.push({\n eventId: row.event_id,\n memoryId: row.memory_id,\n eventType: row.event_type as MemoryLifecycleEvent[\"eventType\"],\n timestamp: row.timestamp,\n actor: row.actor,\n reasonCode: typeof row.reason_code === \"string\" ? row.reason_code : undefined,\n ruleVersion: row.rule_version,\n relatedMemoryIds: parseStringArray(row.related_memory_ids_json),\n before: parseJsonObject<MemoryLifecycleEvent[\"before\"]>(row.before_json),\n after: parseJsonObject<MemoryLifecycleEvent[\"after\"]>(row.after_json),\n correlationId: typeof row.correlation_id === \"string\" ? row.correlation_id : undefined,\n });\n }\n\n return out;\n}\n\nexport function readProjectedMemoryState(\n memoryDir: string,\n memoryId: string,\n): MemoryProjectionCurrentState | null {\n return withProjectionReadonly(memoryDir, (db) => {\n const currentSelect = memoryCurrentSelectExpressions(db);\n const row = db\n .prepare(\n `\n SELECT\n memory_id,\n category,\n status,\n lifecycle_state,\n path_rel,\n created_at,\n updated_at,\n archived_at,\n superseded_at,\n entity_ref,\n source,\n confidence,\n confidence_tier,\n memory_kind,\n access_count,\n last_accessed,\n ${currentSelect.tagsJson},\n ${currentSelect.previewText}\n FROM memory_current\n WHERE memory_id = ?\n `,\n )\n .get(memoryId) as Record<string, unknown> | undefined;\n return parseCurrentRow(memoryDir, row);\n });\n}\n\nexport function readProjectedMemoryTimeline(\n memoryDir: string,\n memoryId: string,\n limit: number,\n): MemoryLifecycleEvent[] | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const rows = db\n .prepare(\n `\n SELECT * FROM (\n SELECT\n event_id,\n memory_id,\n event_type,\n timestamp,\n event_order,\n actor,\n reason_code,\n rule_version,\n related_memory_ids_json,\n before_json,\n after_json,\n correlation_id\n FROM memory_timeline\n WHERE memory_id = ?\n ORDER BY timestamp DESC, event_order DESC\n LIMIT ?\n )\n ORDER BY timestamp ASC, event_order ASC\n `,\n )\n .all(memoryId, limit) as Array<Record<string, unknown>>;\n if (rows.length === 0) return null;\n return parseTimelineRows(rows);\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedMemoryBrowse(\n memoryDir: string,\n options: ProjectedMemoryBrowseOptions,\n): ProjectedMemoryBrowsePage | null {\n return withProjectionReadonly(memoryDir, (db) => {\n const normalizedQuery = options.query?.trim().toLowerCase() ?? \"\";\n\n const currentSelect = memoryCurrentSelectExpressions(db);\n const whereClauses: string[] = [];\n const params: unknown[] = [];\n\n if (options.status) {\n whereClauses.push(\"status = ?\");\n params.push(options.status);\n }\n if (options.category) {\n whereClauses.push(\"category = ?\");\n params.push(options.category);\n }\n const sort = options.sort ?? \"updated_desc\";\n const orderBySql = (() => {\n switch (sort) {\n case \"updated_asc\":\n return \"updated_at ASC, created_at ASC, memory_id ASC\";\n case \"created_desc\":\n return \"created_at DESC, updated_at DESC, memory_id ASC\";\n case \"created_asc\":\n return \"created_at ASC, updated_at ASC, memory_id ASC\";\n case \"updated_desc\":\n default:\n return \"updated_at DESC, created_at DESC, memory_id ASC\";\n }\n })();\n const whereSql = whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\";\n\n if (normalizedQuery) {\n // Query-based browse: fetch all matching rows, filter by full file content, then paginate in JS\n const allRows = db\n .prepare(`\n SELECT\n memory_id,\n path_rel,\n category,\n status,\n created_at,\n updated_at,\n entity_ref,\n ${currentSelect.tagsJson},\n ${currentSelect.previewText}\n FROM memory_current\n ${whereSql}\n ORDER BY ${orderBySql}\n `)\n .all(...params) as Array<Record<string, unknown>>;\n\n const filtered = allRows.filter((row) => {\n if (typeof row.memory_id !== \"string\" || typeof row.path_rel !== \"string\") return false;\n // Check preview, category, entity_ref, tags first (fast)\n const preview = typeof row.preview_text === \"string\" ? row.preview_text.toLowerCase() : \"\";\n const category = typeof row.category === \"string\" ? row.category.toLowerCase() : \"\";\n const entityRef = typeof row.entity_ref === \"string\" ? row.entity_ref.toLowerCase() : \"\";\n const tags = typeof row.tags_json === \"string\" ? row.tags_json.toLowerCase() : \"\";\n if (preview.includes(normalizedQuery) || category.includes(normalizedQuery) ||\n entityRef.includes(normalizedQuery) || tags.includes(normalizedQuery)) {\n return true;\n }\n // Fall back to reading full file content from disk\n try {\n const filePath = path.join(memoryDir, row.path_rel as string);\n const content = readFileSync(filePath, \"utf-8\").toLowerCase();\n return content.includes(normalizedQuery);\n } catch {\n return false;\n }\n });\n\n const pageRows = filtered.slice(options.offset, options.offset + options.limit);\n return {\n total: filtered.length,\n memories: pageRows\n .filter(\n (row) =>\n typeof row.memory_id === \"string\" &&\n typeof row.path_rel === \"string\" &&\n typeof row.category === \"string\" &&\n typeof row.status === \"string\",\n )\n .map((row) => ({\n id: row.memory_id as string,\n path: path.join(memoryDir, row.path_rel as string),\n category: row.category as MemoryCategory,\n status: row.status as MemoryStatus,\n created: typeof row.created_at === \"string\" ? row.created_at : undefined,\n updated: typeof row.updated_at === \"string\" ? row.updated_at : undefined,\n tags: parseStringArray(row.tags_json),\n entityRef: typeof row.entity_ref === \"string\" ? row.entity_ref : undefined,\n preview: typeof row.preview_text === \"string\" ? row.preview_text : \"\",\n })),\n };\n }\n\n // No query: use SQL pagination directly\n const totalRow = db\n .prepare(`SELECT COUNT(*) AS total FROM memory_current ${whereSql}`)\n .get(...params) as { total?: number } | undefined;\n const rows = db\n .prepare(`\n SELECT\n memory_id,\n path_rel,\n category,\n status,\n created_at,\n updated_at,\n entity_ref,\n ${currentSelect.tagsJson},\n ${currentSelect.previewText}\n FROM memory_current\n ${whereSql}\n ORDER BY ${orderBySql}\n LIMIT ? OFFSET ?\n `)\n .all(...params, options.limit, options.offset) as Array<Record<string, unknown>>;\n\n return {\n total: typeof totalRow?.total === \"number\" ? totalRow.total : 0,\n memories: rows\n .filter(\n (row) =>\n typeof row.memory_id === \"string\" &&\n typeof row.path_rel === \"string\" &&\n typeof row.category === \"string\" &&\n typeof row.status === \"string\",\n )\n .map((row) => ({\n id: row.memory_id as string,\n path: path.join(memoryDir, row.path_rel as string),\n category: row.category as MemoryCategory,\n status: row.status as MemoryStatus,\n created: typeof row.created_at === \"string\" ? row.created_at : undefined,\n updated: typeof row.updated_at === \"string\" ? row.updated_at : undefined,\n tags: parseStringArray(row.tags_json),\n entityRef: typeof row.entity_ref === \"string\" ? row.entity_ref : undefined,\n preview: typeof row.preview_text === \"string\" ? row.preview_text : \"\",\n })),\n };\n });\n}\n\nexport function readProjectedEntityMentions(\n memoryDir: string,\n memoryIds?: Set<string>,\n): ProjectedEntityMentionRow[] | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const rows = db\n .prepare(`\n SELECT\n memory_id,\n entity_ref,\n mention_source,\n created_at,\n updated_at\n FROM memory_entity_mentions\n ORDER BY entity_ref ASC, updated_at DESC, memory_id ASC\n `)\n .all() as Array<Record<string, unknown>>;\n\n return rows\n .filter(\n (row) =>\n typeof row.memory_id === \"string\" &&\n typeof row.entity_ref === \"string\" &&\n typeof row.mention_source === \"string\" &&\n typeof row.created_at === \"string\" &&\n typeof row.updated_at === \"string\" &&\n (!memoryIds || memoryIds.has(row.memory_id)),\n )\n .map((row) => ({\n memoryId: row.memory_id as string,\n entityRef: row.entity_ref as string,\n mentionSource: row.mention_source as string,\n created: row.created_at as string,\n updated: row.updated_at as string,\n }));\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedNativeKnowledgeChunks(\n memoryDir: string,\n): ProjectedNativeKnowledgeChunkRow[] | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const rows = db\n .prepare(`\n SELECT\n chunk_id,\n source_path,\n title,\n source_kind,\n start_line,\n end_line,\n derived_date,\n session_key,\n workflow_key,\n author,\n agent,\n namespace,\n privacy_class,\n source_hash,\n preview_text\n FROM native_knowledge_chunks\n ORDER BY source_kind ASC, source_path ASC, start_line ASC\n `)\n .all() as Array<Record<string, unknown>>;\n\n return rows\n .filter(\n (row) =>\n typeof row.chunk_id === \"string\" &&\n typeof row.source_path === \"string\" &&\n typeof row.title === \"string\" &&\n typeof row.source_kind === \"string\" &&\n typeof row.start_line === \"number\" &&\n typeof row.end_line === \"number\" &&\n typeof row.preview_text === \"string\",\n )\n .map((row) => ({\n chunkId: row.chunk_id as string,\n sourcePath: row.source_path as string,\n title: row.title as string,\n sourceKind: row.source_kind as string,\n startLine: row.start_line as number,\n endLine: row.end_line as number,\n derivedDate: typeof row.derived_date === \"string\" ? row.derived_date : undefined,\n sessionKey: typeof row.session_key === \"string\" ? row.session_key : undefined,\n workflowKey: typeof row.workflow_key === \"string\" ? row.workflow_key : undefined,\n author: typeof row.author === \"string\" ? row.author : undefined,\n agent: typeof row.agent === \"string\" ? row.agent : undefined,\n namespace: typeof row.namespace === \"string\" ? row.namespace : undefined,\n privacyClass: typeof row.privacy_class === \"string\" ? row.privacy_class : undefined,\n sourceHash: typeof row.source_hash === \"string\" ? row.source_hash : undefined,\n preview: row.preview_text as string,\n }));\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedLatestReviewQueue(\n memoryDir: string,\n): ProjectedReviewQueueSnapshot | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const latestRunId =\n (db.prepare(`SELECT value FROM meta WHERE key = 'latestGovernanceRunId'`).get() as { value?: string } | undefined)\n ?.value\n ?? (db.prepare(`SELECT run_id AS value FROM memory_review_runs ORDER BY created_at DESC LIMIT 1`).get() as {\n value?: string;\n } | undefined)?.value;\n if (!latestRunId) {\n return { found: false };\n }\n\n const runRow = db\n .prepare(`\n SELECT\n run_id,\n summary_json,\n metrics_json,\n applied_actions_json,\n report_markdown\n FROM memory_review_runs\n WHERE run_id = ?\n `)\n .get(latestRunId) as Record<string, unknown> | undefined;\n if (!runRow || typeof runRow.run_id !== \"string\") {\n return { found: false };\n }\n\n const queueRows = db\n .prepare(`\n SELECT\n entry_id,\n memory_id,\n path,\n reason_code,\n severity,\n suggested_action,\n suggested_status,\n related_memory_ids_json\n FROM memory_review_queue\n WHERE run_id = ?\n ORDER BY reason_code ASC, memory_id ASC\n `)\n .all(latestRunId) as Array<Record<string, unknown>>;\n\n const actionRows = db\n .prepare(`\n SELECT\n row_key,\n action,\n memory_id,\n reason_code,\n before_status,\n after_status,\n original_path,\n current_path\n FROM memory_review_actions\n WHERE run_id = ?\n ORDER BY memory_id ASC, action ASC\n `)\n .all(latestRunId) as Array<Record<string, unknown>>;\n\n const reviewQueue: MemoryGovernanceReviewQueueEntry[] = queueRows\n .filter(\n (row) =>\n typeof row.entry_id === \"string\" &&\n typeof row.memory_id === \"string\" &&\n typeof row.path === \"string\" &&\n typeof row.reason_code === \"string\" &&\n typeof row.severity === \"string\" &&\n typeof row.suggested_action === \"string\",\n )\n .map((row) => ({\n entryId: row.entry_id as string,\n memoryId: row.memory_id as string,\n path: row.path as string,\n reasonCode: row.reason_code as MemoryGovernanceReviewQueueEntry[\"reasonCode\"],\n severity: row.severity as MemoryGovernanceReviewQueueEntry[\"severity\"],\n suggestedAction: row.suggested_action as MemoryGovernanceReviewQueueEntry[\"suggestedAction\"],\n suggestedStatus:\n typeof row.suggested_status === \"string\"\n ? (row.suggested_status as MemoryGovernanceReviewQueueEntry[\"suggestedStatus\"])\n : undefined,\n relatedMemoryIds: parseStringArray(row.related_memory_ids_json),\n }));\n\n return {\n found: true,\n runId: latestRunId,\n summary: parseJsonObject<MemoryGovernanceSummary>(runRow.summary_json),\n metrics: parseJsonObject<MemoryGovernanceMetrics>(runRow.metrics_json),\n reviewQueue,\n appliedActions:\n actionRows.length > 0\n ? actionRows\n .filter(\n (row) =>\n typeof row.action === \"string\" &&\n typeof row.memory_id === \"string\" &&\n typeof row.reason_code === \"string\" &&\n typeof row.before_status === \"string\" &&\n typeof row.original_path === \"string\" &&\n typeof row.current_path === \"string\",\n )\n .map((row) => ({\n action: row.action as MemoryGovernanceAppliedAction[\"action\"],\n memoryId: row.memory_id as string,\n reasonCode: row.reason_code as MemoryGovernanceAppliedAction[\"reasonCode\"],\n beforeStatus: row.before_status as MemoryGovernanceAppliedAction[\"beforeStatus\"],\n afterStatus:\n typeof row.after_status === \"string\"\n ? (row.after_status as MemoryGovernanceAppliedAction[\"afterStatus\"])\n : undefined,\n originalPath: row.original_path as string,\n currentPath: row.current_path as string,\n }))\n : (parseJsonObject<MemoryGovernanceAppliedAction[]>(runRow.applied_actions_json) ?? []),\n report: typeof runRow.report_markdown === \"string\" ? runRow.report_markdown : undefined,\n };\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedGovernanceRecord(\n memoryDir: string,\n): {\n runId: string;\n summary: unknown;\n metrics: unknown;\n reviewQueueRows: MemoryProjectionGovernanceReviewQueueRow[];\n appliedActionRows: MemoryProjectionGovernanceAppliedActionRow[];\n report: string;\n} | null {\n const snapshot = readProjectedLatestReviewQueue(memoryDir);\n if (!snapshot?.found || !snapshot.runId) return null;\n\n return {\n runId: snapshot.runId,\n summary: snapshot.summary ?? {},\n metrics: snapshot.metrics ?? {},\n reviewQueueRows: (snapshot.reviewQueue ?? []).map((entry) => ({\n runId: snapshot.runId as string,\n entryId: entry.entryId,\n memoryId: entry.memoryId,\n path: entry.path,\n reasonCode: entry.reasonCode,\n severity: entry.severity,\n suggestedAction: entry.suggestedAction,\n suggestedStatus: entry.suggestedStatus,\n relatedMemoryIds: [...entry.relatedMemoryIds],\n })),\n appliedActionRows: (snapshot.appliedActions ?? []).map((action) => ({\n runId: snapshot.runId as string,\n rowKey: [\n action.action,\n action.memoryId,\n action.reasonCode,\n action.originalPath,\n action.currentPath,\n ].join(\"::\"),\n action: action.action,\n memoryId: action.memoryId,\n reasonCode: action.reasonCode,\n beforeStatus: action.beforeStatus,\n afterStatus: action.afterStatus,\n originalPath: action.originalPath,\n currentPath: action.currentPath,\n })),\n report: snapshot.report ?? \"\",\n };\n}\n","import path from \"node:path\";\nimport type {\n MemoryFile,\n MemoryLifecycleEvent,\n MemoryLifecycleEventType,\n MemoryLifecycleStateSummary,\n MemoryFrontmatter,\n MemoryStatus,\n} from \"./types.js\";\n\nexport const MEMORY_LIFECYCLE_RULE_VERSION = \"memory-lifecycle-ledger.v1\";\n\nexport const MEMORY_LIFECYCLE_EVENT_SORT_ORDER: Record<MemoryLifecycleEventType, number> = {\n created: 0,\n updated: 1,\n promoted: 2,\n explicit_capture_accepted: 3,\n explicit_capture_queued: 4,\n imported: 5,\n merged: 6,\n restored: 7,\n superseded: 8,\n rejected: 9,\n archived: 10,\n};\n\nexport function toMemoryPathRel(baseDir: string, filePath: string): string {\n if (!baseDir) return filePath.split(path.sep).join(\"/\");\n return path.relative(baseDir, filePath).split(path.sep).join(\"/\");\n}\n\nexport function isArchivedMemoryPath(pathRel: string): boolean {\n return pathRel === \"archive\" || pathRel.startsWith(\"archive/\");\n}\n\nexport function inferMemoryStatus(\n frontmatter: MemoryFrontmatter,\n pathRel: string,\n fallbackStatus: MemoryStatus = \"active\",\n): MemoryStatus {\n if (frontmatter.status && frontmatter.status !== \"active\") return frontmatter.status;\n if (frontmatter.archivedAt) return \"archived\";\n if (isArchivedMemoryPath(pathRel)) return \"archived\";\n if (frontmatter.status) return frontmatter.status;\n return fallbackStatus;\n}\n\nexport function summarizeMemoryLifecycleState(memory: MemoryFile): MemoryLifecycleStateSummary {\n return {\n category: memory.frontmatter.category,\n path: memory.path,\n status: memory.frontmatter.status ?? \"active\",\n lifecycleState: memory.frontmatter.lifecycleState,\n };\n}\n\nexport function makeRebuiltMemoryLifecycleEvent(\n memory: MemoryFile,\n eventType: MemoryLifecycleEventType,\n timestamp: string,\n): MemoryLifecycleEvent {\n return {\n eventId: `rebuild-${memory.frontmatter.id}-${eventType}-${timestamp}`,\n memoryId: memory.frontmatter.id,\n eventType,\n timestamp,\n actor: \"maintenance.rebuildMemoryLifecycleLedger\",\n ruleVersion: MEMORY_LIFECYCLE_RULE_VERSION,\n after: summarizeMemoryLifecycleState(memory),\n relatedMemoryIds: [\n ...(memory.frontmatter.supersededBy ? [memory.frontmatter.supersededBy] : []),\n ...(memory.frontmatter.supersedes ? [memory.frontmatter.supersedes] : []),\n ...((memory.frontmatter.lineage ?? []).filter(Boolean)),\n ],\n };\n}\n\nexport function buildLifecycleEventsForMemory(memory: MemoryFile): MemoryLifecycleEvent[] {\n const events: MemoryLifecycleEvent[] = [];\n const created = memory.frontmatter.created;\n const updated = memory.frontmatter.updated;\n const archivedAt = memory.frontmatter.archivedAt;\n const supersededAt = memory.frontmatter.supersededAt;\n const effectiveArchivedAt =\n archivedAt ?? (memory.frontmatter.status === \"archived\" && updated ? updated : undefined);\n\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"created\", created));\n if (\n updated &&\n updated !== created &&\n updated !== effectiveArchivedAt &&\n updated !== supersededAt\n ) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"updated\", updated));\n }\n if (supersededAt) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"superseded\", supersededAt));\n }\n if (effectiveArchivedAt) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"archived\", effectiveArchivedAt));\n }\n\n return events;\n}\n\nexport function sortMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): MemoryLifecycleEvent[] {\n return [...events].sort((a, b) => {\n if (a.memoryId !== b.memoryId) return a.memoryId.localeCompare(b.memoryId);\n if (a.timestamp !== b.timestamp) return a.timestamp.localeCompare(b.timestamp);\n return MEMORY_LIFECYCLE_EVENT_SORT_ORDER[a.eventType] - MEMORY_LIFECYCLE_EVENT_SORT_ORDER[b.eventType];\n });\n}\n","export function normalizeProjectionPreview(content: string, maxChars = 180): string {\n return content.replace(/\\s+/g, \" \").trim().slice(0, maxChars);\n}\n\nexport function normalizeProjectionTags(tags: string[] | undefined): string[] {\n return [...new Set(\n (tags ?? [])\n .map((value) => value.trim())\n .filter((value) => value.length > 0),\n )].sort();\n}\n","import type {\n ContinuityIncidentCloseInput,\n ContinuityIncidentOpenInput,\n ContinuityImprovementLoop,\n ContinuityLoopCadence,\n ContinuityLoopReviewInput,\n ContinuityLoopStatus,\n ContinuityLoopUpsertInput,\n ContinuityIncidentRecord,\n ContinuityIncidentState,\n} from \"./types.js\";\n\nfunction parseFrontmatterValue(raw: string): unknown {\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n}\n\nfunction parseFrontmatter(raw: string): Record<string, unknown> {\n const parsed: Record<string, unknown> = {};\n for (const line of raw.split(\"\\n\")) {\n const idx = line.indexOf(\":\");\n if (idx <= 0) continue;\n const key = line.slice(0, idx).trim();\n const value = line.slice(idx + 1).trim();\n parsed[key] = parseFrontmatterValue(value);\n }\n return parsed;\n}\n\nfunction emitSection(lines: string[], title: string, value?: string): void {\n if (!value || value.trim().length === 0) return;\n lines.push(`## ${title}`, \"\", value.trim(), \"\");\n}\n\nfunction parseSection(body: string, title: string): string | undefined {\n const escaped = title.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const re = new RegExp(`## ${escaped}\\\\n\\\\n([\\\\s\\\\S]*?)(?=\\\\n## |$)`);\n const match = body.match(re);\n if (!match) return undefined;\n const value = match[1].trim();\n return value.length > 0 ? value : undefined;\n}\n\nexport function serializeContinuityIncident(incident: ContinuityIncidentRecord): string {\n const lines = [\n \"---\",\n `id: ${JSON.stringify(incident.id)}`,\n `state: ${JSON.stringify(incident.state)}`,\n `openedAt: ${JSON.stringify(incident.openedAt)}`,\n `updatedAt: ${JSON.stringify(incident.updatedAt)}`,\n ];\n if (incident.closedAt) lines.push(`closedAt: ${JSON.stringify(incident.closedAt)}`);\n if (incident.triggerWindow) lines.push(`triggerWindow: ${JSON.stringify(incident.triggerWindow)}`);\n lines.push(\"---\", \"\");\n\n emitSection(lines, \"Symptom\", incident.symptom);\n emitSection(lines, \"Suspected Cause\", incident.suspectedCause);\n emitSection(lines, \"Fix Applied\", incident.fixApplied);\n emitSection(lines, \"Verification Result\", incident.verificationResult);\n emitSection(lines, \"Preventive Rule\", incident.preventiveRule);\n\n return lines.join(\"\\n\").trimEnd() + \"\\n\";\n}\n\nexport function parseContinuityIncident(raw: string): ContinuityIncidentRecord | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (!match) return null;\n const frontmatter = parseFrontmatter(match[1]);\n const body = match[2] ?? \"\";\n\n const id = typeof frontmatter.id === \"string\" ? frontmatter.id : \"\";\n const stateRaw = frontmatter.state;\n const state: ContinuityIncidentState = stateRaw === \"closed\" ? \"closed\" : \"open\";\n const openedAt = typeof frontmatter.openedAt === \"string\" ? frontmatter.openedAt : \"\";\n const updatedAt = typeof frontmatter.updatedAt === \"string\" ? frontmatter.updatedAt : openedAt;\n const symptom = parseSection(body, \"Symptom\");\n\n if (!id || !openedAt || !updatedAt || !symptom) return null;\n\n return {\n id,\n state,\n openedAt,\n updatedAt,\n triggerWindow: typeof frontmatter.triggerWindow === \"string\" ? frontmatter.triggerWindow : undefined,\n symptom,\n suspectedCause: parseSection(body, \"Suspected Cause\"),\n fixApplied: parseSection(body, \"Fix Applied\"),\n verificationResult: parseSection(body, \"Verification Result\"),\n preventiveRule: parseSection(body, \"Preventive Rule\"),\n closedAt: typeof frontmatter.closedAt === \"string\" ? frontmatter.closedAt : undefined,\n };\n}\n\nexport function createContinuityIncidentRecord(\n id: string,\n input: ContinuityIncidentOpenInput,\n nowIso: string,\n): ContinuityIncidentRecord {\n return {\n id,\n state: \"open\",\n openedAt: nowIso,\n updatedAt: nowIso,\n triggerWindow: input.triggerWindow?.trim() || undefined,\n symptom: input.symptom.trim(),\n suspectedCause: input.suspectedCause?.trim() || undefined,\n };\n}\n\nexport function closeContinuityIncidentRecord(\n incident: ContinuityIncidentRecord,\n closure: ContinuityIncidentCloseInput,\n nowIso: string,\n): ContinuityIncidentRecord {\n return {\n ...incident,\n state: \"closed\",\n updatedAt: nowIso,\n closedAt: nowIso,\n fixApplied: closure.fixApplied.trim(),\n verificationResult: closure.verificationResult.trim(),\n preventiveRule: closure.preventiveRule?.trim() || incident.preventiveRule,\n };\n}\n\nconst LOOP_HEADER = \"# Continuity Improvement Loops\";\nconst LOOP_CADENCES = new Set<ContinuityLoopCadence>([\"daily\", \"weekly\", \"monthly\", \"quarterly\"]);\nconst LOOP_STATUSES = new Set<ContinuityLoopStatus>([\"active\", \"paused\", \"retired\"]);\nconst STALE_LAST_REVIEWED_FALLBACK = \"1970-01-01T00:00:00.000Z\";\n\nfunction normalizeLoopField(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n return trimmed.replace(/\\s+/g, \" \");\n}\n\nfunction isValidIso(value: string): boolean {\n const ts = Date.parse(value);\n return Number.isFinite(ts);\n}\n\nfunction normalizeContinuityLoop(\n input: ContinuityLoopUpsertInput | ContinuityImprovementLoop,\n nowIso: string,\n): ContinuityImprovementLoop | null {\n const id = normalizeLoopField(input.id);\n const cadence = normalizeLoopField(input.cadence) as ContinuityLoopCadence | undefined;\n const status = normalizeLoopField(input.status) as ContinuityLoopStatus | undefined;\n const purpose = normalizeLoopField(input.purpose);\n const killCondition = normalizeLoopField(input.killCondition);\n const notes = normalizeLoopField(input.notes);\n const lastReviewedRaw =\n \"lastReviewed\" in input && typeof input.lastReviewed === \"string\" ? input.lastReviewed : undefined;\n const lastReviewed = normalizeLoopField(lastReviewedRaw) ?? nowIso;\n\n if (!id || !cadence || !status || !purpose || !killCondition) return null;\n if (!LOOP_CADENCES.has(cadence)) return null;\n if (!LOOP_STATUSES.has(status)) return null;\n if (!isValidIso(lastReviewed)) return null;\n\n return {\n id,\n cadence,\n purpose,\n status,\n killCondition,\n lastReviewed,\n notes,\n };\n}\n\nfunction serializeContinuityLoopSection(loop: ContinuityImprovementLoop): string {\n const lines = [\n `## ${loop.id}`,\n `cadence: ${loop.cadence}`,\n `purpose: ${loop.purpose}`,\n `status: ${loop.status}`,\n `killCondition: ${loop.killCondition}`,\n `lastReviewed: ${loop.lastReviewed}`,\n ];\n if (loop.notes) lines.push(`notes: ${loop.notes}`);\n return lines.join(\"\\n\");\n}\n\ntype MarkdownSection = {\n title: string;\n body: string;\n};\n\nfunction splitLoopMarkdown(raw: string | null): { header: string; sections: MarkdownSection[] } {\n const text = (raw ?? \"\").replace(/\\r/g, \"\");\n const lines = text.split(\"\\n\");\n const headerLines: string[] = [];\n const sections: MarkdownSection[] = [];\n let current: MarkdownSection | null = null;\n\n for (const line of lines) {\n const sectionMatch = line.match(/^##\\s+(.+?)\\s*$/);\n if (sectionMatch) {\n if (current) sections.push({ title: current.title, body: current.body.trimEnd() });\n current = { title: sectionMatch[1].trim(), body: \"\" };\n continue;\n }\n if (!current) {\n headerLines.push(line);\n continue;\n }\n current.body += current.body.length > 0 ? `\\n${line}` : line;\n }\n if (current) sections.push({ title: current.title, body: current.body.trimEnd() });\n\n const headerRaw = headerLines.join(\"\\n\").trim();\n const header = headerRaw.length > 0 ? headerRaw : LOOP_HEADER;\n return { header, sections };\n}\n\nfunction parseLoopFromSection(section: MarkdownSection, nowIso: string): ContinuityImprovementLoop | null {\n const fields: Record<string, string> = {};\n for (const line of section.body.split(\"\\n\")) {\n const kv = line.match(/^([A-Za-z][A-Za-z0-9_]*):\\s*(.+?)\\s*$/);\n if (!kv) continue;\n fields[kv[1]] = kv[2];\n }\n const parsedLastReviewed = normalizeLoopField(fields.lastReviewed);\n const safeLastReviewed =\n parsedLastReviewed && isValidIso(parsedLastReviewed) ? parsedLastReviewed : STALE_LAST_REVIEWED_FALLBACK;\n return normalizeContinuityLoop(\n {\n id: section.title,\n cadence: (fields.cadence ?? \"\") as ContinuityLoopCadence,\n purpose: fields.purpose ?? \"\",\n status: (fields.status ?? \"\") as ContinuityLoopStatus,\n killCondition: fields.killCondition ?? \"\",\n lastReviewed: safeLastReviewed,\n notes: fields.notes,\n },\n nowIso,\n );\n}\n\nfunction joinLoopMarkdown(header: string, sections: MarkdownSection[]): string {\n const lines: string[] = [header.trim(), \"\"];\n for (const section of sections) {\n lines.push(`## ${section.title}`);\n if (section.body.trim().length > 0) {\n lines.push(section.body.trimEnd());\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trimEnd() + \"\\n\";\n}\n\nexport function parseContinuityImprovementLoops(raw: string): ContinuityImprovementLoop[] {\n const parsed = splitLoopMarkdown(raw);\n const nowIso = new Date().toISOString();\n return parsed.sections\n .map((section) => parseLoopFromSection(section, nowIso))\n .filter((loop): loop is ContinuityImprovementLoop => loop !== null);\n}\n\nexport function upsertContinuityLoopInMarkdown(\n raw: string | null,\n input: ContinuityLoopUpsertInput,\n nowIso: string,\n): { markdown: string; loop: ContinuityImprovementLoop } {\n const normalized = normalizeContinuityLoop(input, nowIso);\n if (!normalized) {\n throw new Error(\"Invalid continuity loop input\");\n }\n\n const parsed = splitLoopMarkdown(raw);\n let replaced = false;\n const nextSections = parsed.sections.map((section) => {\n if (normalizeLoopField(section.title) !== normalized.id) return section;\n replaced = true;\n return { title: normalized.id, body: serializeContinuityLoopSection(normalized).split(\"\\n\").slice(1).join(\"\\n\") };\n });\n\n if (!replaced) {\n nextSections.push({\n title: normalized.id,\n body: serializeContinuityLoopSection(normalized).split(\"\\n\").slice(1).join(\"\\n\"),\n });\n }\n\n return { markdown: joinLoopMarkdown(parsed.header, nextSections), loop: normalized };\n}\n\nexport function reviewContinuityLoopInMarkdown(\n raw: string | null,\n id: string,\n input: ContinuityLoopReviewInput,\n nowIso: string,\n): { markdown: string; loop: ContinuityImprovementLoop | null } {\n const parsed = splitLoopMarkdown(raw);\n const normalizedId = normalizeLoopField(id);\n if (!normalizedId) {\n return { markdown: joinLoopMarkdown(parsed.header, parsed.sections), loop: null };\n }\n let updatedLoop: ContinuityImprovementLoop | null = null;\n const nextSections = parsed.sections.map((section) => {\n if (normalizeLoopField(section.title) !== normalizedId) return section;\n const existing = parseLoopFromSection(section, nowIso);\n if (!existing) return section;\n const reviewed = applyContinuityLoopReview(existing, input, nowIso);\n updatedLoop = reviewed;\n return { title: reviewed.id, body: serializeContinuityLoopSection(reviewed).split(\"\\n\").slice(1).join(\"\\n\") };\n });\n\n return { markdown: joinLoopMarkdown(parsed.header, nextSections), loop: updatedLoop };\n}\n\nfunction applyContinuityLoopReview(\n existing: ContinuityImprovementLoop,\n input: ContinuityLoopReviewInput,\n nowIso: string,\n): ContinuityImprovementLoop {\n const nextStatus = normalizeLoopField(input.status) as ContinuityLoopStatus | undefined;\n const nextNotes = normalizeLoopField(input.notes);\n const reviewedAt = normalizeLoopField(input.reviewedAt) ?? nowIso;\n\n return {\n ...existing,\n status: nextStatus && LOOP_STATUSES.has(nextStatus) ? nextStatus : existing.status,\n notes: nextNotes ?? existing.notes,\n lastReviewed: isValidIso(reviewedAt) ? reviewedAt : nowIso,\n };\n}\n"],"mappings":"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","names":["readFile","stat","writeFile","mkdir","path","path","path","parseFrontmatter","match","path","readFile","mkdir","writeFile","stat","q"]}
1
+ {"version":3,"sources":["../src/storage.ts","../src/memory-cache.ts","../src/hygiene.ts","../src/sanitize.ts","../src/types.ts","../src/memory-projection-store.ts","../src/memory-lifecycle-ledger-utils.ts","../src/memory-projection-format.ts","../src/identity-continuity.ts"],"sourcesContent":["import { access, readdir, readFile, stat, writeFile, mkdir, unlink, rename, appendFile } from \"node:fs/promises\";\nimport { appendFileSync, mkdirSync, statSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { log } from \"./logger.js\";\nimport { getCachedEntities, setCachedEntities } from \"./memory-cache.js\";\nimport { rotateMarkdownFileToArchive } from \"./hygiene.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport type {\n AccessTrackingEntry,\n BufferState,\n ConfidenceTier,\n ContinuityIncidentCloseInput,\n ContinuityIncidentOpenInput,\n ContinuityIncidentRecord,\n ContinuityImprovementLoop,\n ContinuityLoopReviewInput,\n ContinuityLoopUpsertInput,\n EntityActivityEntry,\n EntityFile,\n EntityRelationship,\n ImportanceLevel,\n ImportanceScore,\n MemoryCategory,\n MemoryFile,\n MemoryFrontmatter,\n MemoryLink,\n LifecycleState,\n VerificationState,\n PolicyClass,\n MemoryStatus,\n MemoryActionEvent,\n MemoryLifecycleEvent,\n MemoryLifecycleEventType,\n MemoryLifecycleStateSummary,\n MemoryProjectionCurrentState,\n BehaviorSignalEvent,\n MemorySummary,\n MetaState,\n CompressionGuidelineOptimizerState,\n PluginConfig,\n ScoredEntity,\n TopicScore,\n FileHygieneConfig,\n} from \"./types.js\";\nimport { confidenceTier, SPECULATIVE_TTL_DAYS } from \"./types.js\";\nimport {\n type ProjectedMemoryBrowseOptions,\n type ProjectedMemoryBrowsePage,\n readProjectedMemoryState,\n readProjectedMemoryBrowse,\n readProjectedGovernanceRecord,\n readProjectedMemoryTimeline,\n} from \"./memory-projection-store.js\";\nimport {\n inferMemoryStatus,\n isArchivedMemoryPath,\n sortMemoryLifecycleEvents,\n toMemoryPathRel,\n} from \"./memory-lifecycle-ledger-utils.js\";\nimport {\n normalizeProjectionPreview,\n normalizeProjectionTags,\n} from \"./memory-projection-format.js\";\nimport {\n closeContinuityIncidentRecord,\n createContinuityIncidentRecord,\n parseContinuityIncident,\n parseContinuityImprovementLoops,\n reviewContinuityLoopInMarkdown,\n serializeContinuityIncident,\n upsertContinuityLoopInMarkdown,\n} from \"./identity-continuity.js\";\n\nconst ARTIFACT_SEARCH_STOPWORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"but\",\n \"by\",\n \"for\",\n \"from\",\n \"has\",\n \"have\",\n \"i\",\n \"in\",\n \"is\",\n \"it\",\n \"of\",\n \"on\",\n \"or\",\n \"that\",\n \"the\",\n \"this\",\n \"to\",\n \"was\",\n \"were\",\n \"with\",\n]);\n\nexport interface ReextractJobRequest {\n memoryId: string;\n model: string;\n requestedAt: string;\n source: \"cli-migrate\";\n}\n\nexport interface MemoryLifecycleEventWriteOptions {\n at?: Date;\n actor?: string;\n reasonCode?: string;\n ruleVersion?: string;\n relatedMemoryIds?: string[];\n correlationId?: string;\n}\n\nfunction tokenizeArtifactSearchText(input: string): string[] {\n return input\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 2)\n .filter((t) => !ARTIFACT_SEARCH_STOPWORDS.has(t));\n}\n\nfunction serializeFrontmatter(fm: MemoryFrontmatter): string {\n const lines = [\n \"---\",\n `id: ${fm.id}`,\n `category: ${fm.category}`,\n `created: ${fm.created}`,\n `updated: ${fm.updated}`,\n `source: ${fm.source}`,\n `confidence: ${fm.confidence}`,\n `confidenceTier: ${fm.confidenceTier}`,\n `tags: [${fm.tags.map((t) => `\"${t}\"`).join(\", \")}]`,\n ];\n if (fm.entityRef) lines.push(`entityRef: ${fm.entityRef}`);\n if (fm.supersedes) lines.push(`supersedes: ${fm.supersedes}`);\n if (fm.expiresAt) lines.push(`expiresAt: ${fm.expiresAt}`);\n if (fm.lineage && fm.lineage.length > 0) {\n lines.push(`lineage: [${fm.lineage.map((l) => `\"${l}\"`).join(\", \")}]`);\n }\n // Status management\n if (fm.status && fm.status !== \"active\") lines.push(`status: ${fm.status}`);\n if (fm.supersededBy) lines.push(`supersededBy: ${fm.supersededBy}`);\n if (fm.supersededAt) lines.push(`supersededAt: ${fm.supersededAt}`);\n if (fm.archivedAt) lines.push(`archivedAt: ${fm.archivedAt}`);\n // Lifecycle policy fields\n if (fm.lifecycleState) lines.push(`lifecycleState: ${fm.lifecycleState}`);\n if (fm.verificationState) lines.push(`verificationState: ${fm.verificationState}`);\n if (fm.policyClass) lines.push(`policyClass: ${fm.policyClass}`);\n if (fm.lastValidatedAt) lines.push(`lastValidatedAt: ${fm.lastValidatedAt}`);\n if (fm.decayScore !== undefined) lines.push(`decayScore: ${fm.decayScore}`);\n if (fm.heatScore !== undefined) lines.push(`heatScore: ${fm.heatScore}`);\n // Access tracking\n if (fm.accessCount !== undefined && fm.accessCount > 0) {\n lines.push(`accessCount: ${fm.accessCount}`);\n }\n if (fm.lastAccessed) lines.push(`lastAccessed: ${fm.lastAccessed}`);\n // Importance scoring\n if (fm.importance) {\n lines.push(`importanceScore: ${fm.importance.score}`);\n lines.push(`importanceLevel: ${fm.importance.level}`);\n if (fm.importance.reasons.length > 0) {\n lines.push(\n `importanceReasons: [${fm.importance.reasons\n .map((r) => `\"${r.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`)\n .join(\", \")}]`,\n );\n }\n if (fm.importance.keywords.length > 0) {\n lines.push(`importanceKeywords: [${fm.importance.keywords.map((k) => `\"${k}\"`).join(\", \")}]`);\n }\n }\n // Chunking (Phase 2A)\n if (fm.parentId) lines.push(`parentId: ${fm.parentId}`);\n if (fm.chunkIndex !== undefined) lines.push(`chunkIndex: ${fm.chunkIndex}`);\n if (fm.chunkTotal !== undefined) lines.push(`chunkTotal: ${fm.chunkTotal}`);\n // Memory Linking (Phase 3A)\n if (fm.links && fm.links.length > 0) {\n lines.push(\"links:\");\n for (const link of fm.links) {\n lines.push(` - targetId: ${link.targetId}`);\n lines.push(` linkType: ${link.linkType}`);\n lines.push(` strength: ${link.strength}`);\n if (link.reason) lines.push(` reason: ${JSON.stringify(link.reason)}`);\n }\n }\n if (fm.intentGoal) lines.push(`intentGoal: ${fm.intentGoal}`);\n if (fm.intentActionType) lines.push(`intentActionType: ${fm.intentActionType}`);\n if (fm.intentEntityTypes && fm.intentEntityTypes.length > 0) {\n lines.push(`intentEntityTypes: [${fm.intentEntityTypes.map((t) => `\"${t}\"`).join(\", \")}]`);\n }\n if (fm.artifactType) lines.push(`artifactType: ${fm.artifactType}`);\n if (fm.sourceMemoryId) lines.push(`sourceMemoryId: ${fm.sourceMemoryId}`);\n if (fm.sourceTurnId) lines.push(`sourceTurnId: ${fm.sourceTurnId}`);\n // v8.0 Phase 2B: HiMem episode/note classification\n if (fm.memoryKind) lines.push(`memoryKind: ${fm.memoryKind}`);\n // Structured attributes (stored as JSON on a single line)\n if (fm.structuredAttributes && Object.keys(fm.structuredAttributes).length > 0) {\n lines.push(`structuredAttributes: ${JSON.stringify(fm.structuredAttributes)}`);\n }\n lines.push(\"---\");\n return lines.join(\"\\n\");\n}\n\nfunction parseStructuredAttributes(raw: string | undefined): Record<string, string> | undefined {\n if (!raw || !raw.trim()) return undefined;\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n const result: Record<string, string> = {};\n for (const [k, v] of Object.entries(parsed)) {\n if (typeof k === \"string\" && typeof v === \"string\") {\n result[k] = v;\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n }\n } catch {\n // Not valid JSON — ignore\n }\n return undefined;\n}\n\nfunction parseLinkReasonValue(rawValue: string): string {\n const legacyValue = rawValue.replace(/\\\\\"/g, '\"');\n const looksLikeLegacyPath =\n !rawValue.includes(\"\\\\\\\\\") &&\n (/[A-Za-z]:\\\\[A-Za-z0-9._ -]+(?:\\\\[A-Za-z0-9._ -]+)*/.test(rawValue) ||\n /\\\\[A-Za-z0-9._ -]+\\\\[A-Za-z0-9._ -]+/.test(rawValue));\n\n if (looksLikeLegacyPath) {\n return legacyValue;\n }\n\n try {\n return JSON.parse(`\"${rawValue}\"`) as string;\n } catch {\n return legacyValue;\n }\n}\n\nfunction parseFrontmatter(\n raw: string,\n): { frontmatter: MemoryFrontmatter; content: string } | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (!match) return null;\n\n const fmBlock = match[1];\n const content = match[2].trim();\n const fm: Record<string, string> = {};\n\n for (const line of fmBlock.split(\"\\n\")) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx === -1) continue;\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n fm[key] = value;\n }\n\n let tags: string[] = [];\n const tagsStr = fm.tags ?? \"\";\n const tagMatch = tagsStr.match(/\\[(.*)]/);\n if (tagMatch) {\n tags = tagMatch[1]\n .split(\",\")\n .map((t) => t.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n let intentEntityTypes: string[] | undefined;\n const intentEntityTypesStr = fm.intentEntityTypes ?? \"\";\n const intentEntityTypesMatch = intentEntityTypesStr.match(/\\[(.*)]/);\n if (intentEntityTypesMatch) {\n intentEntityTypes = intentEntityTypesMatch[1]\n .split(\",\")\n .map((t) => t.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n const conf = parseFloat(fm.confidence ?? \"0.8\");\n\n // Parse lineage array if present\n let lineage: string[] | undefined;\n const lineageStr = fm.lineage ?? \"\";\n const lineageMatch = lineageStr.match(/\\[(.*)]/);\n if (lineageMatch) {\n lineage = lineageMatch[1]\n .split(\",\")\n .map((l) => l.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n // Parse accessCount\n const accessCount = fm.accessCount ? parseInt(fm.accessCount, 10) : undefined;\n const decayScore = fm.decayScore !== undefined ? parseFloat(fm.decayScore) : undefined;\n const heatScore = fm.heatScore !== undefined ? parseFloat(fm.heatScore) : undefined;\n\n // Parse importance\n let importance: ImportanceScore | undefined;\n if (fm.importanceScore) {\n const score = parseFloat(fm.importanceScore);\n const level = (fm.importanceLevel as ImportanceLevel) || \"normal\";\n\n // Parse importance reasons array\n let reasons: string[] = [];\n const reasonsStr = fm.importanceReasons ?? \"\";\n if (reasonsStr.trim().startsWith(\"[\") && reasonsStr.trim().endsWith(\"]\")) {\n const reasonMatches = reasonsStr.matchAll(/\"((?:\\\\.|[^\"\\\\])*)\"/g);\n for (const match of reasonMatches) {\n const reason = parseLinkReasonValue(match[1]);\n if (reason.length > 0) {\n reasons.push(reason);\n }\n }\n }\n\n // Parse importance keywords array\n let keywords: string[] = [];\n const keywordsStr = fm.importanceKeywords ?? \"\";\n const keywordsMatch = keywordsStr.match(/\\[(.*)]/);\n if (keywordsMatch) {\n keywords = keywordsMatch[1]\n .split(\",\")\n .map((k) => k.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n importance = { score, level, reasons, keywords };\n }\n\n const result: { frontmatter: MemoryFrontmatter; content: string } = {\n frontmatter: {\n id: fm.id ?? \"\",\n category: (fm.category ?? \"fact\") as MemoryCategory,\n created: fm.created ?? new Date().toISOString(),\n updated: fm.updated ?? new Date().toISOString(),\n source: fm.source ?? \"unknown\",\n confidence: conf,\n confidenceTier: (fm.confidenceTier as ConfidenceTier) || confidenceTier(conf),\n tags,\n entityRef: fm.entityRef || undefined,\n supersedes: fm.supersedes || undefined,\n expiresAt: fm.expiresAt || undefined,\n lineage: lineage && lineage.length > 0 ? lineage : undefined,\n // Status management\n status: (fm.status as MemoryStatus) || \"active\",\n supersededBy: fm.supersededBy || undefined,\n supersededAt: fm.supersededAt || undefined,\n archivedAt: fm.archivedAt || undefined,\n lifecycleState: (fm.lifecycleState as LifecycleState) || undefined,\n verificationState: (fm.verificationState as VerificationState) || undefined,\n policyClass: (fm.policyClass as PolicyClass) || undefined,\n lastValidatedAt: fm.lastValidatedAt || undefined,\n decayScore: Number.isFinite(decayScore) ? decayScore : undefined,\n heatScore: Number.isFinite(heatScore) ? heatScore : undefined,\n // Access tracking\n accessCount: accessCount && accessCount > 0 ? accessCount : undefined,\n lastAccessed: fm.lastAccessed || undefined,\n // Importance scoring\n importance,\n // Chunking\n parentId: fm.parentId || undefined,\n chunkIndex: fm.chunkIndex ? parseInt(fm.chunkIndex, 10) : undefined,\n chunkTotal: fm.chunkTotal ? parseInt(fm.chunkTotal, 10) : undefined,\n // Links are parsed separately below\n intentGoal: fm.intentGoal || undefined,\n intentActionType: fm.intentActionType || undefined,\n intentEntityTypes: intentEntityTypes && intentEntityTypes.length > 0 ? intentEntityTypes : undefined,\n artifactType: (fm.artifactType as MemoryFrontmatter[\"artifactType\"]) || undefined,\n sourceMemoryId: fm.sourceMemoryId || undefined,\n sourceTurnId: fm.sourceTurnId || undefined,\n // v8.0 Phase 2B: HiMem episode/note classification\n memoryKind: (fm.memoryKind as MemoryFrontmatter[\"memoryKind\"]) || undefined,\n // Structured attributes (JSON on a single line)\n structuredAttributes: parseStructuredAttributes(fm.structuredAttributes),\n },\n content,\n };\n\n // Parse links (YAML array format)\n // Note: Simple parsing - for full YAML we'd need a library.\n if (fmBlock.includes(\"links:\")) {\n const links: MemoryLink[] = [];\n const linkMatches = fmBlock.matchAll(\n /- targetId: (\\S+)\\s+linkType: (\\S+)\\s+strength: ([\\d.]+)(?:\\s+reason: \"((?:\\\\.|[^\"\\\\])*)\")?/g,\n );\n for (const match of linkMatches) {\n links.push({\n targetId: match[1],\n linkType: match[2] as MemoryLink[\"linkType\"],\n strength: parseFloat(match[3]),\n reason: match[4] ? parseLinkReasonValue(match[4]) : undefined,\n });\n }\n if (links.length > 0) {\n result.frontmatter.links = links;\n }\n }\n\n return result;\n}\n\nfunction normalizeFrontmatterForPath(frontmatter: MemoryFrontmatter, pathRel: string): MemoryFrontmatter {\n if (isArchivedMemoryPath(pathRel) && (!frontmatter.status || frontmatter.status === \"active\")) {\n return {\n ...frontmatter,\n status: \"archived\",\n };\n }\n\n return frontmatter;\n}\n\nfunction inferCurrentStateStatus(\n frontmatter: MemoryFrontmatter,\n pathRel: string,\n fallbackStatus: MemoryStatus,\n): MemoryStatus {\n return inferMemoryStatus(frontmatter, pathRel, fallbackStatus);\n}\n\n/**\n * Entity alias table loaded from the user's local config.\n * Populated by StorageManager.loadAliases() at startup.\n * Falls back to built-in structural aliases (e.g. \"open-claw\" → \"openclaw\").\n */\nlet userAliases: Record<string, string> = {};\n\n/** Built-in aliases for common structural normalizations (no personal data) */\nconst BUILTIN_ALIASES: Record<string, string> = {\n openclaw: \"openclaw\",\n \"open-claw\": \"openclaw\",\n};\n\n/**\n * Normalize an entity name to a canonical form.\n * Strips non-alphanumeric chars, collapses hyphens, removes type prefix duplication.\n * e.g. \"My Project\" → \"my-project\"\n *\n * Checks user-defined aliases (from config/aliases.json) first, then built-in aliases.\n */\nexport function normalizeEntityName(raw: string, type: string): string {\n // Strip type prefix if present (e.g. name=\"person-jane-doe\", type=\"person\")\n const rawStr = typeof raw === \"string\" ? raw : \"\";\n const typeStr = typeof type === \"string\" && type.trim().length > 0 ? type : \"entity\";\n\n let name = rawStr.toLowerCase().trim();\n const typePrefix = `${typeStr.toLowerCase()}-`;\n if (name.startsWith(typePrefix)) {\n name = name.slice(typePrefix.length);\n }\n\n // Replace non-alphanumeric with hyphens, collapse multiples, trim edges\n let normalized = name\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n // Check user aliases first, then built-in\n if (userAliases[normalized]) {\n normalized = userAliases[normalized];\n } else if (BUILTIN_ALIASES[normalized]) {\n normalized = BUILTIN_ALIASES[normalized];\n }\n\n return `${typeStr.toLowerCase()}-${normalized}`;\n}\n\n/**\n * Simple Levenshtein distance between two strings.\n */\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (m === 0) return n;\n if (n === 0) return m;\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\n/** Strip hyphens from a string for loose comparison */\nfunction dehyphenate(s: string): string {\n return s.replace(/-/g, \"\");\n}\n\n/**\n * Content-hash dedup index for facts.\n * Normalizes content (lowercase, strip punctuation, collapse whitespace),\n * computes SHA-256, and stores hashes in a line-delimited file.\n * Prevents writing semantically identical facts.\n */\nexport class ContentHashIndex {\n private hashes: Set<string> = new Set();\n private dirty = false;\n private readonly filePath: string;\n\n constructor(stateDir: string) {\n this.filePath = path.join(stateDir, \"fact-hashes.txt\");\n }\n\n /** Load existing hashes from disk. Safe to call multiple times. */\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.filePath, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.length > 0) {\n this.hashes.add(trimmed);\n }\n }\n log.debug(`content-hash index: loaded ${this.hashes.size} hashes`);\n } catch {\n log.debug(\"content-hash index: no existing index — starting fresh\");\n }\n }\n\n /** Check if content already exists in the index. */\n has(content: string): boolean {\n return this.hashes.has(ContentHashIndex.computeHash(content));\n }\n\n /** Add content hash to the index. */\n add(content: string): void {\n const hash = ContentHashIndex.computeHash(content);\n if (!this.hashes.has(hash)) {\n this.hashes.add(hash);\n this.dirty = true;\n }\n }\n\n get size(): number {\n return this.hashes.size;\n }\n\n /** Persist index to disk if changed. */\n async save(): Promise<void> {\n if (!this.dirty) return;\n await mkdir(path.dirname(this.filePath), { recursive: true });\n await writeFile(this.filePath, [...this.hashes].join(\"\\n\") + \"\\n\", \"utf-8\");\n this.dirty = false;\n log.debug(`content-hash index: saved ${this.hashes.size} hashes`);\n }\n\n /** Remove a hash from the index (used when archiving/deleting). */\n remove(content: string): void {\n const hash = ContentHashIndex.computeHash(content);\n if (this.hashes.delete(hash)) {\n this.dirty = true;\n }\n }\n\n /** Normalize content and compute SHA-256 hash. */\n static normalizeContent(content: string): string {\n return content\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n }\n\n /** Normalize content and compute SHA-256 hash. */\n static computeHash(content: string): string {\n const normalized = ContentHashIndex.normalizeContent(content);\n return createHash(\"sha256\").update(normalized).digest(\"hex\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Entity file parsing / serialization (Knowledge Graph v7.0)\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an entity markdown file into a structured EntityFile.\n * Backward compatible: old files without new sections get empty arrays.\n */\nexport function parseEntityFile(content: string): EntityFile {\n const lines = content.split(\"\\n\");\n\n // Header\n let name = \"\";\n let type = \"other\";\n let updated = \"\";\n let summary: string | undefined;\n const facts: string[] = [];\n const relationships: EntityRelationship[] = [];\n const activity: EntityActivityEntry[] = [];\n const aliases: string[] = [];\n\n // Parse name from first heading\n const headingLine = lines.find((l) => l.startsWith(\"# \"));\n if (headingLine) name = headingLine.slice(2).trim();\n\n // Parse type\n const typeLine = lines.find((l) => l.startsWith(\"**Type:**\"));\n if (typeLine) type = typeLine.replace(\"**Type:**\", \"\").trim();\n\n // Parse updated\n const updatedLine = lines.find((l) => l.startsWith(\"**Updated:**\"));\n if (updatedLine) updated = updatedLine.replace(\"**Updated:**\", \"\").trim();\n\n // Detect which section we're in\n let section = \"\";\n for (const line of lines) {\n if (line.startsWith(\"## \")) {\n section = line.slice(3).trim().toLowerCase();\n continue;\n }\n if (!line.startsWith(\"- \")) continue;\n\n const bullet = line.slice(2).trim();\n if (!bullet) continue;\n\n switch (section) {\n case \"facts\":\n facts.push(bullet);\n break;\n case \"summary\":\n // Summary is typically a single line after the heading, not a bullet\n break;\n case \"connected to\": {\n // Format: [[target-entity]] — relationship label\n const relMatch = bullet.match(/^\\[\\[([^\\]]+)\\]\\]\\s*[—–-]\\s*(.+)$/);\n if (relMatch) {\n relationships.push({ target: relMatch[1].trim(), label: relMatch[2].trim() });\n }\n break;\n }\n case \"activity\": {\n // Format: YYYY-MM-DD: note\n const actMatch = bullet.match(/^(\\d{4}-\\d{2}-\\d{2}):\\s*(.+)$/);\n if (actMatch) {\n activity.push({ date: actMatch[1], note: actMatch[2].trim() });\n }\n break;\n }\n case \"aliases\":\n aliases.push(bullet);\n break;\n }\n }\n\n // Parse summary: text between ## Summary heading and next ## heading (not bulleted)\n const summaryIdx = lines.findIndex((l) => l.startsWith(\"## Summary\"));\n if (summaryIdx !== -1) {\n const summaryLines: string[] = [];\n for (let i = summaryIdx + 1; i < lines.length; i++) {\n if (lines[i].startsWith(\"## \")) break;\n const trimmed = lines[i].trim();\n if (trimmed) summaryLines.push(trimmed);\n }\n if (summaryLines.length > 0) summary = summaryLines.join(\" \");\n }\n\n return { name, type, updated, facts, summary, relationships, activity, aliases };\n}\n\n/**\n * Serialize an EntityFile back to markdown.\n * Only emits sections that have content (except Facts which is always emitted).\n */\nexport function serializeEntityFile(entity: EntityFile): string {\n const lines: string[] = [\n `# ${entity.name}`,\n \"\",\n `**Type:** ${entity.type}`,\n `**Updated:** ${entity.updated || new Date().toISOString()}`,\n \"\",\n ];\n\n // Summary (optional)\n if (entity.summary) {\n lines.push(\"## Summary\", \"\", entity.summary, \"\");\n }\n\n // Facts (always emitted)\n lines.push(\"## Facts\", \"\");\n for (const f of entity.facts) {\n lines.push(`- ${f}`);\n }\n lines.push(\"\");\n\n // Connected to (optional)\n if (entity.relationships.length > 0) {\n lines.push(\"## Connected to\", \"\");\n for (const rel of entity.relationships) {\n lines.push(`- [[${rel.target}]] — ${rel.label}`);\n }\n lines.push(\"\");\n }\n\n // Activity (optional)\n if (entity.activity.length > 0) {\n lines.push(\"## Activity\", \"\");\n for (const act of entity.activity) {\n lines.push(`- ${act.date}: ${act.note}`);\n }\n lines.push(\"\");\n }\n\n // Aliases (optional)\n if (entity.aliases.length > 0) {\n lines.push(\"## Aliases\", \"\");\n for (const alias of entity.aliases) {\n lines.push(`- ${alias}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nexport class StorageManager {\n private knowledgeIndexCache: { result: string; builtAt: number } | null = null;\n private static readonly KNOWLEDGE_INDEX_CACHE_TTL_MS = 600_000; // 10 minutes (entity mutations invalidate)\n private artifactIndexCache: { memories: MemoryFile[]; loadedAtMs: number; writeVersion: number } | null = null;\n private static readonly ARTIFACT_INDEX_CACHE_TTL_MS = 60_000; // 1 minute\n private static readonly artifactWriteVersionByDir = new Map<string, number>();\n private static readonly memoryStatusVersionByDir = new Map<string, number>();\n\n // Module-level cache for readAllMemories() keyed by base directory.\n // Shared across all StorageManager instances to avoid duplicate I/O when\n // multiple concurrent callers (e.g. verifiedRecall + verifiedRules) read the\n // same directory simultaneously. In-flight deduplication prevents multiple\n // concurrent reads of the same directory.\n //\n // Stale-while-revalidate: once the cache has a value, subsequent reads after\n // TTL expiry return the stale cached data immediately and kick off a background\n // refresh. This eliminates the 13-60 s cold-scan penalty that would otherwise\n // block recall requests every 5 minutes on large memory collections (80k+ files).\n private static readonly allMemoriesInFlight = new Map<string, Promise<MemoryFile[]>>();\n\n // Cache for readQuestions() — avoids serially re-reading tens of thousands of\n // question files on every recall. 60-second TTL is intentionally short so that\n // newly written questions surface quickly.\n private static readonly QUESTIONS_CACHE_TTL_MS = 60_000; // 1 minute\n private static readonly questionsCache = new Map<\n string,\n {\n questions: Array<{\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n }>;\n loadedAt: number;\n }\n >();\n private factHashIndex: ContentHashIndex | null = null;\n private factHashIndexLoadPromise: Promise<ContentHashIndex> | null = null;\n private factHashIndexAuthoritative: boolean | null = null;\n private factHashIndexAuthoritativePromise: Promise<void> | null = null;\n\n constructor(private readonly baseDir: string) {}\n\n /** The root directory of this storage instance. */\n get dir(): string {\n return this.baseDir;\n }\n\n private identityFilePath(workspaceDir: string, namespace?: string): string {\n const rawNamespace = typeof namespace === \"string\" ? namespace.trim() : \"\";\n if (!rawNamespace) return path.join(workspaceDir, \"IDENTITY.md\");\n const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n return path.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);\n }\n\n private versionFilePath(kind: \"memory-status\" | \"artifact-write\"): string {\n const fileName =\n kind === \"memory-status\" ? \".memory-status-version.log\" : \".artifact-write-version.log\";\n return path.join(this.stateDir, fileName);\n }\n\n private bumpSharedVersion(\n kind: \"memory-status\" | \"artifact-write\",\n fallbackMap: Map<string, number>,\n ): number {\n const filePath = this.versionFilePath(kind);\n try {\n mkdirSync(this.stateDir, { recursive: true });\n appendFileSync(filePath, \"x\");\n const next = statSync(filePath).size;\n fallbackMap.set(this.baseDir, next);\n return next;\n } catch {\n const next = (fallbackMap.get(this.baseDir) ?? 0) + 1;\n fallbackMap.set(this.baseDir, next);\n return next;\n }\n }\n\n private readSharedVersion(\n kind: \"memory-status\" | \"artifact-write\",\n fallbackMap: Map<string, number>,\n ): number {\n const filePath = this.versionFilePath(kind);\n try {\n return statSync(filePath).size;\n } catch {\n return fallbackMap.get(this.baseDir) ?? 0;\n }\n }\n\n private bumpMemoryStatusVersion(): void {\n this.bumpSharedVersion(\"memory-status\", StorageManager.memoryStatusVersionByDir);\n }\n\n getMemoryStatusVersion(): number {\n return this.readSharedVersion(\"memory-status\", StorageManager.memoryStatusVersionByDir);\n }\n\n private bumpArtifactWriteVersion(): number {\n return this.bumpSharedVersion(\"artifact-write\", StorageManager.artifactWriteVersionByDir);\n }\n\n private getArtifactWriteVersion(): number {\n return this.readSharedVersion(\"artifact-write\", StorageManager.artifactWriteVersionByDir);\n }\n\n private get factsDir(): string {\n return path.join(this.baseDir, \"facts\");\n }\n private get correctionsDir(): string {\n return path.join(this.baseDir, \"corrections\");\n }\n private get entitiesDir(): string {\n return path.join(this.baseDir, \"entities\");\n }\n private get stateDir(): string {\n return path.join(this.baseDir, \"state\");\n }\n private get factHashIndexReadyPath(): string {\n return path.join(this.stateDir, \"fact-hashes.ready\");\n }\n\n private async getFactHashIndex(): Promise<ContentHashIndex> {\n if (this.factHashIndex) {\n return this.factHashIndex;\n }\n if (!this.factHashIndexLoadPromise) {\n const index = new ContentHashIndex(this.stateDir);\n this.factHashIndexLoadPromise = index\n .load()\n .then(() => {\n this.factHashIndex = index;\n return index;\n })\n .catch((err) => {\n this.factHashIndexLoadPromise = null;\n throw err;\n });\n }\n return this.factHashIndexLoadPromise;\n }\n\n private async ensureFactHashIndexAuthoritative(): Promise<void> {\n if (this.factHashIndexAuthoritative === true) {\n return;\n }\n if (this.factHashIndexAuthoritativePromise) {\n await this.factHashIndexAuthoritativePromise;\n return;\n }\n\n this.factHashIndexAuthoritativePromise = (async () => {\n try {\n await access(this.factHashIndexReadyPath);\n this.factHashIndexAuthoritative = true;\n return;\n } catch {\n // Fall through and backfill from the live fact corpus once.\n }\n\n const factHashIndex = await this.getFactHashIndex();\n const existing = await this.readAllMemories();\n for (const memory of existing) {\n if (memory.frontmatter.category !== \"fact\") continue;\n if (inferMemoryStatus(memory.frontmatter, memory.path) !== \"active\") continue;\n factHashIndex.add(memory.content);\n }\n await factHashIndex.save();\n await mkdir(path.dirname(this.factHashIndexReadyPath), { recursive: true });\n await writeFile(this.factHashIndexReadyPath, \"v1\\n\", \"utf-8\");\n this.factHashIndexAuthoritative = true;\n })().finally(() => {\n this.factHashIndexAuthoritativePromise = null;\n });\n await this.factHashIndexAuthoritativePromise;\n }\n private get questionsDir(): string {\n return path.join(this.baseDir, \"questions\");\n }\n private get artifactsDir(): string {\n return path.join(this.baseDir, \"artifacts\");\n }\n private get identityDir(): string {\n return path.join(this.baseDir, \"identity\");\n }\n private get identityAnchorPath(): string {\n return path.join(this.identityDir, \"identity-anchor.md\");\n }\n private get identityIncidentsDir(): string {\n return path.join(this.identityDir, \"incidents\");\n }\n private get identityAuditsWeeklyDir(): string {\n return path.join(this.identityDir, \"audits\", \"weekly\");\n }\n private get identityAuditsMonthlyDir(): string {\n return path.join(this.identityDir, \"audits\", \"monthly\");\n }\n private get identityImprovementLoopsPath(): string {\n return path.join(this.identityDir, \"improvement-loops.md\");\n }\n private get identityReflectionsPath(): string {\n return path.join(this.identityDir, \"reflections.md\");\n }\n private get profilePath(): string {\n return path.join(this.baseDir, \"profile.md\");\n }\n private get memoryActionsPath(): string {\n return path.join(this.stateDir, \"memory-actions.jsonl\");\n }\n private get memoryLifecycleLedgerPath(): string {\n return path.join(this.stateDir, \"memory-lifecycle-ledger.jsonl\");\n }\n private get compressionGuidelinesPath(): string {\n return path.join(this.stateDir, \"compression-guidelines.md\");\n }\n private get compressionGuidelineDraftPath(): string {\n return path.join(this.stateDir, \"compression-guidelines.draft.md\");\n }\n private get compressionGuidelineStatePath(): string {\n return path.join(this.stateDir, \"compression-guideline-state.json\");\n }\n private get compressionGuidelineDraftStatePath(): string {\n return path.join(this.stateDir, \"compression-guideline-draft-state.json\");\n }\n private get behaviorSignalsPath(): string {\n return path.join(this.stateDir, \"behavior-signals.jsonl\");\n }\n\n /**\n * Load user-defined entity aliases from config/aliases.json in the memory store.\n * File format: { \"variant\": \"canonical\", \"variant2\": \"canonical\", ... }\n * Call this once at startup (e.g. from orchestrator.initialize()).\n */\n async loadAliases(): Promise<void> {\n const aliasPath = path.join(this.baseDir, \"config\", \"aliases.json\");\n try {\n const raw = await readFile(aliasPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null) {\n userAliases = parsed as Record<string, string>;\n log.debug(`loaded ${Object.keys(userAliases).length} entity aliases from ${aliasPath}`);\n }\n } catch {\n // No aliases file — that's fine, use built-in only\n log.debug(\"no config/aliases.json found — using built-in aliases only\");\n }\n }\n\n async ensureDirectories(): Promise<void> {\n const today = new Date().toISOString().slice(0, 10);\n await mkdir(path.join(this.factsDir, today), { recursive: true });\n await mkdir(this.correctionsDir, { recursive: true });\n await mkdir(this.entitiesDir, { recursive: true });\n await mkdir(this.stateDir, { recursive: true });\n await mkdir(this.questionsDir, { recursive: true });\n await mkdir(this.artifactsDir, { recursive: true });\n await mkdir(this.identityDir, { recursive: true });\n await mkdir(this.identityIncidentsDir, { recursive: true });\n await mkdir(this.identityAuditsWeeklyDir, { recursive: true });\n await mkdir(this.identityAuditsMonthlyDir, { recursive: true });\n await mkdir(path.join(this.baseDir, \"config\"), { recursive: true });\n }\n\n async writeMemory(\n category: MemoryCategory,\n content: string,\n options: {\n actor?: string;\n confidence?: number;\n tags?: string[];\n entityRef?: string;\n source?: string;\n supersedes?: string;\n lineage?: string[];\n importance?: ImportanceScore;\n links?: MemoryLink[];\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n artifactType?: MemoryFrontmatter[\"artifactType\"];\n sourceMemoryId?: string;\n sourceTurnId?: string;\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n expiresAt?: string;\n structuredAttributes?: Record<string, string>;\n } = {},\n ): Promise<string> {\n await this.ensureDirectories();\n const now = new Date();\n const today = now.toISOString().slice(0, 10);\n const id = `${category}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n const conf = options.confidence ?? 0.8;\n const tier = confidenceTier(conf);\n\n // Auto-set TTL for speculative memories\n let expiresAt: string | undefined;\n if (typeof options.expiresAt === \"string\" && options.expiresAt.length > 0) {\n expiresAt = options.expiresAt;\n } else if (tier === \"speculative\") {\n const expiry = new Date(now.getTime() + SPECULATIVE_TTL_DAYS * 24 * 60 * 60 * 1000);\n expiresAt = expiry.toISOString();\n }\n\n const fm: MemoryFrontmatter = {\n id,\n category,\n created: now.toISOString(),\n updated: now.toISOString(),\n source: options.source ?? \"extraction\",\n confidence: conf,\n confidenceTier: tier,\n tags: options.tags ?? [],\n entityRef: options.entityRef,\n supersedes: options.supersedes,\n expiresAt,\n lineage: options.lineage,\n importance: options.importance,\n links: options.links,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n artifactType: options.artifactType,\n sourceMemoryId: options.sourceMemoryId,\n sourceTurnId: options.sourceTurnId,\n memoryKind: options.memoryKind,\n structuredAttributes: options.structuredAttributes,\n };\n\n // Append structured attributes as searchable suffix so QMD indexes them\n let enrichedContent = content;\n if (options.structuredAttributes && Object.keys(options.structuredAttributes).length > 0) {\n const attrLines = Object.entries(options.structuredAttributes)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n enrichedContent = `${content}\\n[Attributes: ${attrLines}]`;\n }\n\n const sanitized = sanitizeMemoryContent(enrichedContent);\n if (!sanitized.clean) {\n log.warn(`memory content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n const fileContent = `${serializeFrontmatter(fm)}\\n\\n${sanitized.text}\\n`;\n\n let filePath: string;\n if (category === \"correction\") {\n filePath = path.join(this.correctionsDir, `${id}.md`);\n } else {\n filePath = path.join(this.factsDir, today, `${id}.md`);\n }\n\n await writeFile(filePath, fileContent, \"utf-8\");\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.writeMemory\", {\n memoryId: id,\n eventType: \"created\",\n timestamp: fm.created,\n actor: options.actor ?? \"storage.writeMemory\",\n after: this.summarizeLifecycleState(fm, filePath),\n relatedMemoryIds: [\n ...(options.supersedes ? [options.supersedes] : []),\n ...((options.lineage ?? []).filter(Boolean)),\n ],\n });\n if (category === \"fact\") {\n try {\n const factHashIndex = await this.getFactHashIndex();\n factHashIndex.add(sanitized.text);\n await factHashIndex.save();\n } catch (err) {\n log.warn(`storage.writeMemory completed but failed to update fact hash index: ${err}`);\n }\n }\n log.debug(`wrote memory ${id} to ${filePath}`);\n return id;\n }\n\n async hasFactContentHash(content: string): Promise<boolean> {\n await this.ensureFactHashIndexAuthoritative();\n const factHashIndex = await this.getFactHashIndex();\n const sanitized = sanitizeMemoryContent(content);\n return factHashIndex.has(sanitized.text);\n }\n\n async isFactContentHashAuthoritative(): Promise<boolean> {\n await this.ensureFactHashIndexAuthoritative();\n return true;\n }\n\n async writeArtifact(\n quote: string,\n options: {\n actor?: string;\n tags?: string[];\n confidence?: number;\n artifactType?: MemoryFrontmatter[\"artifactType\"];\n sourceMemoryId?: string;\n sourceTurnId?: string;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n } = {},\n ): Promise<string> {\n await this.ensureDirectories();\n const now = new Date();\n const day = now.toISOString().slice(0, 10);\n const dir = path.join(this.artifactsDir, day);\n await mkdir(dir, { recursive: true });\n\n const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n const fm: MemoryFrontmatter = {\n id,\n category: \"fact\",\n created: now.toISOString(),\n updated: now.toISOString(),\n source: \"artifact\",\n confidence: options.confidence ?? 0.9,\n confidenceTier: confidenceTier(options.confidence ?? 0.9),\n tags: options.tags ?? [],\n artifactType: options.artifactType ?? \"fact\",\n sourceMemoryId: options.sourceMemoryId,\n sourceTurnId: options.sourceTurnId,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n };\n\n const sanitized = sanitizeMemoryContent(quote);\n if (!sanitized.clean) {\n log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(\", \")}`);\n return \"\";\n }\n const filePath = path.join(dir, `${id}.md`);\n await writeFile(filePath, `${serializeFrontmatter(fm)}\\n\\n${sanitized.text}\\n`, \"utf-8\");\n const actor =\n typeof options.actor === \"string\" && options.actor.length > 0\n ? options.actor\n : \"storage.writeArtifact\";\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.writeArtifact\", {\n memoryId: id,\n eventType: \"created\",\n timestamp: fm.created,\n actor,\n after: this.summarizeLifecycleState(fm, filePath),\n relatedMemoryIds: options.sourceMemoryId ? [options.sourceMemoryId] : [],\n });\n this.bumpArtifactWriteVersion();\n // Always invalidate on write. This avoids stale mixed snapshots when multiple\n // processes share the same memoryDir and write concurrently.\n this.artifactIndexCache = null;\n return id;\n }\n\n private async readAllArtifactsCached(): Promise<MemoryFile[]> {\n if (\n this.artifactIndexCache &&\n Date.now() - this.artifactIndexCache.loadedAtMs <= StorageManager.ARTIFACT_INDEX_CACHE_TTL_MS &&\n this.artifactIndexCache.writeVersion === this.getArtifactWriteVersion()\n ) {\n return this.artifactIndexCache.memories;\n }\n\n const scanArtifacts = async (): Promise<MemoryFile[]> => {\n const artifacts: MemoryFile[] = [];\n const readDir = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await readDir(fullPath);\n continue;\n }\n if (!entry.name.endsWith(\".md\")) continue;\n const memory = await this.readMemoryByPath(fullPath);\n if (!memory) continue;\n artifacts.push(memory);\n }\n } catch {\n // Directory doesn't exist yet\n }\n };\n await readDir(this.artifactsDir);\n return artifacts;\n };\n\n const MAX_REBUILD_RETRIES = 2;\n let latestArtifacts: MemoryFile[] = [];\n for (let attempt = 0; attempt <= MAX_REBUILD_RETRIES; attempt += 1) {\n const versionBefore = this.getArtifactWriteVersion();\n const artifacts = await scanArtifacts();\n const versionAfter = this.getArtifactWriteVersion();\n latestArtifacts = artifacts;\n if (versionAfter === versionBefore) {\n this.artifactIndexCache = { memories: artifacts, loadedAtMs: Date.now(), writeVersion: versionAfter };\n return artifacts;\n }\n }\n\n // Highly concurrent writer churn; keep cache invalid so next read retries a clean rebuild.\n // Return best-effort latest scan instead of an empty set to avoid dropping recall entirely.\n this.artifactIndexCache = null;\n return latestArtifacts;\n }\n\n async searchArtifacts(query: string, maxResults: number): Promise<MemoryFile[]> {\n const tokens = tokenizeArtifactSearchText(query);\n if (tokens.length === 0) return [];\n\n const artifacts = await this.readAllArtifactsCached();\n const hits: Array<{ score: number; memory: MemoryFile }> = [];\n for (const memory of artifacts) {\n const indexedTokens = new Set(\n tokenizeArtifactSearchText(`${memory.content} ${(memory.frontmatter.tags ?? []).join(\" \")}`),\n );\n const score = tokens.reduce((sum, t) => sum + (indexedTokens.has(t) ? 1 : 0), 0);\n if (score > 0) {\n hits.push({ score, memory });\n }\n }\n hits.sort((a, b) => b.score - a.score);\n return hits.slice(0, maxResults).map((h) => h.memory);\n }\n\n async writeEntity(\n name: string,\n type: string,\n facts: string[],\n ): Promise<string> {\n await this.ensureDirectories();\n if (typeof name !== \"string\" || !name.trim() || typeof type !== \"string\" || !type.trim()) {\n log.warn(\"writeEntity: invalid entity payload, skipping\", {\n nameType: typeof name,\n typeType: typeof type,\n });\n return \"\";\n }\n const safeFacts = Array.isArray(facts) ? facts.filter((f) => typeof f === \"string\") : [];\n let normalized = normalizeEntityName(name, type);\n\n // Check for fuzzy match against existing entities before creating a new file\n const match = await this.findMatchingEntity(name, type);\n if (match && match !== normalized) {\n log.debug(`fuzzy match: \"${normalized}\" → existing \"${match}\"`);\n normalized = match;\n }\n\n const filePath = path.join(this.entitiesDir, `${normalized}.md`);\n\n // Parse existing file to preserve relationships/activity/aliases/summary\n let entity: EntityFile = {\n name, type, updated: new Date().toISOString(),\n facts: [], summary: undefined, relationships: [], activity: [], aliases: [],\n };\n try {\n const existing = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(existing);\n } catch {\n // File doesn't exist yet\n }\n\n // Merge facts (dedup)\n entity.facts = [...new Set([...entity.facts, ...safeFacts])];\n entity.name = name;\n entity.type = type;\n entity.updated = new Date().toISOString();\n\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n this.bumpMemoryStatusVersion(); // invalidate entity cache\n log.debug(`wrote entity ${normalized}`);\n return normalized;\n }\n\n async readProfile(): Promise<string> {\n try {\n return await readFile(this.profilePath, \"utf-8\");\n } catch {\n return \"\";\n }\n }\n\n async writeProfile(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.profilePath, content, \"utf-8\");\n log.debug(\"updated profile.md\");\n }\n\n /**\n * Normalize a string for fuzzy profile dedup: lowercase, strip punctuation, collapse whitespace.\n */\n private static normalizeForDedup(s: string): string {\n if (typeof s !== \"string\") return \"\";\n return s\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n }\n\n /**\n * Check if a new bullet is a fuzzy duplicate of any existing bullet.\n * Returns true if the new bullet should be skipped.\n */\n private static isFuzzyDuplicate(newNorm: string, existingNorms: string[]): boolean {\n for (const existing of existingNorms) {\n // Exact normalized match\n if (newNorm === existing) return true;\n\n // Containment check: shorter must be >60% length of longer\n const shorter = newNorm.length <= existing.length ? newNorm : existing;\n const longer = newNorm.length > existing.length ? newNorm : existing;\n if (shorter.length > 20 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {\n return true;\n }\n }\n return false;\n }\n\n async appendToProfile(updates: string[]): Promise<void> {\n // Filter out non-string entries that the LLM may return\n updates = updates.filter((u) => typeof u === \"string\" && u.trim().length > 0);\n if (updates.length === 0) return;\n const existing = await this.readProfile();\n\n const lines = existing ? existing.split(\"\\n\") : [];\n const existingBulletRaw = lines\n .filter((l) => l.startsWith(\"- \"))\n .map((l) => l.slice(2).trim());\n const existingNorms = existingBulletRaw.map(StorageManager.normalizeForDedup);\n\n const newBullets = updates.filter((u) => {\n const norm = StorageManager.normalizeForDedup(u);\n return !StorageManager.isFuzzyDuplicate(norm, existingNorms);\n });\n if (newBullets.length === 0) return;\n\n if (!existing) {\n const content = [\n \"# Behavioral Profile\",\n \"\",\n `*Last updated: ${new Date().toISOString()}*`,\n \"\",\n ...newBullets.map((b) => `- ${b}`),\n \"\",\n ].join(\"\\n\");\n await this.writeProfile(content);\n } else {\n const updatedTimestamp = existing.replace(\n /\\*Last updated:.*\\*/,\n `*Last updated: ${new Date().toISOString()}*`,\n );\n const withBullets = updatedTimestamp.trimEnd() + \"\\n\" + newBullets.map((b) => `- ${b}`).join(\"\\n\") + \"\\n\";\n await this.writeProfile(withBullets);\n }\n }\n\n /** Check if profile.md exceeds the max line cap and needs LLM consolidation */\n async profileNeedsConsolidation(triggerLines?: number): Promise<boolean> {\n const profile = await this.readProfile();\n if (!profile) return false;\n const lineCount = profile.split(\"\\n\").length;\n const threshold = typeof triggerLines === \"number\"\n ? Math.max(0, Math.floor(triggerLines))\n : StorageManager.PROFILE_MAX_LINES;\n return lineCount > threshold;\n }\n\n async readAllMemories(): Promise<MemoryFile[]> {\n // Deduplicate concurrent reads for the same directory so multiple\n // callers in the same recall share one disk scan.\n const inFlight = StorageManager.allMemoriesInFlight.get(this.baseDir);\n if (inFlight) return inFlight;\n\n const readPromise = this._readAllMemoriesFromDisk();\n StorageManager.allMemoriesInFlight.set(this.baseDir, readPromise);\n try {\n return await readPromise;\n } finally {\n // Only delete if we still own the slot — invalidateAllMemoriesCache()\n // may have already cleared it and a new read may have claimed it.\n if (StorageManager.allMemoriesInFlight.get(this.baseDir) === readPromise) {\n StorageManager.allMemoriesInFlight.delete(this.baseDir);\n }\n }\n }\n\n /** Invalidate the readAllMemories() cache after writes that add/remove memories. */\n /** Public cache invalidation for callers that need authoritative disk reads\n * (e.g. projection verify/rebuild). */\n invalidateAllMemoriesCacheForDir(): void {\n this.invalidateAllMemoriesCache();\n }\n\n /** Clear ALL static caches. Use in tests that write files directly\n * (bypassing StorageManager.writeMemory) to avoid stale reads. */\n static clearAllStaticCaches(): void {\n StorageManager.allMemoriesInFlight.clear();\n StorageManager.questionsCache.clear();\n }\n\n /** Cancel any in-flight concurrent read so the next readAllMemories()\n * starts a fresh disk scan and sees the just-written data. */\n private invalidateAllMemoriesCache(): void {\n StorageManager.allMemoriesInFlight.delete(this.baseDir);\n }\n\n private async _readAllMemoriesFromDisk(): Promise<MemoryFile[]> {\n // Collect all .md file paths first (directory traversal is sequential but fast),\n // then read files in parallel batches to avoid O(N) sequential I/O.\n // With 80k+ memory files, sequential reads can take 60+ seconds under load.\n const filePaths: string[] = [];\n\n const collectPaths = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n const subdirs: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n subdirs.push(fullPath);\n } else if (entry.name.endsWith(\".md\")) {\n filePaths.push(fullPath);\n }\n }\n // Recurse into subdirectories sequentially (directory tree is shallow)\n for (const subdir of subdirs) {\n await collectPaths(subdir);\n }\n } catch {\n // Directory doesn't exist yet\n }\n };\n\n await collectPaths(this.factsDir);\n await collectPaths(this.correctionsDir);\n\n if (filePaths.length === 0) return [];\n\n // Read all files in parallel batches of 50 to balance throughput and I/O pressure.\n const BATCH_SIZE = 50;\n const memories: MemoryFile[] = [];\n for (let i = 0; i < filePaths.length; i += BATCH_SIZE) {\n const batch = filePaths.slice(i, i + BATCH_SIZE);\n const results = await Promise.all(\n batch.map(async (fullPath) => {\n try {\n const raw = await readFile(fullPath, \"utf-8\");\n const parsed = parseFrontmatter(raw);\n if (!parsed) return null;\n return {\n path: fullPath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, fullPath),\n ),\n content: parsed.content,\n } satisfies MemoryFile;\n } catch {\n return null;\n }\n }),\n );\n for (const m of results) {\n if (m !== null) memories.push(m);\n }\n }\n return memories;\n }\n\n /**\n * Read archived memory markdown files under archive/.\n * Used by long-term recall fallback when hot recall has no hits.\n */\n async readArchivedMemories(): Promise<MemoryFile[]> {\n const memories: MemoryFile[] = [];\n const root = this.archiveDir;\n\n const readDir = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await readDir(fullPath);\n } else if (entry.name.endsWith(\".md\")) {\n try {\n const raw = await readFile(fullPath, \"utf-8\");\n const parsed = parseFrontmatter(raw);\n if (parsed) {\n memories.push({\n path: fullPath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, fullPath),\n ),\n content: parsed.content,\n });\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n } catch {\n // Directory doesn't exist yet\n }\n };\n\n await readDir(root);\n return memories;\n }\n\n /** Read a single memory file by its absolute path. Returns null if unreadable. */\n async readMemoryByPath(filePath: string): Promise<MemoryFile | null> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = parseFrontmatter(raw);\n if (parsed) {\n return {\n path: filePath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, filePath),\n ),\n content: parsed.content,\n };\n }\n\n // Entity files use a `# Name` + `**Type:** ...` markdown format rather than\n // YAML frontmatter. Build a synthetic MemoryFile so entity files returned by\n // the direct retrieval agent participate in boostSearchResults and last-recall\n // tracking rather than being silently dropped.\n const normalizedPath = filePath.split(path.sep).join(\"/\");\n if (normalizedPath.includes(\"/entities/\") && filePath.endsWith(\".md\")) {\n const entity = parseEntityFile(raw);\n if (!entity.name) return null;\n const nameWithoutExt = path.basename(filePath, \".md\");\n // Fall back to file mtime rather than new Date() so that entities without\n // an explicit Updated: timestamp are not treated as freshly created on every\n // read. Using new Date() would inflate boostSearchResults recency scores for\n // every entity that lacks a timestamp.\n // Use epoch as the last-resort fallback so that entities without a\n // parseable timestamp don't appear as \"freshly created\" and inflate scores.\n const fileMtime = entity.updated\n || await stat(filePath).then((s) => s.mtime.toISOString()).catch(() => new Date(0).toISOString());\n return {\n path: filePath,\n frontmatter: {\n id: nameWithoutExt,\n category: \"entity\",\n created: fileMtime,\n updated: fileMtime,\n source: \"entity_extraction\",\n confidence: 0.9,\n confidenceTier: confidenceTier(0.9),\n tags: entity.type ? [entity.type] : [],\n },\n content: raw,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n private resolveTierRootDir(tier: \"hot\" | \"cold\"): string {\n return tier === \"cold\" ? path.join(this.baseDir, \"cold\") : this.baseDir;\n }\n\n private resolveMemoryDateDir(memory: MemoryFile): string {\n const preferred = memory.frontmatter.created || memory.frontmatter.updated;\n const dateToken = (preferred ?? \"\").slice(0, 10);\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(dateToken)\n ? dateToken\n : new Date().toISOString().slice(0, 10);\n }\n\n private isArtifactMemory(memory: MemoryFile): boolean {\n if (memory.frontmatter.source === \"artifact\") return true;\n if (memory.frontmatter.artifactType !== undefined) return true;\n return /[\\\\/]artifacts[\\\\/]/.test(memory.path);\n }\n\n buildTierMemoryPath(memory: MemoryFile, tier: \"hot\" | \"cold\"): string {\n const root = this.resolveTierRootDir(tier);\n if (this.isArtifactMemory(memory)) {\n return path.join(root, \"artifacts\", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);\n }\n if (memory.frontmatter.category === \"correction\") {\n return path.join(root, \"corrections\", `${memory.frontmatter.id}.md`);\n }\n return path.join(root, \"facts\", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);\n }\n\n private async writeMemoryFileAtomic(targetPath: string, memory: MemoryFile): Promise<void> {\n const fileContent = `${serializeFrontmatter(memory.frontmatter)}\\n\\n${memory.content}\\n`;\n await mkdir(path.dirname(targetPath), { recursive: true });\n const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;\n try {\n await writeFile(tempPath, fileContent, \"utf-8\");\n await rename(tempPath, targetPath);\n this.invalidateAllMemoriesCache();\n } catch (err) {\n try {\n await unlink(tempPath);\n } catch {\n // best-effort cleanup\n }\n throw err;\n }\n }\n\n async moveMemoryToPath(memory: MemoryFile, targetPath: string): Promise<void> {\n await this.writeMemoryFileAtomic(targetPath, memory);\n const sourcePath = path.resolve(memory.path);\n const destPath = path.resolve(targetPath);\n if (sourcePath !== destPath) {\n try {\n await unlink(memory.path);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (!message.includes(\"ENOENT\")) {\n throw err;\n }\n }\n // Re-invalidate after the unlink — writeMemoryFileAtomic already\n // invalidated, but a concurrent readAllMemories() may have re-populated\n // the cache between the write and the unlink.\n this.invalidateAllMemoriesCache();\n }\n }\n\n async migrateMemoryToTier(\n memory: MemoryFile,\n targetTier: \"hot\" | \"cold\",\n ): Promise<{ changed: boolean; targetPath: string }> {\n const targetPath = this.buildTierMemoryPath(memory, targetTier);\n const sourcePath = path.resolve(memory.path);\n const destPath = path.resolve(targetPath);\n if (sourcePath === destPath) {\n return { changed: false, targetPath };\n }\n\n const existing = await this.readMemoryByPath(targetPath);\n if (existing?.frontmatter.id === memory.frontmatter.id) {\n try {\n await unlink(memory.path);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (!message.includes(\"ENOENT\")) {\n throw err;\n }\n }\n this.bumpMemoryStatusVersion();\n return { changed: false, targetPath };\n }\n\n await this.moveMemoryToPath(memory, targetPath);\n this.invalidateAllMemoriesCache();\n this.bumpMemoryStatusVersion();\n return { changed: true, targetPath };\n }\n\n private get archiveDir(): string {\n return path.join(this.baseDir, \"archive\");\n }\n\n /**\n * Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.\n * Updates frontmatter with archived status before moving.\n * Returns the new file path on success, null on failure.\n */\n async archiveMemory(\n memory: MemoryFile,\n lifecycle?: MemoryLifecycleEventWriteOptions,\n ): Promise<string | null> {\n try {\n const now = lifecycle?.at ?? new Date();\n const today = now.toISOString().slice(0, 10);\n const destDir = path.join(this.archiveDir, today);\n await mkdir(destDir, { recursive: true });\n\n // Update frontmatter to reflect archived status\n const updatedFm: MemoryFrontmatter = {\n ...memory.frontmatter,\n status: \"archived\",\n archivedAt: now.toISOString(),\n updated: now.toISOString(),\n };\n\n const fileContent = `${serializeFrontmatter(updatedFm)}\\n\\n${memory.content}\\n`;\n const destPath = path.join(destDir, path.basename(memory.path));\n\n // Write to archive location first, then remove original\n await writeFile(destPath, fileContent, \"utf-8\");\n await unlink(memory.path);\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\n \"storage.archiveMemory\",\n {\n memoryId: memory.frontmatter.id,\n eventType: \"archived\",\n timestamp: updatedFm.archivedAt ?? updatedFm.updated,\n actor: lifecycle?.actor ?? \"storage.archiveMemory\",\n reasonCode: lifecycle?.reasonCode,\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updatedFm, destPath),\n relatedMemoryIds: lifecycle?.relatedMemoryIds,\n correlationId: lifecycle?.correlationId,\n },\n lifecycle?.ruleVersion,\n );\n this.bumpMemoryStatusVersion();\n\n log.debug(`archived memory ${memory.frontmatter.id} → ${destPath}`);\n return destPath;\n } catch (err) {\n log.warn(`failed to archive memory ${memory.frontmatter.id}: ${err}`);\n return null;\n }\n }\n\n async readEntities(): Promise<string[]> {\n try {\n const entries = await readdir(this.entitiesDir);\n return entries.filter((e) => e.endsWith(\".md\")).map((e) => e.replace(\".md\", \"\"));\n } catch {\n return [];\n }\n }\n\n async readEntity(name: string): Promise<string> {\n try {\n return await readFile(path.join(this.entitiesDir, `${name}.md`), \"utf-8\");\n } catch {\n return \"\";\n }\n }\n\n /** Return sorted list of entity filenames (without .md extension) */\n async listEntityNames(): Promise<string[]> {\n try {\n const entries = await readdir(this.entitiesDir);\n return entries\n .filter((e) => e.endsWith(\".md\"))\n .map((e) => e.replace(\".md\", \"\"))\n .sort();\n } catch {\n return [];\n }\n }\n\n /**\n * Find an existing entity that fuzzy-matches the proposed name.\n * Returns the existing entity filename (without .md) or null if no match.\n *\n * Matching priority:\n * 1. Exact normalized match (handled by normalizeEntityName already)\n * 2. Dehyphenated match: \"jane-doe\" vs \"janedoe\"\n * 3. Substring containment: \"handle-janedoe\" contains \"janedoe\"\n * 4. Levenshtein ≤ 2 on dehyphenated names\n */\n async findMatchingEntity(proposedName: string, type: string): Promise<string | null> {\n const existing = await this.listEntityNames();\n if (existing.length === 0) return null;\n\n const typePrefix = `${type.toLowerCase()}-`;\n // Extract the name part from the proposed normalized name\n const proposedFull = normalizeEntityName(proposedName, type);\n const proposedNamePart = proposedFull.startsWith(typePrefix)\n ? proposedFull.slice(typePrefix.length)\n : proposedFull;\n const proposedDehyph = dehyphenate(proposedNamePart);\n\n // Only compare against entities of the same type\n const sameType = existing.filter((e) => e.startsWith(typePrefix));\n\n for (const entity of sameType) {\n const entityNamePart = entity.slice(typePrefix.length);\n const entityDehyph = dehyphenate(entityNamePart);\n\n // Already the exact normalized form\n if (entity === proposedFull) return entity;\n\n // Dehyphenated exact match\n if (entityDehyph === proposedDehyph) return entity;\n\n // Substring containment (shorter must be >60% length of longer)\n const shorter = proposedDehyph.length <= entityDehyph.length ? proposedDehyph : entityDehyph;\n const longer = proposedDehyph.length > entityDehyph.length ? proposedDehyph : entityDehyph;\n if (shorter.length > 3 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {\n return entity;\n }\n\n // Levenshtein distance ≤ 2 (only for names of reasonable length)\n if (proposedDehyph.length >= 4 && entityDehyph.length >= 4) {\n const dist = levenshtein(proposedDehyph, entityDehyph);\n if (dist <= 2) return entity;\n }\n }\n\n return null;\n }\n\n async invalidateMemory(id: string): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === id);\n if (!memory) return false;\n\n try {\n await unlink(memory.path);\n this.invalidateAllMemoriesCache();\n this.bumpMemoryStatusVersion();\n log.debug(`invalidated memory ${id}`);\n return true;\n } catch {\n return false;\n }\n }\n\n async updateMemory(\n id: string,\n newContent: string,\n options?: { supersedes?: string; lineage?: string[]; actor?: string },\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === id);\n if (!memory) return false;\n\n const mergedLineage = [\n ...(memory.frontmatter.lineage ?? []),\n ...(options?.lineage ?? []),\n ].filter((v, i, a) => a.indexOf(v) === i); // dedupe\n\n const updated: MemoryFrontmatter = {\n ...memory.frontmatter,\n updated: new Date().toISOString(),\n supersedes: options?.supersedes ?? memory.frontmatter.supersedes,\n lineage: mergedLineage.length > 0 ? mergedLineage : undefined,\n };\n const sanitized = sanitizeMemoryContent(newContent);\n if (!sanitized.clean) {\n log.warn(`updated memory content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n const fileContent = `${serializeFrontmatter(updated)}\\n\\n${sanitized.text}\\n`;\n await writeFile(memory.path, fileContent, \"utf-8\");\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.updateMemory\", {\n memoryId: id,\n eventType: \"updated\",\n timestamp: updated.updated,\n actor: options?.actor ?? \"storage.updateMemory\",\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updated, memory.path),\n relatedMemoryIds: [\n ...(updated.supersedes ? [updated.supersedes] : []),\n ...((updated.lineage ?? []).filter(Boolean)),\n ],\n });\n log.debug(`updated memory ${id}`);\n return true;\n }\n\n /**\n * Update frontmatter fields without changing memory content.\n * Returns false when the memory is not found.\n */\n async writeMemoryFrontmatter(\n memory: MemoryFile,\n patch: Partial<MemoryFrontmatter>,\n lifecycle?: MemoryLifecycleEventWriteOptions,\n ): Promise<boolean> {\n const beforeStatus = memory.frontmatter.status ?? \"active\";\n const updated: MemoryFrontmatter = {\n ...memory.frontmatter,\n ...patch,\n };\n const afterStatus = updated.status ?? \"active\";\n\n const fileContent = `${serializeFrontmatter(updated)}\\n\\n${memory.content}\\n`;\n await writeFile(memory.path, fileContent, \"utf-8\");\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\n \"storage.writeMemoryFrontmatter\",\n {\n memoryId: updated.id,\n eventType: this.frontmatterPatchEventType(memory.frontmatter, updated),\n timestamp: updated.updated ?? new Date().toISOString(),\n actor: lifecycle?.actor ?? \"storage.writeMemoryFrontmatter\",\n reasonCode: lifecycle?.reasonCode,\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updated, memory.path),\n relatedMemoryIds: [\n ...(lifecycle?.relatedMemoryIds ?? []),\n ...(updated.supersededBy ? [updated.supersededBy] : []),\n ...(updated.supersedes ? [updated.supersedes] : []),\n ],\n correlationId: lifecycle?.correlationId,\n },\n lifecycle?.ruleVersion,\n );\n if (beforeStatus !== afterStatus) {\n this.bumpMemoryStatusVersion();\n }\n return true;\n }\n\n /**\n * Update frontmatter by memory ID.\n * Prefer writeMemoryFrontmatter(memory, patch) in batch loops to avoid full-corpus rescans.\n */\n async updateMemoryFrontmatter(\n id: string,\n patch: Partial<MemoryFrontmatter>,\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === id);\n if (!memory) return false;\n return this.writeMemoryFrontmatter(memory, patch);\n }\n\n /** Remove memories past their TTL expiresAt date */\n async cleanExpiredTTL(): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n const now = Date.now();\n const deleted: MemoryFile[] = [];\n\n for (const m of memories) {\n if (!m.frontmatter.expiresAt) continue;\n const expiresAt = new Date(m.frontmatter.expiresAt).getTime();\n if (expiresAt < now) {\n try {\n await unlink(m.path);\n deleted.push(m);\n log.debug(`cleaned expired memory ${m.frontmatter.id} (TTL expired)`);\n } catch {\n // Ignore\n }\n }\n }\n\n if (deleted.length > 0) {\n this.invalidateAllMemoriesCache();\n this.bumpMemoryStatusVersion();\n }\n\n return deleted;\n }\n\n async loadBuffer(): Promise<BufferState> {\n const bufferPath = path.join(this.stateDir, \"buffer.json\");\n try {\n const raw = await readFile(bufferPath, \"utf-8\");\n return JSON.parse(raw) as BufferState;\n } catch {\n return { turns: [], lastExtractionAt: null, extractionCount: 0 };\n }\n }\n\n async saveBuffer(state: BufferState): Promise<void> {\n await this.ensureDirectories();\n const bufferPath = path.join(this.stateDir, \"buffer.json\");\n await writeFile(bufferPath, JSON.stringify(state, null, 2), \"utf-8\");\n }\n\n async loadMeta(): Promise<MetaState> {\n const metaPath = path.join(this.stateDir, \"meta.json\");\n try {\n const raw = await readFile(metaPath, \"utf-8\");\n return JSON.parse(raw) as MetaState;\n } catch {\n return {\n extractionCount: 0,\n lastExtractionAt: null,\n lastConsolidationAt: null,\n totalMemories: 0,\n totalEntities: 0,\n };\n }\n }\n\n async saveMeta(state: MetaState): Promise<void> {\n await this.ensureDirectories();\n const metaPath = path.join(this.stateDir, \"meta.json\");\n await writeFile(metaPath, JSON.stringify(state, null, 2), \"utf-8\");\n }\n\n async appendMemoryActionEvents(events: MemoryActionEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n const nowIso = new Date().toISOString();\n const payload = events.map((event) => {\n const normalized: MemoryActionEvent = {\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n };\n return `${JSON.stringify(normalized)}\\n`;\n }).join(\"\");\n\n await appendFile(this.memoryActionsPath, payload, \"utf-8\");\n return events.length;\n }\n\n async appendMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n const nowIso = new Date().toISOString();\n const payload = events.map((event) => {\n const normalized: MemoryLifecycleEvent = {\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n };\n return `${JSON.stringify(normalized)}\\n`;\n }).join(\"\");\n\n await appendFile(this.memoryLifecycleLedgerPath, payload, \"utf-8\");\n return events.length;\n }\n\n async appendBehaviorSignals(events: BehaviorSignalEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n let existingKeys = new Set<string>();\n try {\n const raw = await readFile(this.behaviorSignalsPath, \"utf-8\");\n const lines = raw.split(\"\\n\");\n for (const line of lines) {\n const row = line.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<BehaviorSignalEvent>;\n if (typeof parsed.memoryId === \"string\" && typeof parsed.signalHash === \"string\") {\n existingKeys.add(`${parsed.memoryId}:${parsed.signalHash}`);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n } catch {\n existingKeys = new Set<string>();\n }\n\n const nowIso = new Date().toISOString();\n const deduped: BehaviorSignalEvent[] = [];\n for (const event of events) {\n const key = `${event.memoryId}:${event.signalHash}`;\n if (existingKeys.has(key)) continue;\n existingKeys.add(key);\n deduped.push({\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n });\n }\n\n if (deduped.length === 0) return 0;\n const payload = deduped.map((event) => `${JSON.stringify(event)}\\n`).join(\"\");\n await appendFile(this.behaviorSignalsPath, payload, \"utf-8\");\n return deduped.length;\n }\n\n async appendReextractJobs(events: ReextractJobRequest[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n const filePath = path.join(this.stateDir, \"reextract-jobs.jsonl\");\n const lines = events.map((event) => JSON.stringify(event)).join(\"\\n\") + \"\\n\";\n try {\n await appendFile(filePath, lines, \"utf-8\");\n return events.length;\n } catch {\n return 0;\n }\n }\n\n async readReextractJobs(limit: number = 200): Promise<ReextractJobRequest[]> {\n const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1000, Math.floor(limit))) : 200;\n const filePath = path.join(this.stateDir, \"reextract-jobs.jsonl\");\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const lines = raw.split(\"\\n\").filter((line) => line.trim().length > 0);\n const parsed: ReextractJobRequest[] = [];\n for (const line of lines) {\n try {\n const record = JSON.parse(line) as Partial<ReextractJobRequest>;\n if (\n typeof record.memoryId !== \"string\" ||\n record.memoryId.length === 0 ||\n typeof record.model !== \"string\" ||\n record.model.length === 0 ||\n typeof record.requestedAt !== \"string\" ||\n record.requestedAt.length === 0 ||\n record.source !== \"cli-migrate\"\n ) {\n continue;\n }\n parsed.push({\n memoryId: record.memoryId,\n model: record.model,\n requestedAt: record.requestedAt,\n source: \"cli-migrate\",\n });\n } catch {\n continue;\n }\n }\n return parsed.slice(-safeLimit);\n } catch {\n return [];\n }\n }\n\n async readBehaviorSignals(limit: number = 200): Promise<BehaviorSignalEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n try {\n const raw = await readFile(this.behaviorSignalsPath, \"utf-8\");\n const out: BehaviorSignalEvent[] = [];\n const lines = raw.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0 && out.length < cappedLimit; i -= 1) {\n const row = lines[i]?.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<BehaviorSignalEvent>;\n if (\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.namespace === \"string\" &&\n typeof parsed.memoryId === \"string\" &&\n typeof parsed.category === \"string\" &&\n typeof parsed.signalType === \"string\" &&\n typeof parsed.direction === \"string\" &&\n typeof parsed.confidence === \"number\" &&\n typeof parsed.signalHash === \"string\" &&\n typeof parsed.source === \"string\"\n ) {\n out.push(parsed as BehaviorSignalEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return out.reverse();\n } catch {\n return [];\n }\n }\n\n async readMemoryActionEvents(limit: number = 200): Promise<MemoryActionEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n try {\n const raw = await readFile(this.memoryActionsPath, \"utf-8\");\n const out: MemoryActionEvent[] = [];\n const lines = raw.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0 && out.length < cappedLimit; i -= 1) {\n const line = lines[i]?.trim();\n if (!line) continue;\n try {\n const parsed = JSON.parse(line) as Partial<MemoryActionEvent>;\n if (\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.action === \"string\" &&\n typeof parsed.outcome === \"string\"\n ) {\n out.push(parsed as MemoryActionEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return out.reverse();\n } catch {\n return [];\n }\n }\n\n async readAllMemoryLifecycleEvents(): Promise<MemoryLifecycleEvent[]> {\n try {\n const raw = await readFile(this.memoryLifecycleLedgerPath, \"utf-8\");\n const out: MemoryLifecycleEvent[] = [];\n const lines = raw.split(\"\\n\");\n for (const line of lines) {\n const row = line.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<MemoryLifecycleEvent>;\n if (\n typeof parsed.eventId === \"string\" &&\n typeof parsed.memoryId === \"string\" &&\n typeof parsed.eventType === \"string\" &&\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.actor === \"string\" &&\n typeof parsed.ruleVersion === \"string\"\n ) {\n out.push(parsed as MemoryLifecycleEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return sortMemoryLifecycleEvents(out);\n } catch {\n return [];\n }\n }\n\n async readMemoryLifecycleEvents(limit: number = 200): Promise<MemoryLifecycleEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n const events = await this.readAllMemoryLifecycleEvents();\n return events.slice(-cappedLimit);\n }\n\n async writeCompressionGuidelines(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelinesPath, content, \"utf-8\");\n }\n\n async readCompressionGuidelines(): Promise<string | null> {\n try {\n return await readFile(this.compressionGuidelinesPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeCompressionGuidelineDraft(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelineDraftPath, content, \"utf-8\");\n }\n\n async readCompressionGuidelineDraft(): Promise<string | null> {\n try {\n return await readFile(this.compressionGuidelineDraftPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeCompressionGuidelineOptimizerState(\n state: CompressionGuidelineOptimizerState,\n ): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelineStatePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n }\n\n async writeCompressionGuidelineDraftState(\n state: CompressionGuidelineOptimizerState,\n ): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.compressionGuidelineDraftStatePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n }\n\n async readCompressionGuidelineOptimizerState(): Promise<CompressionGuidelineOptimizerState | null> {\n return this.readCompressionGuidelineStateFile(this.compressionGuidelineStatePath);\n }\n\n async readCompressionGuidelineDraftState(): Promise<CompressionGuidelineOptimizerState | null> {\n return this.readCompressionGuidelineStateFile(this.compressionGuidelineDraftStatePath);\n }\n\n async activateCompressionGuidelineDraft(options?: {\n expectedContentHash?: string;\n expectedGuidelineVersion?: number;\n }): Promise<boolean> {\n const [draftContent, draftState] = await Promise.all([\n this.readCompressionGuidelineDraft(),\n this.readCompressionGuidelineDraftState(),\n ]);\n if (!draftContent || !draftState) return false;\n if (\n typeof options?.expectedContentHash === \"string\" &&\n options.expectedContentHash.length > 0 &&\n draftState.contentHash !== options.expectedContentHash\n ) {\n return false;\n }\n if (\n typeof options?.expectedGuidelineVersion === \"number\" &&\n Number.isFinite(options.expectedGuidelineVersion) &&\n draftState.guidelineVersion !== options.expectedGuidelineVersion\n ) {\n return false;\n }\n if (draftState.contentHash) {\n const contentHash = createHash(\"sha256\").update(draftContent).digest(\"hex\");\n if (contentHash !== draftState.contentHash) return false;\n }\n\n await this.writeCompressionGuidelines(draftContent);\n await this.writeCompressionGuidelineOptimizerState({\n ...draftState,\n activationState: \"active\",\n });\n await Promise.all([\n unlink(this.compressionGuidelineDraftPath).catch(() => undefined),\n unlink(this.compressionGuidelineDraftStatePath).catch(() => undefined),\n ]);\n return true;\n }\n\n private async readCompressionGuidelineStateFile(\n filePath: string,\n ): Promise<CompressionGuidelineOptimizerState | null> {\n const isFiniteNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value) && Number.isInteger(value) && value >= 0;\n const isValidActionSummary = (\n value: unknown,\n ): value is NonNullable<CompressionGuidelineOptimizerState[\"actionSummaries\"]>[number] => {\n if (!value || typeof value !== \"object\") return false;\n const summary = value as NonNullable<CompressionGuidelineOptimizerState[\"actionSummaries\"]>[number];\n return (\n typeof summary.action === \"string\" &&\n isFiniteNonNegativeInteger(summary.total) &&\n summary.outcomes !== null &&\n typeof summary.outcomes === \"object\" &&\n isFiniteNonNegativeInteger(summary.outcomes.applied) &&\n isFiniteNonNegativeInteger(summary.outcomes.skipped) &&\n isFiniteNonNegativeInteger(summary.outcomes.failed) &&\n summary.quality !== null &&\n typeof summary.quality === \"object\" &&\n isFiniteNonNegativeInteger(summary.quality.good) &&\n isFiniteNonNegativeInteger(summary.quality.poor) &&\n isFiniteNonNegativeInteger(summary.quality.unknown)\n );\n };\n const isValidRuleUpdate = (\n value: unknown,\n ): value is NonNullable<CompressionGuidelineOptimizerState[\"ruleUpdates\"]>[number] => {\n if (!value || typeof value !== \"object\") return false;\n const rule = value as NonNullable<CompressionGuidelineOptimizerState[\"ruleUpdates\"]>[number];\n return (\n typeof rule.action === \"string\" &&\n typeof rule.delta === \"number\" &&\n Number.isFinite(rule.delta) &&\n (rule.direction === \"increase\" || rule.direction === \"decrease\" || rule.direction === \"hold\") &&\n (rule.confidence === \"low\" || rule.confidence === \"medium\" || rule.confidence === \"high\") &&\n Array.isArray(rule.notes) &&\n rule.notes.every((note) => typeof note === \"string\")\n );\n };\n\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<CompressionGuidelineOptimizerState>;\n const sourceWindow = parsed?.sourceWindow as Partial<CompressionGuidelineOptimizerState[\"sourceWindow\"]>;\n const eventCounts = parsed?.eventCounts as Partial<CompressionGuidelineOptimizerState[\"eventCounts\"]>;\n const activationState =\n parsed?.activationState === \"draft\" || parsed?.activationState === \"active\"\n ? parsed.activationState\n : undefined;\n const contentHash =\n typeof parsed?.contentHash === \"string\" && parsed.contentHash.length > 0\n ? parsed.contentHash\n : undefined;\n const actionSummaries = Array.isArray(parsed?.actionSummaries)\n ? parsed.actionSummaries.filter(isValidActionSummary)\n : undefined;\n const ruleUpdates = Array.isArray(parsed?.ruleUpdates)\n ? parsed.ruleUpdates.filter(isValidRuleUpdate)\n : undefined;\n if (\n !isFiniteNonNegativeInteger(parsed?.version) ||\n typeof parsed?.updatedAt !== \"string\" ||\n parsed.updatedAt.length === 0 ||\n !sourceWindow ||\n typeof sourceWindow.from !== \"string\" ||\n sourceWindow.from.length === 0 ||\n typeof sourceWindow.to !== \"string\" ||\n sourceWindow.to.length === 0 ||\n !eventCounts ||\n !isFiniteNonNegativeInteger(eventCounts.total) ||\n !isFiniteNonNegativeInteger(eventCounts.applied) ||\n !isFiniteNonNegativeInteger(eventCounts.skipped) ||\n !isFiniteNonNegativeInteger(eventCounts.failed) ||\n !isFiniteNonNegativeInteger(parsed?.guidelineVersion)\n ) {\n return null;\n }\n\n return {\n version: parsed.version,\n updatedAt: parsed.updatedAt,\n sourceWindow: {\n from: sourceWindow.from,\n to: sourceWindow.to,\n },\n eventCounts: {\n total: eventCounts.total,\n applied: eventCounts.applied,\n skipped: eventCounts.skipped,\n failed: eventCounts.failed,\n },\n guidelineVersion: parsed.guidelineVersion,\n ...(contentHash ? { contentHash } : {}),\n ...(activationState ? { activationState } : {}),\n ...(actionSummaries ? { actionSummaries } : {}),\n ...(ruleUpdates ? { ruleUpdates } : {}),\n };\n } catch {\n return null;\n }\n }\n\n async writeIdentityAnchor(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.identityAnchorPath, content, \"utf-8\");\n }\n\n async readIdentityAnchor(): Promise<string | null> {\n try {\n return await readFile(this.identityAnchorPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async appendContinuityIncident(input: ContinuityIncidentOpenInput): Promise<ContinuityIncidentRecord> {\n await this.ensureDirectories();\n const now = new Date();\n const nowIso = now.toISOString();\n const date = nowIso.slice(0, 10);\n const id = this.generateId(\"incident\");\n const incident = createContinuityIncidentRecord(id, input, nowIso);\n const filePath = path.join(this.identityIncidentsDir, `${date}-${id}.md`);\n await writeFile(filePath, serializeContinuityIncident(incident), \"utf-8\");\n return { ...incident, filePath };\n }\n\n async readContinuityIncidents(\n limit: number = 200,\n state: \"open\" | \"closed\" | \"all\" = \"all\",\n ): Promise<ContinuityIncidentRecord[]> {\n const normalizedLimit = Number.isFinite(limit) ? Math.floor(limit) : 0;\n const cappedLimit = Math.max(0, normalizedLimit);\n if (cappedLimit === 0) return [];\n\n try {\n const candidates = await this.readContinuityIncidentFileNames();\n const incidents: ContinuityIncidentRecord[] = [];\n\n for (const file of candidates) {\n if (incidents.length >= cappedLimit) break;\n const filePath = path.join(this.identityIncidentsDir, file);\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = parseContinuityIncident(raw);\n if (!parsed) continue;\n if (state !== \"all\" && parsed.state !== state) continue;\n incidents.push({ ...parsed, filePath });\n } catch {\n // Fail-open on malformed/missing files.\n }\n }\n return incidents;\n } catch {\n return [];\n }\n }\n\n async closeContinuityIncident(\n id: string,\n closure: ContinuityIncidentCloseInput,\n ): Promise<ContinuityIncidentRecord | null> {\n const directFilePath = await this.findContinuityIncidentFilePathById(id);\n const target = directFilePath ? await this.readContinuityIncidentFile(directFilePath) : null;\n if (!target || !directFilePath) return null;\n if (target.state === \"closed\") return target;\n\n const closed = closeContinuityIncidentRecord(target, closure, new Date().toISOString());\n await writeFile(directFilePath, serializeContinuityIncident(closed), \"utf-8\");\n return { ...closed, filePath: directFilePath };\n }\n\n async writeIdentityAudit(period: \"weekly\" | \"monthly\", key: string, content: string): Promise<string> {\n await this.ensureDirectories();\n const safeKey = this.sanitizeIdentityAuditKey(key);\n const dir = period === \"weekly\" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;\n const filePath = path.join(dir, `${safeKey}.md`);\n await writeFile(filePath, content, \"utf-8\");\n return filePath;\n }\n\n async readIdentityAudit(period: \"weekly\" | \"monthly\", key: string): Promise<string | null> {\n try {\n const safeKey = this.sanitizeIdentityAuditKey(key);\n const dir = period === \"weekly\" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;\n return await readFile(path.join(dir, `${safeKey}.md`), \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeIdentityImprovementLoops(content: string): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.identityImprovementLoopsPath, content, \"utf-8\");\n }\n\n async readIdentityImprovementLoops(): Promise<string | null> {\n try {\n return await readFile(this.identityImprovementLoopsPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async readIdentityImprovementLoopRegister(): Promise<ContinuityImprovementLoop[]> {\n const raw = await this.readIdentityImprovementLoops();\n if (!raw) return [];\n return parseContinuityImprovementLoops(raw);\n }\n\n async upsertIdentityImprovementLoop(input: ContinuityLoopUpsertInput): Promise<ContinuityImprovementLoop> {\n const nowIso = new Date().toISOString();\n const raw = await this.readIdentityImprovementLoops();\n const { markdown, loop } = upsertContinuityLoopInMarkdown(raw, input, nowIso);\n await this.writeIdentityImprovementLoops(markdown);\n return loop;\n }\n\n async reviewIdentityImprovementLoop(\n id: string,\n input: ContinuityLoopReviewInput,\n ): Promise<ContinuityImprovementLoop | null> {\n const raw = await this.readIdentityImprovementLoops();\n const { markdown, loop } = reviewContinuityLoopInMarkdown(raw, id, input, new Date().toISOString());\n if (!loop) return null;\n await this.writeIdentityImprovementLoops(markdown);\n return loop;\n }\n\n // ---------------------------------------------------------------------------\n // Question storage\n // ---------------------------------------------------------------------------\n\n private generateId(prefix: string = \"m\"): string {\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 4);\n return `${prefix}-${ts}-${rand}`;\n }\n\n private async readContinuityIncidentFileNames(): Promise<string[]> {\n const files = await readdir(this.identityIncidentsDir);\n return files\n .filter((file) => file.endsWith(\".md\"))\n .sort()\n .reverse();\n }\n\n private async readContinuityIncidentFile(filePath: string): Promise<ContinuityIncidentRecord | null> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = parseContinuityIncident(raw);\n return parsed ? { ...parsed, filePath } : null;\n } catch {\n return null;\n }\n }\n\n private async findContinuityIncidentFilePathById(id: string): Promise<string | null> {\n const fileNames = await this.readContinuityIncidentFileNames();\n const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));\n if (directMatch) {\n const directPath = path.join(this.identityIncidentsDir, directMatch);\n const parsed = await this.readContinuityIncidentFile(directPath);\n if (parsed?.id === id) return directPath;\n }\n\n for (const fileName of fileNames) {\n const filePath = path.join(this.identityIncidentsDir, fileName);\n const parsed = await this.readContinuityIncidentFile(filePath);\n if (parsed?.id === id) return filePath;\n }\n return null;\n }\n\n private sanitizeIdentityAuditKey(key: string): string {\n const trimmed = key.trim();\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(trimmed) || trimmed.includes(\"..\")) {\n throw new Error(\"Invalid identity audit key\");\n }\n return trimmed;\n }\n\n async writeQuestion(\n question: string,\n context: string,\n priority: number,\n ): Promise<string> {\n await mkdir(this.questionsDir, { recursive: true });\n\n const id = this.generateId(\"q\");\n const frontmatter = {\n id,\n created: new Date().toISOString(),\n priority,\n resolved: false,\n };\n\n const content = `---\\n${Object.entries(frontmatter).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(\"\\n\")}\\n---\\n\\n${question}\\n\\n**Context:** ${context}\\n`;\n\n const filePath = path.join(this.questionsDir, `${id}.md`);\n await writeFile(filePath, content, \"utf-8\");\n\n log.debug(`wrote question ${id} to ${filePath}`);\n this.invalidateQuestionsCache();\n return id;\n }\n\n async readQuestions(\n opts?: { unresolvedOnly?: boolean },\n ): Promise<\n Array<{\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n }>\n > {\n const cacheKey = this.questionsDir;\n const cached = StorageManager.questionsCache.get(cacheKey);\n if (cached && Date.now() - cached.loadedAt < StorageManager.QUESTIONS_CACHE_TTL_MS) {\n // Check dir mtime for cross-process invalidation — if another process\n // wrote/resolved a question, the directory mtime will be newer than loadedAt.\n try {\n const dirStat = await stat(this.questionsDir);\n if (dirStat.mtimeMs <= cached.loadedAt) {\n const all = cached.questions;\n return opts?.unresolvedOnly ? all.filter((q) => !q.resolved) : all;\n }\n } catch {\n // Dir doesn't exist — fall through to re-read\n }\n }\n\n try {\n const files = await readdir(this.questionsDir);\n const questions = [];\n for (const file of files) {\n if (!file.endsWith(\".md\")) continue;\n const filePath = path.join(this.questionsDir, file);\n const raw = await readFile(filePath, \"utf-8\");\n const parsed = this.parseQuestionFile(raw, filePath);\n if (parsed) {\n questions.push(parsed);\n }\n }\n const sorted = questions.sort((a, b) => b.priority - a.priority);\n StorageManager.questionsCache.set(cacheKey, { questions: sorted, loadedAt: Date.now() });\n return opts?.unresolvedOnly ? sorted.filter((q) => !q.resolved) : sorted;\n } catch {\n return [];\n }\n }\n\n /** Invalidate the questions cache (call after writing a question). */\n invalidateQuestionsCache(): void {\n StorageManager.questionsCache.delete(this.questionsDir);\n }\n\n private parseQuestionFile(\n raw: string,\n filePath: string,\n ): {\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n } | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n\\n([\\s\\S]*)$/);\n if (!match) return null;\n\n const frontmatterStr = match[1];\n const body = match[2].trim();\n\n // Parse frontmatter\n const id =\n this.extractFrontmatterValue(frontmatterStr, \"id\") ??\n path.basename(filePath, \".md\");\n const created =\n this.extractFrontmatterValue(frontmatterStr, \"created\") ?? \"\";\n const priority = parseFloat(\n this.extractFrontmatterValue(frontmatterStr, \"priority\") ?? \"0.5\",\n );\n const resolved =\n this.extractFrontmatterValue(frontmatterStr, \"resolved\") === \"true\";\n\n // Extract question and context from body\n const contextMatch = body.match(/\\*\\*Context:\\*\\*\\s*(.*)/);\n const question = contextMatch\n ? body.slice(0, contextMatch.index).trim()\n : body;\n const context = contextMatch ? contextMatch[1].trim() : \"\";\n\n return { id, question, context, priority, resolved, created, filePath };\n }\n\n private extractFrontmatterValue(\n frontmatter: string,\n key: string,\n ): string | null {\n const match = frontmatter.match(\n new RegExp(`^${key}:\\\\s*\"?([^\"\\\\n]*)\"?`, \"m\"),\n );\n return match ? match[1] : null;\n }\n\n async resolveQuestion(id: string): Promise<boolean> {\n const questions = await this.readQuestions();\n const q = questions.find((q) => q.id === id);\n if (!q) return false;\n\n let raw = await readFile(q.filePath, \"utf-8\");\n raw = raw.replace(/resolved: false/, \"resolved: true\");\n raw = raw.replace(\n /---\\n\\n/,\n `resolvedAt: \"${new Date().toISOString()}\"\\n---\\n\\n`,\n );\n await writeFile(q.filePath, raw, \"utf-8\");\n log.debug(`resolved question ${id}`);\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Identity file\n // ---------------------------------------------------------------------------\n\n async readIdentity(workspaceDir: string, namespace?: string): Promise<string> {\n const identityPath = this.identityFilePath(workspaceDir, namespace);\n try {\n return await readFile(identityPath, \"utf-8\");\n } catch {\n return \"\";\n }\n }\n\n async writeIdentity(workspaceDir: string, content: string, namespace?: string): Promise<void> {\n const identityPath = this.identityFilePath(workspaceDir, namespace);\n await writeFile(identityPath, content, \"utf-8\");\n log.debug(`wrote consolidated IDENTITY.md (${content.length} chars)`);\n }\n\n /** Max size for IDENTITY.md before we stop appending reflections (15KB leaves room under 20KB gateway limit) */\n private static readonly IDENTITY_MAX_BYTES = 15_000;\n /** Minimum interval between reflections (1 hour) */\n private static readonly REFLECTION_COOLDOWN_MS = 60 * 60 * 1000;\n\n async appendToIdentity(\n workspaceDir: string,\n reflection: string,\n opts?: { hygiene?: FileHygieneConfig; namespace?: string },\n ): Promise<void> {\n const identityPath = this.identityFilePath(workspaceDir, opts?.namespace);\n\n let existing = \"\";\n try {\n existing = await readFile(identityPath, \"utf-8\");\n } catch {\n // File doesn't exist yet\n }\n\n const hygiene = opts?.hygiene;\n const rotateEnabled =\n hygiene?.enabled === true &&\n hygiene.rotateEnabled === true &&\n Array.isArray(hygiene.rotatePaths) &&\n hygiene.rotatePaths.includes(path.basename(identityPath));\n\n // Rotation/splitting: preserve full history, keep the bootstrap file small.\n if (rotateEnabled) {\n const maxBytes = hygiene.rotateMaxBytes;\n if (existing.length > maxBytes) {\n const archiveDir = path.join(workspaceDir, hygiene.archiveDir);\n const { newContent } = await rotateMarkdownFileToArchive({\n filePath: identityPath,\n archiveDir,\n archivePrefix: \"IDENTITY\",\n keepTailChars: hygiene.rotateKeepTailChars,\n });\n await writeFile(identityPath, newContent, \"utf-8\");\n existing = newContent;\n log.info(\n `rotated IDENTITY.md to archive (size=${existing.length} chars, maxBytes=${maxBytes})`,\n );\n }\n } else {\n // Legacy behavior: skip if file is too large\n if (existing.length > StorageManager.IDENTITY_MAX_BYTES) {\n log.debug(`IDENTITY.md is ${existing.length} chars (limit ${StorageManager.IDENTITY_MAX_BYTES}); skipping reflection`);\n return;\n }\n }\n\n // Rate-limit: skip if last reflection was less than 1 hour ago\n const lastMatch = existing.match(/## Reflection — (\\S+)\\s*$/m);\n if (lastMatch) {\n // Find the LAST reflection timestamp\n const allMatches = [...existing.matchAll(/## Reflection — (\\S+)/g)];\n if (allMatches.length > 0) {\n const lastTimestamp = allMatches[allMatches.length - 1][1];\n const elapsed = Date.now() - new Date(lastTimestamp).getTime();\n if (elapsed < StorageManager.REFLECTION_COOLDOWN_MS) {\n log.debug(`reflection cooldown: ${Math.round(elapsed / 1000)}s since last (need ${StorageManager.REFLECTION_COOLDOWN_MS / 1000}s)`);\n return;\n }\n }\n }\n\n const timestamp = new Date().toISOString();\n const section = `\\n\\n## Reflection — ${timestamp}\\n\\n${reflection}\\n`;\n\n await writeFile(identityPath, existing + section, \"utf-8\");\n log.debug(`appended reflection to ${identityPath}`);\n }\n\n async readIdentityReflections(): Promise<string | null> {\n try {\n return await readFile(this.identityReflectionsPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n async writeIdentityReflections(content: string): Promise<void> {\n await mkdir(this.identityDir, { recursive: true });\n await writeFile(this.identityReflectionsPath, content, \"utf-8\");\n }\n\n async appendIdentityReflection(reflection: string): Promise<void> {\n let existing = \"\";\n try {\n existing = await readFile(this.identityReflectionsPath, \"utf-8\");\n } catch {\n // File doesn't exist yet.\n }\n\n if (existing.length > StorageManager.IDENTITY_MAX_BYTES) {\n log.debug(\n `identity/reflections.md is ${existing.length} chars (limit ${StorageManager.IDENTITY_MAX_BYTES}); skipping reflection`,\n );\n return;\n }\n\n const allMatches = [...existing.matchAll(/## Reflection — (\\S+)/g)];\n if (allMatches.length > 0) {\n const lastTimestamp = allMatches[allMatches.length - 1][1];\n const elapsed = Date.now() - new Date(lastTimestamp).getTime();\n if (elapsed < StorageManager.REFLECTION_COOLDOWN_MS) {\n log.debug(\n `reflection cooldown: ${Math.round(elapsed / 1000)}s since last (need ${StorageManager.REFLECTION_COOLDOWN_MS / 1000}s)`,\n );\n return;\n }\n }\n\n const timestamp = new Date().toISOString();\n const section = `${existing.trimEnd().length > 0 ? \"\\n\\n\" : \"\"}## Reflection — ${timestamp}\\n\\n${reflection}\\n`;\n await mkdir(this.identityDir, { recursive: true });\n await writeFile(this.identityReflectionsPath, `${existing.trimEnd()}${section}`, \"utf-8\");\n log.debug(`appended namespace-local reflection to ${this.identityReflectionsPath}`);\n }\n\n // ---------------------------------------------------------------------------\n // Entity mutation helpers (Knowledge Graph v7.0)\n // ---------------------------------------------------------------------------\n\n /**\n * Add a relationship to an entity file.\n * Deduplicates by target+label.\n */\n async addEntityRelationship(name: string, rel: EntityRelationship): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`addEntityRelationship: entity file ${name}.md not found`);\n return;\n }\n\n // Dedupe by target+label\n const exists = entity.relationships.some(\n (r) => r.target === rel.target && r.label === rel.label,\n );\n if (exists) return;\n\n entity.relationships.push(rel);\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n }\n\n /**\n * Add an activity entry to an entity file.\n * Prepends to the beginning, prunes oldest entries beyond maxEntries.\n */\n async addEntityActivity(\n name: string,\n entry: EntityActivityEntry,\n maxEntries: number,\n ): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`addEntityActivity: entity file ${name}.md not found`);\n return;\n }\n\n entity.activity.unshift(entry);\n if (entity.activity.length > maxEntries) {\n entity.activity = entity.activity.slice(0, maxEntries);\n }\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n }\n\n /**\n * Add an alias to an entity file. Deduplicates.\n */\n async addEntityAlias(name: string, alias: string): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`addEntityAlias: entity file ${name}.md not found`);\n return;\n }\n\n if (entity.aliases.includes(alias)) return;\n entity.aliases.push(alias);\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n }\n\n /**\n * Set or update the summary of an entity file.\n */\n async updateEntitySummary(name: string, summary: string): Promise<void> {\n const filePath = path.join(this.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await readFile(filePath, \"utf-8\");\n entity = parseEntityFile(content);\n } catch {\n log.debug(`updateEntitySummary: entity file ${name}.md not found`);\n return;\n }\n\n entity.summary = summary;\n entity.updated = new Date().toISOString();\n await writeFile(filePath, serializeEntityFile(entity), \"utf-8\");\n this.invalidateKnowledgeIndexCache();\n this.bumpMemoryStatusVersion(); // invalidate entity cache\n }\n\n // ---------------------------------------------------------------------------\n // Scoring + Knowledge Index (Knowledge Graph v7.0)\n // ---------------------------------------------------------------------------\n\n /**\n * Read all entity files and return lightweight EntityFile objects.\n * Parsing is fast (~50-100ms for ~1,800 files) since entity files are small.\n */\n async readAllEntityFiles(): Promise<EntityFile[]> {\n const currentVersion = this.getMemoryStatusVersion();\n const cached = getCachedEntities(this.baseDir, currentVersion);\n if (cached) return cached;\n\n try {\n const entries = await readdir(this.entitiesDir);\n const mdFiles = entries.filter((e) => e.endsWith(\".md\"));\n if (mdFiles.length === 0) return [];\n\n // Read all entity files in parallel batches to avoid O(N) sequential I/O.\n // With 3000+ entity files, sequential reads can take 15-20s under load.\n // Batching at 100 keeps file-descriptor pressure manageable while staying fast.\n const BATCH_SIZE = 100;\n const entities: EntityFile[] = [];\n for (let i = 0; i < mdFiles.length; i += BATCH_SIZE) {\n const batch = mdFiles.slice(i, i + BATCH_SIZE);\n const results = await Promise.all(\n batch.map((entry) =>\n readFile(path.join(this.entitiesDir, entry), \"utf-8\").catch(() => null),\n ),\n );\n for (const content of results) {\n if (content !== null) entities.push(parseEntityFile(content));\n }\n }\n\n setCachedEntities(this.baseDir, entities, currentVersion);\n return entities;\n } catch {\n // Directory doesn't exist yet\n return [];\n }\n }\n\n /**\n * Score an entity based on recency, frequency, activity, type priority,\n * and relationship density.\n *\n * score = recency*0.40 + frequency*0.25 + activity*0.15 + typePriority*0.10 + relationshipDensity*0.10\n */\n static scoreEntity(entity: EntityFile, now: Date): number {\n // Recency: 1 / (1 + daysSince/7) — 7-day half-life\n const updated = entity.updated ? new Date(entity.updated).getTime() : 0;\n const daysSince = Math.max(0, (now.getTime() - updated) / (1000 * 60 * 60 * 24));\n const recency = 1 / (1 + daysSince / 7);\n\n // Frequency: min(facts.length / 20, 1.0)\n const frequency = Math.min(entity.facts.length / 20, 1.0);\n\n // Activity: min(activity.length / 10, 1.0)\n const activityScore = Math.min(entity.activity.length / 10, 1.0);\n\n // Type priority\n const TYPE_PRIORITY: Record<string, number> = {\n person: 1.0,\n project: 0.8,\n company: 0.7,\n tool: 0.6,\n place: 0.5,\n other: 0.3,\n };\n const typePriority = TYPE_PRIORITY[entity.type.toLowerCase()] ?? 0.3;\n\n // Relationship density: min(relationships.length / 8, 1.0)\n const relDensity = Math.min(entity.relationships.length / 8, 1.0);\n\n return (\n recency * 0.40 +\n frequency * 0.25 +\n activityScore * 0.15 +\n typePriority * 0.10 +\n relDensity * 0.10\n );\n }\n\n /**\n * Build the Knowledge Index: a compact markdown table of top-scored entities.\n * Respects maxEntities and maxChars limits from config.\n */\n async buildKnowledgeIndex(\n config: PluginConfig,\n overrides?: { maxEntities?: number; maxChars?: number },\n ): Promise<{ result: string; cached: boolean }> {\n const useDefaultLimits =\n overrides?.maxEntities === undefined &&\n overrides?.maxChars === undefined;\n // Return cached index if still fresh\n if (\n useDefaultLimits &&\n this.knowledgeIndexCache &&\n Date.now() - this.knowledgeIndexCache.builtAt < StorageManager.KNOWLEDGE_INDEX_CACHE_TTL_MS\n ) {\n return { result: this.knowledgeIndexCache.result, cached: true };\n }\n\n const entities = await this.readAllEntityFiles();\n if (entities.length === 0) {\n if (useDefaultLimits) this.knowledgeIndexCache = { result: \"\", builtAt: Date.now() };\n return { result: \"\", cached: false };\n }\n\n const now = new Date();\n const scored: ScoredEntity[] = entities.map((e) => ({\n name: e.name,\n type: e.type,\n score: StorageManager.scoreEntity(e, now),\n factCount: e.facts.length,\n summary: e.summary,\n topRelationships: e.relationships.slice(0, 3).map((r) => r.target),\n }));\n\n // Sort by score descending, take top N\n scored.sort((a, b) => b.score - a.score);\n const maxEntities = typeof overrides?.maxEntities === \"number\"\n ? Math.max(0, Math.floor(overrides.maxEntities))\n : config.knowledgeIndexMaxEntities;\n const topN = scored.slice(0, maxEntities);\n\n if (topN.length === 0) {\n if (useDefaultLimits) this.knowledgeIndexCache = { result: \"\", builtAt: Date.now() };\n return { result: \"\", cached: false };\n }\n\n // Build markdown table\n const header = \"## Knowledge Index\\n\\n| Entity | Type | Summary | Connected to |\\n|--------|------|---------|-------------|\";\n const rows: string[] = [];\n let totalChars = header.length;\n const maxChars = typeof overrides?.maxChars === \"number\"\n ? Math.max(0, Math.floor(overrides.maxChars))\n : config.knowledgeIndexMaxChars;\n\n for (const entity of topN) {\n const summary = entity.summary || `${entity.factCount} facts`;\n const connected = entity.topRelationships.length > 0\n ? entity.topRelationships.join(\", \")\n : \"—\";\n const row = `| ${entity.name} | ${entity.type} | ${summary} | ${connected} |`;\n\n if (totalChars + row.length + 1 > maxChars) break;\n rows.push(row);\n totalChars += row.length + 1;\n }\n\n const result = rows.length === 0 ? \"\" : `${header}\\n${rows.join(\"\\n\")}\\n`;\n if (useDefaultLimits) this.knowledgeIndexCache = { result, builtAt: Date.now() };\n return { result, cached: false };\n }\n\n /** Invalidate the Knowledge Index cache (call after entity mutations). */\n invalidateKnowledgeIndexCache(): void {\n this.knowledgeIndexCache = null;\n }\n\n // ---------------------------------------------------------------------------\n // Commitment decay\n // ---------------------------------------------------------------------------\n\n /** Max lines for profile.md before LLM consolidation triggers */\n private static readonly PROFILE_MAX_LINES = 300;\n\n /**\n * Merge fragmented entity files that resolve to the same canonical name.\n * Preserves relationships, activity, aliases, and summary from all fragments.\n * Returns count of files merged.\n */\n async mergeFragmentedEntities(): Promise<number> {\n let merged = 0;\n try {\n const entries = await readdir(this.entitiesDir);\n const mdFiles = entries.filter((e) => e.endsWith(\".md\"));\n\n // Group files by their canonical name\n const groups = new Map<string, string[]>();\n for (const file of mdFiles) {\n const baseName = file.replace(\".md\", \"\");\n // Extract type and name from filename (type-rest-of-name)\n const dashIdx = baseName.indexOf(\"-\");\n if (dashIdx === -1) continue;\n const type = baseName.slice(0, dashIdx);\n const restOfName = baseName.slice(dashIdx + 1);\n const canonical = normalizeEntityName(restOfName, type);\n\n if (!groups.has(canonical)) groups.set(canonical, []);\n groups.get(canonical)!.push(file);\n }\n\n // Merge groups with more than one file\n for (const [canonical, files] of groups) {\n if (files.length <= 1) continue;\n\n // Parse all files and merge into a single EntityFile\n const mergedEntity: EntityFile = {\n name: \"\",\n type: \"other\",\n updated: \"\",\n facts: [],\n summary: undefined,\n relationships: [],\n activity: [],\n aliases: [],\n };\n\n for (const file of files) {\n const filePath = path.join(this.entitiesDir, file);\n try {\n const content = await readFile(filePath, \"utf-8\");\n const parsed = parseEntityFile(content);\n\n // Prefer specific types over \"other\"\n if (!mergedEntity.type || mergedEntity.type === \"other\") {\n mergedEntity.type = parsed.type;\n }\n\n // Keep latest update time\n if (!mergedEntity.updated || parsed.updated > mergedEntity.updated) {\n mergedEntity.updated = parsed.updated;\n }\n\n // Keep longest/best name\n if (parsed.name.length > mergedEntity.name.length) {\n mergedEntity.name = parsed.name;\n }\n\n // Keep first non-empty summary\n if (!mergedEntity.summary && parsed.summary) {\n mergedEntity.summary = parsed.summary;\n }\n\n // Collect all facts\n mergedEntity.facts.push(...parsed.facts);\n\n // Collect relationships (dedup later)\n mergedEntity.relationships.push(...parsed.relationships);\n\n // Collect activity entries\n mergedEntity.activity.push(...parsed.activity);\n\n // Collect aliases\n mergedEntity.aliases.push(...parsed.aliases);\n } catch {\n // Skip unreadable\n }\n }\n\n // Deduplicate facts\n mergedEntity.facts = [...new Set(mergedEntity.facts)];\n\n // Deduplicate relationships by target+label\n const relKeys = new Set<string>();\n mergedEntity.relationships = mergedEntity.relationships.filter((r) => {\n const key = `${r.target}::${r.label}`;\n if (relKeys.has(key)) return false;\n relKeys.add(key);\n return true;\n });\n\n // Sort activity by date descending, deduplicate by date+note\n const actKeys = new Set<string>();\n mergedEntity.activity = mergedEntity.activity\n .filter((a) => {\n const key = `${a.date}::${a.note}`;\n if (actKeys.has(key)) return false;\n actKeys.add(key);\n return true;\n })\n .sort((a, b) => b.date.localeCompare(a.date));\n\n // Deduplicate aliases\n mergedEntity.aliases = [...new Set(mergedEntity.aliases)];\n\n // Fallback name from canonical\n if (!mergedEntity.name) {\n const dashIdx = canonical.indexOf(\"-\");\n mergedEntity.name = dashIdx !== -1 ? canonical.slice(dashIdx + 1) : canonical;\n }\n\n mergedEntity.updated = mergedEntity.updated || new Date().toISOString();\n\n const canonicalPath = path.join(this.entitiesDir, `${canonical}.md`);\n await writeFile(canonicalPath, serializeEntityFile(mergedEntity), \"utf-8\");\n\n // Remove non-canonical files\n for (const file of files) {\n const filePath = path.join(this.entitiesDir, file);\n if (filePath !== canonicalPath) {\n try {\n await unlink(filePath);\n merged++;\n log.debug(`merged entity ${file} → ${canonical}.md`);\n } catch {\n // Ignore\n }\n }\n }\n }\n } catch {\n // Directory doesn't exist yet\n }\n\n return merged;\n }\n\n async cleanExpiredCommitments(decayDays: number): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n const cutoff = Date.now() - decayDays * 24 * 60 * 60 * 1000;\n const deleted: MemoryFile[] = [];\n\n for (const m of memories) {\n if (m.frontmatter.category !== \"commitment\") continue;\n // Only decay commitments that have been marked as resolved/expired\n // (indicated by tags containing \"fulfilled\" or \"expired\")\n const isResolved = m.frontmatter.tags.some(\n (t) => t === \"fulfilled\" || t === \"expired\",\n );\n if (!isResolved) continue;\n\n const updatedAt = new Date(m.frontmatter.updated).getTime();\n if (updatedAt < cutoff) {\n // Remove the file\n try {\n await unlink(m.path);\n deleted.push(m);\n log.debug(`cleaned expired commitment ${m.frontmatter.id}`);\n } catch {\n // Ignore\n }\n }\n }\n\n if (deleted.length > 0) {\n this.bumpMemoryStatusVersion();\n }\n\n return deleted;\n }\n\n // ---------------------------------------------------------------------------\n // Access Tracking (Phase 1A)\n // ---------------------------------------------------------------------------\n\n /**\n * Flush batched access tracking updates to disk.\n * Called during consolidation or when buffer exceeds max size.\n */\n async flushAccessTracking(entries: AccessTrackingEntry[]): Promise<number> {\n if (entries.length === 0) return 0;\n\n const memories = await this.readAllMemories();\n const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));\n let updated = 0;\n\n for (const entry of entries) {\n const memory = memoryMap.get(entry.memoryId);\n if (!memory) continue;\n\n const newFm: MemoryFrontmatter = {\n ...memory.frontmatter,\n accessCount: entry.newCount,\n lastAccessed: entry.lastAccessed,\n };\n\n const fileContent = `${serializeFrontmatter(newFm)}\\n\\n${memory.content}\\n`;\n try {\n await writeFile(memory.path, fileContent, \"utf-8\");\n updated++;\n } catch (err) {\n log.debug(`failed to update access tracking for ${entry.memoryId}: ${err}`);\n }\n }\n\n if (updated > 0) {\n log.debug(`flushed access tracking for ${updated} memories`);\n }\n return updated;\n }\n\n /**\n * Get a memory by its ID.\n */\n async getMemoryById(id: string): Promise<MemoryFile | null> {\n const memories = await this.readAllMemories();\n return memories.find((m) => m.frontmatter.id === id) ?? null;\n }\n\n async getProjectedMemoryState(id: string): Promise<MemoryProjectionCurrentState | null> {\n const projected = readProjectedMemoryState(this.baseDir, id);\n if (projected) return projected;\n\n const active = await this.getMemoryById(id);\n if (active) return this.toProjectedCurrentState(active, \"active\");\n\n const archived = (await this.readArchivedMemories()).find((memory) => memory.frontmatter.id === id);\n if (!archived) return null;\n\n return this.toProjectedCurrentState(archived, \"archived\");\n }\n\n async browseProjectedMemories(\n options: ProjectedMemoryBrowseOptions,\n ): Promise<ProjectedMemoryBrowsePage | null> {\n return readProjectedMemoryBrowse(this.baseDir, options);\n }\n\n async getProjectedGovernanceRecord(): Promise<ReturnType<typeof readProjectedGovernanceRecord>> {\n return readProjectedGovernanceRecord(this.baseDir);\n }\n\n private toProjectedCurrentState(\n memory: MemoryFile,\n fallbackStatus: MemoryStatus,\n ): MemoryProjectionCurrentState {\n const pathRel = toMemoryPathRel(this.baseDir, memory.path);\n return {\n memoryId: memory.frontmatter.id,\n category: memory.frontmatter.category,\n status: inferCurrentStateStatus(memory.frontmatter, pathRel, fallbackStatus),\n lifecycleState: memory.frontmatter.lifecycleState,\n path: memory.path,\n pathRel,\n created: memory.frontmatter.created,\n updated: memory.frontmatter.updated,\n archivedAt: memory.frontmatter.archivedAt,\n supersededAt: memory.frontmatter.supersededAt,\n entityRef: memory.frontmatter.entityRef,\n source: memory.frontmatter.source,\n confidence: memory.frontmatter.confidence,\n confidenceTier: memory.frontmatter.confidenceTier,\n memoryKind: memory.frontmatter.memoryKind,\n accessCount: memory.frontmatter.accessCount,\n lastAccessed: memory.frontmatter.lastAccessed,\n tags: normalizeProjectionTags(memory.frontmatter.tags),\n preview: normalizeProjectionPreview(memory.content),\n };\n }\n\n async getMemoryTimeline(memoryId: string, limit: number = 200): Promise<MemoryLifecycleEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n const projected = readProjectedMemoryTimeline(this.baseDir, memoryId, cappedLimit);\n if (projected && projected.length > 0) return projected;\n\n const events = await this.readAllMemoryLifecycleEvents();\n return events.filter((event) => event.memoryId === memoryId).slice(-cappedLimit);\n }\n\n // ---------------------------------------------------------------------------\n // Chunking (Phase 2A)\n // ---------------------------------------------------------------------------\n\n /**\n * Write a memory chunk with parent reference.\n * Chunk IDs follow format: {parentId}-chunk-{index}\n */\n async writeChunk(\n parentId: string,\n chunkIndex: number,\n chunkTotal: number,\n category: MemoryCategory,\n content: string,\n options: {\n confidence?: number;\n tags?: string[];\n entityRef?: string;\n source?: string;\n importance?: ImportanceScore;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n } = {},\n ): Promise<string> {\n await this.ensureDirectories();\n const now = new Date();\n const today = now.toISOString().slice(0, 10);\n const id = `${parentId}-chunk-${chunkIndex}`;\n const conf = options.confidence ?? 0.8;\n const tier = confidenceTier(conf);\n\n const fm: MemoryFrontmatter = {\n id,\n category,\n created: now.toISOString(),\n updated: now.toISOString(),\n source: options.source ?? \"chunking\",\n confidence: conf,\n confidenceTier: tier,\n tags: options.tags ?? [],\n entityRef: options.entityRef,\n importance: options.importance,\n parentId,\n chunkIndex,\n chunkTotal,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n memoryKind: options.memoryKind,\n };\n\n const sanitized = sanitizeMemoryContent(content);\n if (!sanitized.clean) {\n log.warn(`chunk content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n const fileContent = `${serializeFrontmatter(fm)}\\n\\n${sanitized.text}\\n`;\n\n let filePath: string;\n if (category === \"correction\") {\n filePath = path.join(this.correctionsDir, `${id}.md`);\n } else {\n filePath = path.join(this.factsDir, today, `${id}.md`);\n }\n\n await writeFile(filePath, fileContent, \"utf-8\");\n log.debug(`wrote chunk ${id} (${chunkIndex + 1}/${chunkTotal}) to ${filePath}`);\n return id;\n }\n\n /**\n * Get all chunks for a given parent memory ID.\n * Returns chunks sorted by chunkIndex.\n */\n async getChunksForParent(parentId: string): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n return memories\n .filter((m) => m.frontmatter.parentId === parentId)\n .sort((a, b) => (a.frontmatter.chunkIndex ?? 0) - (b.frontmatter.chunkIndex ?? 0));\n }\n\n // ---------------------------------------------------------------------------\n // Contradiction Detection (Phase 2B)\n // ---------------------------------------------------------------------------\n\n /**\n * Mark a memory as superseded by another.\n * Updates the old memory's status and adds the supersededBy link.\n */\n async supersedeMemory(\n oldMemoryId: string,\n newMemoryId: string,\n reason: string,\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const oldMemory = memories.find((m) => m.frontmatter.id === oldMemoryId);\n if (!oldMemory) return false;\n\n const now = new Date().toISOString();\n const updatedFm: MemoryFrontmatter = {\n ...oldMemory.frontmatter,\n status: \"superseded\",\n supersededBy: newMemoryId,\n supersededAt: now,\n updated: now,\n };\n\n const fileContent = `${serializeFrontmatter(updatedFm)}\\n\\n${oldMemory.content}\\n`;\n\n try {\n await writeFile(oldMemory.path, fileContent, \"utf-8\");\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.supersedeMemory\", {\n memoryId: oldMemoryId,\n eventType: \"superseded\",\n timestamp: now,\n actor: \"storage.supersedeMemory\",\n reasonCode: reason,\n before: this.summarizeLifecycleState(oldMemory.frontmatter, oldMemory.path),\n after: this.summarizeLifecycleState(updatedFm, oldMemory.path),\n relatedMemoryIds: [newMemoryId],\n });\n this.bumpMemoryStatusVersion();\n log.debug(`superseded memory ${oldMemoryId} by ${newMemoryId}: ${reason}`);\n\n // Also write a correction entry for the audit trail\n await this.writeMemory(\"correction\", `Superseded: ${oldMemory.content}\\n\\nReason: ${reason}`, {\n confidence: 1.0,\n tags: [\"supersession\", \"auto-resolved\"],\n source: \"contradiction-detection\",\n lineage: [oldMemoryId, newMemoryId],\n });\n\n return true;\n } catch (err) {\n log.error(`failed to supersede memory ${oldMemoryId}:`, err);\n return false;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Memory Summarization (Phase 4A)\n // ---------------------------------------------------------------------------\n\n private get summariesDir(): string {\n return path.join(this.baseDir, \"summaries\");\n }\n\n /**\n * Write a memory summary.\n */\n async writeSummary(summary: MemorySummary): Promise<void> {\n await mkdir(this.summariesDir, { recursive: true });\n const filePath = path.join(this.summariesDir, `${summary.id}.json`);\n await writeFile(filePath, JSON.stringify(summary, null, 2), \"utf-8\");\n log.debug(`wrote summary ${summary.id}`);\n }\n\n /**\n * Get all summaries.\n */\n async readSummaries(): Promise<MemorySummary[]> {\n try {\n const files = await readdir(this.summariesDir);\n const summaries: MemorySummary[] = [];\n\n for (const file of files) {\n if (!file.endsWith(\".json\")) continue;\n const filePath = path.join(this.summariesDir, file);\n const raw = await readFile(filePath, \"utf-8\");\n summaries.push(JSON.parse(raw) as MemorySummary);\n }\n\n return summaries;\n } catch {\n return [];\n }\n }\n\n /**\n * Archive memories (mark as archived, not delete).\n */\n async archiveMemories(memoryIds: string[], summaryId: string): Promise<number> {\n const memories = await this.readAllMemories();\n const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));\n let archived = 0;\n\n for (const id of memoryIds) {\n const memory = memoryMap.get(id);\n if (!memory) continue;\n\n const now = new Date().toISOString();\n const updatedFm: MemoryFrontmatter = {\n ...memory.frontmatter,\n status: \"archived\",\n archivedAt: now,\n updated: now,\n };\n\n const fileContent = `${serializeFrontmatter(updatedFm)}\\n\\n${memory.content}\\n`;\n\n try {\n await writeFile(memory.path, fileContent, \"utf-8\");\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.archiveMemories\", {\n memoryId: id,\n eventType: \"archived\",\n timestamp: updatedFm.archivedAt ?? updatedFm.updated,\n actor: \"storage.archiveMemories\",\n reasonCode: `summary:${summaryId}`,\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updatedFm, memory.path),\n relatedMemoryIds: [summaryId],\n });\n archived++;\n } catch {\n // Ignore individual failures\n }\n }\n\n if (archived > 0) {\n this.bumpMemoryStatusVersion();\n log.debug(`archived ${archived} memories for summary ${summaryId}`);\n }\n return archived;\n }\n\n // ---------------------------------------------------------------------------\n // Topic Extraction (Phase 4B)\n // ---------------------------------------------------------------------------\n\n /**\n * Save topic scores to meta.json.\n */\n async saveTopics(topics: TopicScore[]): Promise<void> {\n const metaPath = path.join(this.stateDir, \"topics.json\");\n await mkdir(this.stateDir, { recursive: true });\n await writeFile(metaPath, JSON.stringify({ topics, updatedAt: new Date().toISOString() }, null, 2), \"utf-8\");\n log.debug(`saved ${topics.length} topic scores`);\n }\n\n /**\n * Load topic scores from meta.json.\n */\n async loadTopics(): Promise<{ topics: TopicScore[]; updatedAt: string | null }> {\n const metaPath = path.join(this.stateDir, \"topics.json\");\n try {\n const raw = await readFile(metaPath, \"utf-8\");\n return JSON.parse(raw) as { topics: TopicScore[]; updatedAt: string | null };\n } catch {\n return { topics: [], updatedAt: null };\n }\n }\n\n /**\n * Add links to an existing memory.\n */\n async addLinksToMemory(\n memoryId: string,\n links: MemoryLink[],\n lifecycle?: MemoryLifecycleEventWriteOptions,\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === memoryId);\n if (!memory) return false;\n\n const existingLinks = memory.frontmatter.links ?? [];\n const mergedLinks = [...existingLinks];\n\n // Add new links, avoiding duplicates\n for (const link of links) {\n if (!mergedLinks.some((l) => l.targetId === link.targetId && l.linkType === link.linkType)) {\n mergedLinks.push(link);\n }\n }\n\n try {\n await this.writeMemoryFrontmatter(\n memory,\n {\n links: mergedLinks,\n updated: new Date().toISOString(),\n },\n lifecycle,\n );\n log.debug(`added ${links.length} links to memory ${memoryId}`);\n return true;\n } catch (err) {\n log.error(`failed to add links to memory ${memoryId}:`, err);\n return false;\n }\n }\n\n private summarizeLifecycleState(\n frontmatter: MemoryFrontmatter,\n filePath: string,\n ): MemoryLifecycleStateSummary {\n return {\n category: frontmatter.category,\n path: filePath,\n status: frontmatter.status ?? \"active\",\n lifecycleState: frontmatter.lifecycleState,\n };\n }\n\n private frontmatterPatchEventType(\n before: MemoryFrontmatter,\n after: MemoryFrontmatter,\n ): MemoryLifecycleEventType {\n const beforeStatus = before.status ?? \"active\";\n const afterStatus = after.status ?? \"active\";\n if (beforeStatus !== \"archived\" && afterStatus === \"archived\") return \"archived\";\n if (beforeStatus !== \"superseded\" && afterStatus === \"superseded\") return \"superseded\";\n if (beforeStatus !== \"rejected\" && afterStatus === \"rejected\") return \"rejected\";\n if (beforeStatus !== \"active\" && afterStatus === \"active\") {\n return \"restored\";\n }\n return \"updated\";\n }\n\n private async appendGeneratedMemoryLifecycleEvent(\n input: Omit<MemoryLifecycleEvent, \"eventId\" | \"ruleVersion\">,\n ruleVersion = \"memory-lifecycle-ledger.v1\",\n ): Promise<void> {\n await this.appendMemoryLifecycleEvents([\n {\n ...input,\n eventId: this.generateId(\"mle\"),\n ruleVersion,\n },\n ]);\n }\n\n private async appendGeneratedMemoryLifecycleEventFailOpen(\n operation: string,\n input: Omit<MemoryLifecycleEvent, \"eventId\" | \"ruleVersion\">,\n ruleVersion?: string,\n ): Promise<void> {\n try {\n await this.appendGeneratedMemoryLifecycleEvent(input, ruleVersion);\n } catch (appendErr) {\n log.warn(`${operation} completed but failed to append lifecycle event: ${appendErr}`);\n }\n }\n}\n","import type { EntityFile, MemoryFile } from \"./types.js\";\n\ninterface CacheEntry {\n memories: Map<string, MemoryFile>; // keyed by file path\n version: number;\n loadedAt: number;\n}\n\n// Module-level singleton — shared across all StorageManager instances and sessions\nconst hotCacheByDir = new Map<string, CacheEntry>();\nconst archiveCacheByDir = new Map<string, CacheEntry>();\n\nexport function getCachedMemories(baseDir: string, currentVersion: number): MemoryFile[] | null {\n // Don't serve from cache when version tracking is unavailable (version=0).\n // This ensures tests and fresh installs without a version file always read disk.\n if (currentVersion === 0) return null;\n const entry = hotCacheByDir.get(baseDir);\n if (!entry || entry.version !== currentVersion) return null;\n return [...entry.memories.values()];\n}\n\nexport function setCachedMemories(baseDir: string, memories: MemoryFile[], version: number): void {\n const map = new Map<string, MemoryFile>();\n for (const m of memories) map.set(m.path, m);\n hotCacheByDir.set(baseDir, { memories: map, version, loadedAt: Date.now() });\n}\n\nexport function updateCacheOnWrite(baseDir: string, memory: MemoryFile): void {\n const entry = hotCacheByDir.get(baseDir);\n if (entry) entry.memories.set(memory.path, memory);\n}\n\nexport function updateCacheOnDelete(baseDir: string, filePath: string): void {\n const entry = hotCacheByDir.get(baseDir);\n if (entry) entry.memories.delete(filePath);\n}\n\n// Archive cache — same pattern, separate store\nexport function getCachedArchivedMemories(baseDir: string, currentVersion: number): MemoryFile[] | null {\n if (currentVersion === 0) return null;\n const entry = archiveCacheByDir.get(baseDir);\n if (!entry || entry.version !== currentVersion) return null;\n return [...entry.memories.values()];\n}\n\nexport function setCachedArchivedMemories(baseDir: string, memories: MemoryFile[], version: number): void {\n const map = new Map<string, MemoryFile>();\n for (const m of memories) map.set(m.path, m);\n archiveCacheByDir.set(baseDir, { memories: map, version, loadedAt: Date.now() });\n}\n\n// Entity cache — same pattern as memory cache\nconst entityCacheByDir = new Map<string, { entities: EntityFile[]; version: number; loadedAt: number }>();\n\nexport function getCachedEntities(baseDir: string, currentVersion: number): EntityFile[] | null {\n if (currentVersion === 0) return null;\n const entry = entityCacheByDir.get(baseDir);\n if (!entry || entry.version !== currentVersion) return null;\n return entry.entities;\n}\n\nexport function setCachedEntities(baseDir: string, entities: EntityFile[], version: number): void {\n entityCacheByDir.set(baseDir, { entities, version, loadedAt: Date.now() });\n}\n\n// Derived caches — pre-filtered views invalidated alongside the main cache.\n// These avoid O(146K) filter+map on every verified recall/rules call.\ninterface DerivedCacheEntry<T> {\n data: T;\n sourceVersion: number; // matches the hot cache version it was derived from\n}\n\nconst episodeMapByDir = new Map<string, DerivedCacheEntry<Map<string, MemoryFile>>>();\nconst ruleMemoriesByDir = new Map<string, DerivedCacheEntry<{ all: MemoryFile[]; byId: Map<string, MemoryFile> }>>();\n\n/** Get a pre-filtered Map of episode memories (keyed by ID). Derived from hot cache. */\nexport function getCachedEpisodeMap(baseDir: string, currentVersion: number): Map<string, MemoryFile> | null {\n if (currentVersion === 0) return null;\n const entry = episodeMapByDir.get(baseDir);\n if (!entry || entry.sourceVersion !== currentVersion) return null;\n return entry.data;\n}\n\n/** Build and cache the episode memory map from the full memory list. */\nexport function setCachedEpisodeMap(baseDir: string, memories: MemoryFile[], version: number): Map<string, MemoryFile> {\n const map = new Map<string, MemoryFile>();\n for (const m of memories) {\n if (m.frontmatter.status === \"archived\") continue;\n if (m.frontmatter.memoryKind !== \"episode\") continue;\n map.set(m.frontmatter.id, m);\n }\n episodeMapByDir.set(baseDir, { data: map, sourceVersion: version });\n return map;\n}\n\n/** Get pre-filtered rule memories. Derived from hot cache. */\nexport function getCachedRuleMemories(baseDir: string, currentVersion: number): { all: MemoryFile[]; byId: Map<string, MemoryFile> } | null {\n if (currentVersion === 0) return null;\n const entry = ruleMemoriesByDir.get(baseDir);\n if (!entry || entry.sourceVersion !== currentVersion) return null;\n return entry.data;\n}\n\n/** Build and cache the rule memories from the full memory list. */\nexport function setCachedRuleMemories(baseDir: string, memories: MemoryFile[], version: number): { all: MemoryFile[]; byId: Map<string, MemoryFile> } {\n const byId = new Map<string, MemoryFile>();\n const all: MemoryFile[] = [];\n for (const m of memories) {\n byId.set(m.frontmatter.id, m);\n if (m.frontmatter.category === \"rule\" && m.frontmatter.status !== \"archived\") {\n all.push(m);\n }\n }\n const result = { all, byId };\n ruleMemoriesByDir.set(baseDir, { data: result, sourceVersion: version });\n return result;\n}\n\n// QMD search result cache — short-lived (60s TTL) to avoid stale results\n// while reducing redundant daemon calls for repeated/similar queries.\ninterface QmdCacheEntry {\n results: unknown[];\n cachedAt: number;\n}\nconst QMD_CACHE_TTL_MS = 60_000;\nconst qmdSearchCache = new Map<string, QmdCacheEntry>();\n\nexport function getCachedQmdSearch(cacheKey: string): unknown[] | null {\n const entry = qmdSearchCache.get(cacheKey);\n if (!entry) return null;\n if (Date.now() - entry.cachedAt > QMD_CACHE_TTL_MS) {\n qmdSearchCache.delete(cacheKey);\n return null;\n }\n return entry.results;\n}\n\nexport function setCachedQmdSearch(cacheKey: string, results: unknown[]): void {\n qmdSearchCache.set(cacheKey, { results, cachedAt: Date.now() });\n // Evict old entries to prevent unbounded growth\n if (qmdSearchCache.size > 200) {\n const now = Date.now();\n for (const [key, entry] of qmdSearchCache) {\n if (now - entry.cachedAt > QMD_CACHE_TTL_MS) qmdSearchCache.delete(key);\n }\n }\n}\n\nexport function clearMemoryCache(baseDir?: string): void {\n if (baseDir) {\n hotCacheByDir.delete(baseDir);\n archiveCacheByDir.delete(baseDir);\n entityCacheByDir.delete(baseDir);\n episodeMapByDir.delete(baseDir);\n ruleMemoriesByDir.delete(baseDir);\n } else {\n hotCacheByDir.clear();\n archiveCacheByDir.clear();\n entityCacheByDir.clear();\n episodeMapByDir.clear();\n ruleMemoriesByDir.clear();\n qmdSearchCache.clear();\n }\n}\n\nexport function getMemoryCacheStats(baseDir: string): {\n hotSize: number;\n archiveSize: number;\n hotVersion: number | null;\n archiveVersion: number | null;\n} {\n const hot = hotCacheByDir.get(baseDir);\n const archive = archiveCacheByDir.get(baseDir);\n return {\n hotSize: hot?.memories.size ?? 0,\n archiveSize: archive?.memories.size ?? 0,\n hotVersion: hot?.version ?? null,\n archiveVersion: archive?.version ?? null,\n };\n}\n","import { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type HygieneWarning = {\n path: string;\n bytes: number;\n budgetBytes: number;\n warnAtBytes: number;\n message: string;\n};\n\nfunction toSafeTimestamp(ts: Date): string {\n // filesystem-safe, deterministic-ish, UTC\n return ts.toISOString().replace(/[:.]/g, \"\");\n}\n\nexport async function lintWorkspaceFiles(opts: {\n workspaceDir: string;\n paths: string[];\n budgetBytes: number;\n warnRatio: number;\n}): Promise<HygieneWarning[]> {\n const warnings: HygieneWarning[] = [];\n const warnAtBytes = Math.floor(opts.budgetBytes * opts.warnRatio);\n\n for (const p of opts.paths) {\n const abs = path.isAbsolute(p) ? p : path.join(opts.workspaceDir, p);\n try {\n const st = await stat(abs);\n if (!st.isFile()) continue;\n const bytes = st.size;\n if (bytes >= warnAtBytes) {\n warnings.push({\n path: p,\n bytes,\n budgetBytes: opts.budgetBytes,\n warnAtBytes,\n message: `Bootstrap file '${p}' is approaching its budget (${bytes} bytes >= ${warnAtBytes} bytes). Consider splitting/archiving it to avoid silent truncation.`,\n });\n }\n } catch {\n // ignore missing files\n }\n }\n\n return warnings;\n}\n\nexport async function rotateMarkdownFileToArchive(opts: {\n filePath: string;\n archiveDir: string;\n archivePrefix: string;\n keepTailChars: number;\n}): Promise<{ archivedPath: string; newContent: string }> {\n const existing = await readFile(opts.filePath, \"utf-8\");\n const ts = toSafeTimestamp(new Date());\n const archiveName = `${opts.archivePrefix}-${ts}.md`;\n await mkdir(opts.archiveDir, { recursive: true });\n const archivedPath = path.join(opts.archiveDir, archiveName);\n await writeFile(archivedPath, existing, \"utf-8\");\n\n const tail =\n opts.keepTailChars > 0 && existing.length > opts.keepTailChars\n ? existing.slice(-opts.keepTailChars)\n : existing;\n\n const relLink = path.relative(path.dirname(opts.filePath), archivedPath);\n\n const newContent = [\n \"# Index\",\n \"\",\n \"This file is kept intentionally small to reduce the risk of silent truncation when OpenClaw bootstraps workspace files into the prompt.\",\n \"\",\n \"## Archives\",\n `- [${archiveName}](${relLink})`,\n \"\",\n \"## Recent Tail (for continuity)\",\n \"\",\n \"```md\",\n tail.trim(),\n \"```\",\n \"\",\n ].join(\"\\n\");\n\n return { archivedPath, newContent };\n}\n\n","const INJECTION_PATTERNS: RegExp[] = [\n /ignore\\s+(all\\s+)?(previous|prior|above)\\s+(instructions?|prompts?|context)/i,\n /forget\\s+(everything|all|previous|what)/i,\n /new\\s+(system\\s+)?prompt:/i,\n /\\[system\\]/i,\n /<\\s*system\\s*>/i,\n /you\\s+are\\s+now\\s+(?!called|named)/i,\n /disregard\\s+(all\\s+)?(previous|prior)/i,\n /override\\s+(previous\\s+)?(instructions?|prompt)/i,\n /act\\s+as\\s+(?:an?\\s+)?(?:AI|assistant|ChatGPT|GPT|Claude|LLM)\\s+(?:without|that\\s+ignores)/i,\n /do\\s+not\\s+(?:follow|obey)\\s+(?:previous|prior|your)\\s+instructions/i,\n /pretend\\s+(?:you\\s+)?(?:have\\s+no|you\\s+don.?t\\s+have)\\s+(restrictions|guidelines|rules)/i,\n];\n\nexport type SanitizeResult = {\n clean: boolean;\n text: string;\n violations: string[];\n};\n\nconst REDACTED_PLACEHOLDER = \"[content removed: possible prompt injection]\";\n\nexport function sanitizeMemoryContent(text: string): SanitizeResult {\n const source = typeof text === \"string\" ? text : \"\";\n const violations: string[] = [];\n\n for (const pattern of INJECTION_PATTERNS) {\n if (pattern.test(source)) {\n violations.push(pattern.source);\n }\n }\n\n if (violations.length === 0) {\n return { clean: true, text: source, violations: [] };\n }\n\n return {\n clean: false,\n text: REDACTED_PLACEHOLDER,\n violations,\n };\n}\n\nexport function isSafeMemoryContent(text: string): boolean {\n return sanitizeMemoryContent(text).clean;\n}\n\n","export type ReasoningEffort = \"none\" | \"low\" | \"medium\" | \"high\";\nexport type TriggerMode = \"smart\" | \"every_n\" | \"time_based\";\nexport type SignalLevel = \"none\" | \"low\" | \"medium\" | \"high\";\nexport type MemoryCategory = \"fact\" | \"preference\" | \"correction\" | \"entity\" | \"decision\" | \"relationship\" | \"principle\" | \"commitment\" | \"moment\" | \"skill\" | \"rule\";\nexport type ConsolidationAction = \"ADD\" | \"MERGE\" | \"UPDATE\" | \"INVALIDATE\" | \"SKIP\";\nexport type ConfidenceTier = \"explicit\" | \"implied\" | \"inferred\" | \"speculative\";\nexport type PrincipalFromSessionKeyMode = \"map\" | \"prefix\" | \"regex\";\nexport type RecallPlanMode = \"no_recall\" | \"minimal\" | \"full\" | \"graph_mode\";\nexport type CronRecallMode = \"all\" | \"none\" | \"allowlist\";\nexport type CronConversationRecallMode = \"auto\" | \"always\" | \"never\";\nexport type IdentityInjectionMode = \"recovery_only\" | \"minimal\" | \"full\";\nexport type CaptureMode = \"implicit\" | \"explicit\" | \"hybrid\";\nexport type MemoryOsPresetName = \"conservative\" | \"balanced\" | \"research-max\" | \"local-llm-heavy\";\nexport type ExtractionPassSource = \"base\" | \"proactive\";\n\nexport interface RecallSectionConfig {\n id: string;\n enabled?: boolean;\n maxChars?: number | null;\n maxHints?: number;\n maxSupportingFacts?: number;\n maxRelatedEntities?: number;\n consolidateTriggerLines?: number;\n consolidateTargetLines?: number;\n maxEntities?: number;\n maxResults?: number;\n recentTurns?: number;\n maxTurns?: number;\n maxTokens?: number;\n lookbackHours?: number;\n maxCount?: number;\n topK?: number;\n timeoutMs?: number;\n maxPatterns?: number;\n maxRubrics?: number;\n}\n\nexport interface RecallPipelineConfig {\n recallBudgetChars: number;\n pipeline: RecallSectionConfig[];\n}\n\nexport interface SessionObserverBandConfig {\n maxBytes: number;\n triggerDeltaBytes: number;\n triggerDeltaTokens: number;\n}\n\nexport interface FileHygieneConfig {\n enabled: boolean;\n // Lint (warn before truncation risk)\n lintEnabled: boolean;\n lintBudgetBytes: number;\n lintWarnRatio: number;\n lintPaths: string[];\n // Rotation/splitting\n rotateEnabled: boolean;\n rotateMaxBytes: number;\n rotateKeepTailChars: number;\n rotatePaths: string[];\n archiveDir: string;\n // Cadence\n runMinIntervalMs: number;\n // Optional warnings log (future-proofed)\n warningsLogEnabled: boolean;\n warningsLogPath: string;\n // Optional index file (future-proofed)\n indexEnabled: boolean;\n indexPath: string;\n}\n\nexport interface NativeKnowledgeConfig {\n enabled: boolean;\n includeFiles: string[];\n maxChunkChars: number;\n maxResults: number;\n maxChars: number;\n stateDir: string;\n obsidianVaults: NativeKnowledgeObsidianVaultConfig[];\n openclawWorkspace?: NativeKnowledgeOpenClawWorkspaceConfig;\n}\n\nexport interface NativeKnowledgeFolderRuleConfig {\n pathPrefix: string;\n namespace?: string;\n privacyClass?: string;\n}\n\nexport interface NativeKnowledgeObsidianVaultConfig {\n id: string;\n rootDir: string;\n includeGlobs: string[];\n excludeGlobs: string[];\n namespace?: string;\n privacyClass?: string;\n folderRules: NativeKnowledgeFolderRuleConfig[];\n dailyNotePatterns: string[];\n materializeBacklinks: boolean;\n}\n\nexport interface NativeKnowledgeOpenClawWorkspaceConfig {\n enabled: boolean;\n bootstrapFiles: string[];\n handoffGlobs: string[];\n dailySummaryGlobs: string[];\n automationNoteGlobs: string[];\n workspaceDocGlobs: string[];\n excludeGlobs: string[];\n sharedSafeGlobs: string[];\n}\n\nexport interface AgentAccessHttpConfig {\n enabled: boolean;\n host: string;\n port: number;\n authToken?: string;\n principal?: string;\n maxBodyBytes: number;\n}\n\nexport function confidenceTier(score: number): ConfidenceTier {\n if (score >= 0.95) return \"explicit\";\n if (score >= 0.70) return \"implied\";\n if (score >= 0.40) return \"inferred\";\n return \"speculative\";\n}\n\n/** Default TTL in days for speculative memories (auto-expire if unconfirmed) */\nexport const SPECULATIVE_TTL_DAYS = 30;\n\nexport interface PluginConfig {\n openaiApiKey: string | undefined;\n openaiBaseUrl: string | undefined;\n model: string;\n reasoningEffort: ReasoningEffort;\n triggerMode: TriggerMode;\n bufferMaxTurns: number;\n bufferMaxMinutes: number;\n consolidateEveryN: number;\n highSignalPatterns: string[];\n maxMemoryTokens: number;\n memoryOsPreset?: MemoryOsPresetName;\n qmdEnabled: boolean;\n qmdCollection: string;\n qmdMaxResults: number;\n qmdColdTierEnabled?: boolean;\n qmdColdCollection?: string;\n qmdColdMaxResults?: number;\n qmdTierMigrationEnabled: boolean;\n qmdTierDemotionMinAgeDays: number;\n qmdTierDemotionValueThreshold: number;\n qmdTierPromotionValueThreshold: number;\n qmdTierParityGraphEnabled: boolean;\n qmdTierParityHiMemEnabled: boolean;\n qmdTierAutoBackfillEnabled: boolean;\n embeddingFallbackEnabled: boolean;\n embeddingFallbackProvider: \"auto\" | \"openai\" | \"local\";\n /** Optional absolute path to qmd binary. If unset, PATH/fallback discovery is used. */\n qmdPath?: string;\n memoryDir: string;\n debug: boolean;\n identityEnabled: boolean;\n identityContinuityEnabled: boolean;\n identityInjectionMode: IdentityInjectionMode;\n identityMaxInjectChars: number;\n continuityIncidentLoggingEnabled: boolean;\n continuityAuditEnabled: boolean;\n sessionObserverEnabled?: boolean;\n sessionObserverDebounceMs?: number;\n sessionObserverBands?: SessionObserverBandConfig[];\n injectQuestions: boolean;\n commitmentDecayDays: number;\n workspaceDir: string;\n captureMode: CaptureMode;\n fileHygiene?: FileHygieneConfig;\n nativeKnowledge?: NativeKnowledgeConfig;\n agentAccessHttp: AgentAccessHttpConfig;\n // Access tracking (Phase 1A)\n accessTrackingEnabled: boolean;\n accessTrackingBufferMaxSize: number;\n // Retrieval options\n recencyWeight: number;\n boostAccessCount: boolean;\n /** Record empty recall impressions (memoryIds: []) when no memories are injected. Disabled by default. */\n recordEmptyRecallImpressions: boolean;\n // v2.2 Advanced Retrieval\n queryExpansionEnabled: boolean;\n queryExpansionMaxQueries: number;\n /** Minimum token length to consider for query expansion. */\n queryExpansionMinTokenLen: number;\n rerankEnabled: boolean;\n /** Rerank provider. \"local\" uses Local LLM only; \"cloud\" uses gateway fallback chain. */\n rerankProvider: \"local\" | \"cloud\";\n rerankMaxCandidates: number;\n rerankTimeoutMs: number;\n rerankCacheEnabled: boolean;\n rerankCacheTtlMs: number;\n feedbackEnabled: boolean;\n // v2.2 Negative Examples (safe defaults: off unless enabled)\n /** If true, allow recording negative examples and apply a soft penalty during ranking. */\n negativeExamplesEnabled: boolean;\n /** Score penalty per \"not useful\" hit (typical QMD scores ~0-1). Keep small. */\n negativeExamplesPenaltyPerHit: number;\n /** Maximum penalty applied from negative examples. */\n negativeExamplesPenaltyCap: number;\n // Chunking (Phase 2A)\n chunkingEnabled: boolean;\n chunkingTargetTokens: number;\n chunkingMinTokens: number;\n chunkingOverlapSentences: number;\n // Contradiction Detection (Phase 2B)\n contradictionDetectionEnabled: boolean;\n contradictionSimilarityThreshold: number;\n contradictionMinConfidence: number;\n contradictionAutoResolve: boolean;\n // Memory Linking (Phase 3A)\n memoryLinkingEnabled: boolean;\n // Conversation Threading (Phase 3B)\n threadingEnabled: boolean;\n threadingGapMinutes: number;\n // Memory Summarization (Phase 4A)\n summarizationEnabled: boolean;\n summarizationTriggerCount: number;\n summarizationRecentToKeep: number;\n summarizationImportanceThreshold: number;\n summarizationProtectedTags: string[];\n // Topic Extraction (Phase 4B)\n topicExtractionEnabled: boolean;\n topicExtractionTopN: number;\n // Transcript & Context Preservation (v2.0)\n // Transcript archive\n transcriptEnabled: boolean;\n transcriptRetentionDays: number;\n /** Channel types to skip from transcript logging (e.g., [\"cron\"]) */\n transcriptSkipChannelTypes: string[];\n // Transcript injection\n transcriptRecallHours: number;\n maxTranscriptTurns: number;\n maxTranscriptTokens: number;\n // Checkpoint\n checkpointEnabled: boolean;\n checkpointTurns: number;\n // Compaction reset: trigger session reset after compaction instead of continuing degraded.\n // Requires OC fork with PR #29985 (api.resetSession).\n compactionResetEnabled: boolean;\n // Hourly summaries\n hourlySummariesEnabled: boolean;\n daySummaryEnabled: boolean;\n /** If true, Engram may attempt to auto-register an hourly summary cron job (default off). */\n hourlySummaryCronAutoRegister: boolean;\n summaryRecallHours: number;\n maxSummaryCount: number;\n summaryModel: string;\n // v2.4 Extended hourly summaries\n hourlySummariesExtendedEnabled: boolean;\n hourlySummariesIncludeToolStats: boolean;\n hourlySummariesIncludeSystemMessages: boolean;\n hourlySummariesMaxTurnsPerRun: number;\n // v2.4 Conversation index (optional)\n conversationIndexEnabled: boolean;\n conversationIndexBackend: \"qmd\" | \"faiss\";\n conversationIndexQmdCollection: string;\n conversationIndexRetentionDays: number;\n conversationIndexMinUpdateIntervalMs: number;\n conversationIndexEmbedOnUpdate: boolean;\n conversationIndexFaissScriptPath?: string;\n conversationIndexFaissPythonBin?: string;\n conversationIndexFaissModelId: string;\n conversationIndexFaissIndexDir: string;\n conversationIndexFaissUpsertTimeoutMs: number;\n conversationIndexFaissSearchTimeoutMs: number;\n conversationIndexFaissHealthTimeoutMs: number;\n conversationIndexFaissMaxBatchSize: number;\n conversationIndexFaissMaxSearchK: number;\n conversationRecallTopK: number;\n conversationRecallMaxChars: number;\n conversationRecallTimeoutMs: number;\n // Evaluation harness foundation\n evalHarnessEnabled: boolean;\n evalShadowModeEnabled: boolean;\n benchmarkBaselineSnapshotsEnabled: boolean;\n benchmarkDeltaReporterEnabled: boolean;\n benchmarkStoredBaselineEnabled: boolean;\n evalStoreDir: string;\n // Objective-state memory foundation\n objectiveStateMemoryEnabled: boolean;\n objectiveStateSnapshotWritesEnabled: boolean;\n objectiveStateRecallEnabled: boolean;\n objectiveStateStoreDir: string;\n // Causal trajectory memory foundation\n causalTrajectoryMemoryEnabled: boolean;\n causalTrajectoryStoreDir: string;\n causalTrajectoryRecallEnabled: boolean;\n actionGraphRecallEnabled: boolean;\n // Trust-zone memory foundation\n trustZonesEnabled: boolean;\n quarantinePromotionEnabled: boolean;\n trustZoneStoreDir: string;\n trustZoneRecallEnabled: boolean;\n memoryPoisoningDefenseEnabled: boolean;\n memoryRedTeamBenchEnabled: boolean;\n // Harmonic retrieval foundation\n harmonicRetrievalEnabled: boolean;\n abstractionAnchorsEnabled: boolean;\n abstractionNodeStoreDir: string;\n // Episodic/semantic split foundation\n verifiedRecallEnabled: boolean;\n semanticRulePromotionEnabled: boolean;\n semanticRuleVerificationEnabled: boolean;\n semanticConsolidationEnabled: boolean;\n semanticConsolidationModel: string;\n semanticConsolidationThreshold: number;\n semanticConsolidationMinClusterSize: number;\n semanticConsolidationExcludeCategories: string[];\n semanticConsolidationIntervalHours: number;\n semanticConsolidationMaxPerRun: number;\n // Creation-memory foundation\n creationMemoryEnabled: boolean;\n memoryUtilityLearningEnabled: boolean;\n promotionByOutcomeEnabled: boolean;\n commitmentLedgerEnabled: boolean;\n commitmentLifecycleEnabled: boolean;\n commitmentStaleDays: number;\n commitmentLedgerDir: string;\n resumeBundlesEnabled: boolean;\n resumeBundleDir: string;\n workProductRecallEnabled: boolean;\n workProductLedgerDir: string;\n workTasksEnabled: boolean;\n workProjectsEnabled: boolean;\n workTasksDir: string;\n workProjectsDir: string;\n workIndexEnabled: boolean;\n workIndexDir: string;\n workTaskIndexEnabled: boolean;\n workProjectIndexEnabled: boolean;\n workIndexAutoRebuildEnabled: boolean;\n workIndexAutoRebuildDebounceMs: number;\n // Local LLM Provider (v2.1)\n localLlmEnabled: boolean;\n localLlmUrl: string;\n localLlmModel: string;\n /** Optional API key for authenticated OpenAI-compatible endpoints. */\n localLlmApiKey?: string;\n /** Additional headers for local/compatible endpoint requests. */\n localLlmHeaders?: Record<string, string>;\n /** If false, do not send Authorization header even when localLlmApiKey is set. */\n localLlmAuthHeader: boolean;\n localLlmFallback: boolean;\n /** Optional home directory override for local LLM helpers (LM Studio settings, CLI PATH). */\n localLlmHomeDir?: string;\n /** Optional absolute path to LMS CLI binary (preferred over auto-detection). */\n localLmsCliPath?: string;\n /** Optional bin directory prepended to PATH for LMS CLI execution. */\n localLmsBinDir?: string;\n /** Hard timeout for local LLM requests (ms). */\n localLlmTimeoutMs: number;\n /** Max context window for local LLM (override auto-detection). Set lower if your LLM server defaults to smaller contexts. */\n localLlmMaxContext?: number;\n // Observability\n /** If true, log slow operations (local LLM + related I/O) with durations and metadata (no content). */\n slowLogEnabled: boolean;\n /**\n * If true, include the full recalled memory text in `RecallTraceEvent.recalledContent`.\n * Disabled by default — enable only when you want external trace subscribers (e.g. Langfuse)\n * to see the exact memory context injected into each conversation turn.\n * This adds payload to trace events but does not log to files or the gateway log.\n */\n traceRecallContent: boolean;\n /** Threshold for slow operation logging (ms). */\n slowLogThresholdMs: number;\n // Extraction stability guards (P0/P1)\n extractionDedupeEnabled: boolean;\n extractionDedupeWindowMs: number;\n extractionMinChars: number;\n extractionMinUserTurns: number;\n extractionMaxTurnChars: number;\n extractionMaxFactsPerRun: number;\n extractionMaxEntitiesPerRun: number;\n extractionMaxQuestionsPerRun: number;\n extractionMaxProfileUpdatesPerRun: number;\n consolidationRequireNonZeroExtraction: boolean;\n consolidationMinIntervalMs: number;\n // QMD maintenance (debounced singleflight)\n qmdMaintenanceEnabled: boolean;\n qmdMaintenanceDebounceMs: number;\n qmdAutoEmbedEnabled: boolean;\n qmdEmbedMinIntervalMs: number;\n qmdUpdateTimeoutMs: number;\n qmdUpdateMinIntervalMs: number;\n // Local LLM resilience\n localLlmRetry5xxCount: number;\n localLlmRetryBackoffMs: number;\n localLlm400TripThreshold: number;\n localLlm400CooldownMs: number;\n // Local LLM fast tier (v9.1) — smaller model for quick ops\n localLlmFastEnabled: boolean;\n localLlmFastModel: string;\n localLlmFastUrl: string;\n localLlmFastTimeoutMs: number;\n // Gateway config for fallback AI\n gatewayConfig?: GatewayConfig;\n // Gateway model source (v9.2) — route LLM calls through gateway agent model chain\n modelSource: \"plugin\" | \"gateway\";\n gatewayAgentId: string;\n fastGatewayAgentId: string;\n\n // v3.0 Multi-agent memory (namespaces)\n namespacesEnabled: boolean;\n defaultNamespace: string;\n sharedNamespace: string;\n principalFromSessionKeyMode: PrincipalFromSessionKeyMode;\n principalFromSessionKeyRules: PrincipalRule[];\n namespacePolicies: NamespacePolicy[];\n defaultRecallNamespaces: Array<\"self\" | \"shared\">;\n cronRecallMode: CronRecallMode;\n cronRecallAllowlist: string[];\n cronRecallPolicyEnabled: boolean;\n cronRecallNormalizedQueryMaxChars: number;\n cronRecallInstructionHeavyTokenCap: number;\n cronConversationRecallMode: CronConversationRecallMode;\n autoPromoteToSharedEnabled: boolean;\n autoPromoteToSharedCategories: Array<\"fact\" | \"correction\" | \"decision\" | \"preference\">;\n autoPromoteMinConfidenceTier: ConfidenceTier;\n routingRulesEnabled: boolean;\n routingRulesStateFile: string;\n\n // v4.0 Shared-context (cross-agent shared intelligence)\n sharedContextEnabled: boolean;\n sharedContextDir?: string;\n sharedContextMaxInjectChars: number;\n crossSignalsSemanticEnabled: boolean;\n crossSignalsSemanticTimeoutMs: number;\n sharedCrossSignalSemanticEnabled?: boolean;\n sharedCrossSignalSemanticTimeoutMs?: number;\n sharedCrossSignalSemanticMaxCandidates?: number;\n\n // v5.0 Compounding engine\n compoundingEnabled: boolean;\n compoundingWeeklyCronEnabled: boolean;\n compoundingSemanticEnabled: boolean;\n compoundingSynthesisTimeoutMs: number;\n compoundingInjectEnabled: boolean;\n\n // IRC (Inductive Rule Consolidation) — preference synthesis\n ircEnabled: boolean;\n ircMaxPreferences: number;\n ircIncludeCorrections: boolean;\n ircMinConfidence: number;\n\n // CMC (Causal Memory Consolidation) — cross-session causal reasoning\n cmcEnabled: boolean;\n cmcStitchLookbackDays: number;\n cmcStitchMinScore: number;\n cmcStitchMaxEdgesPerTrajectory: number;\n cmcConsolidationEnabled: boolean;\n cmcConsolidationMinRecurrence: number;\n cmcConsolidationMinSessions: number;\n cmcConsolidationSuccessThreshold: number;\n cmcRetrievalEnabled: boolean;\n cmcRetrievalMaxDepth: number;\n cmcRetrievalMaxChars: number;\n cmcRetrievalCounterfactualBoost: number;\n cmcBehaviorLearningEnabled: boolean;\n cmcBehaviorMinFrequency: number;\n cmcBehaviorMinSessions: number;\n cmcBehaviorConfidenceThreshold: number;\n cmcLifecycleCausalImpactWeight: number;\n\n // PEDC (Prediction-Error-Driven Calibration) — model-user alignment\n calibrationEnabled: boolean;\n calibrationMaxRulesPerRecall: number;\n calibrationMaxChars: number;\n\n // Search backend abstraction\n searchBackend?: \"qmd\" | \"remote\" | \"noop\" | \"lancedb\" | \"meilisearch\" | \"orama\";\n remoteSearchBaseUrl?: string;\n remoteSearchApiKey?: string;\n remoteSearchTimeoutMs?: number;\n\n // LanceDB backend\n lancedbEnabled: boolean;\n lanceDbPath?: string;\n lanceEmbeddingDimension?: number;\n\n // Meilisearch backend\n meilisearchEnabled: boolean;\n meilisearchHost?: string;\n meilisearchApiKey?: string;\n meilisearchTimeoutMs?: number;\n meilisearchAutoIndex?: boolean;\n\n // Orama backend\n oramaEnabled: boolean;\n oramaDbPath?: string;\n oramaEmbeddingDimension?: number;\n\n // QMD daemon mode\n qmdDaemonEnabled: boolean;\n qmdDaemonUrl: string;\n qmdDaemonRecheckIntervalMs: number;\n qmdIntentHintsEnabled: boolean;\n qmdExplainEnabled: boolean;\n\n // v7.0 Knowledge Graph Enhancement\n knowledgeIndexEnabled: boolean;\n knowledgeIndexMaxEntities: number;\n knowledgeIndexMaxChars: number;\n entityRetrievalEnabled: boolean;\n entityRetrievalMaxChars: number;\n entityRetrievalMaxHints: number;\n entityRetrievalMaxSupportingFacts: number;\n entityRetrievalMaxRelatedEntities: number;\n entityRetrievalRecentTurns: number;\n // Recall assembly controls\n recallBudgetChars: number;\n recallOuterTimeoutMs: number;\n recallCoreDeadlineMs: number;\n recallEnrichmentDeadlineMs: number;\n recallPipeline: RecallSectionConfig[];\n qmdRecallCacheTtlMs: number;\n qmdRecallCacheStaleTtlMs: number;\n qmdRecallCacheMaxEntries: number;\n entityRelationshipsEnabled: boolean;\n entityActivityLogEnabled: boolean;\n entityActivityLogMaxEntries: number;\n entityAliasesEnabled: boolean;\n entitySummaryEnabled: boolean;\n\n // v6.0 Fact deduplication & archival\n /** Enable content-hash deduplication to prevent storing semantically identical facts. */\n factDeduplicationEnabled: boolean;\n /** Enable automatic archival of old, low-importance, rarely-accessed facts. */\n factArchivalEnabled: boolean;\n /** Minimum age in days before a fact is eligible for archival. */\n factArchivalAgeDays: number;\n /** Maximum importance score for archival eligibility (0-1). Only facts below this are archived. */\n factArchivalMaxImportance: number;\n /** Maximum access count for archival eligibility. Only rarely-accessed facts are archived. */\n factArchivalMaxAccessCount: number;\n /** Tags that protect a fact from archival regardless of other criteria. */\n factArchivalProtectedCategories: string[];\n // v8.3 Lifecycle policy engine\n lifecyclePolicyEnabled: boolean;\n lifecycleFilterStaleEnabled: boolean;\n lifecyclePromoteHeatThreshold: number;\n lifecycleStaleDecayThreshold: number;\n lifecycleArchiveDecayThreshold: number;\n lifecycleProtectedCategories: MemoryCategory[];\n lifecycleMetricsEnabled: boolean;\n // v8.3 proactive + policy learning\n proactiveExtractionEnabled: boolean;\n contextCompressionActionsEnabled: boolean;\n compressionGuidelineLearningEnabled: boolean;\n compressionGuidelineSemanticRefinementEnabled: boolean;\n compressionGuidelineSemanticTimeoutMs: number;\n maxProactiveQuestionsPerExtraction: number;\n proactiveExtractionTimeoutMs: number;\n proactiveExtractionMaxTokens: number;\n extractionMaxOutputTokens: number;\n proactiveExtractionCategoryAllowlist?: MemoryCategory[];\n maxCompressionTokensPerHour: number;\n behaviorLoopAutoTuneEnabled: boolean;\n behaviorLoopLearningWindowDays: number;\n behaviorLoopMinSignalCount: number;\n behaviorLoopMaxDeltaPerCycle: number;\n behaviorLoopProtectedParams: string[];\n // v8.0 Phase 1: recall planner + intent routing + verbatim artifacts\n recallPlannerEnabled: boolean;\n recallPlannerModel: string;\n recallPlannerTimeoutMs: number;\n recallPlannerUseResponsesApi: boolean;\n recallPlannerMaxPromptChars: number;\n recallPlannerMaxMemoryHints: number;\n recallPlannerShadowMode: boolean;\n recallPlannerTelemetryEnabled: boolean;\n recallPlannerMaxQmdResultsMinimal: number;\n recallPlannerMaxQmdResultsFull: number;\n intentRoutingEnabled: boolean;\n intentRoutingBoost: number;\n verbatimArtifactsEnabled: boolean;\n verbatimArtifactsMinConfidence: number;\n verbatimArtifactsMaxRecall: number;\n verbatimArtifactCategories: MemoryCategory[];\n // v8.0 Phase 2A: Memory Boxes + Trace Weaving\n memoryBoxesEnabled: boolean;\n /** Jaccard overlap threshold below which a topic shift triggers box sealing (0-1, default 0.35) */\n boxTopicShiftThreshold: number;\n /** Time gap in ms before an open box is sealed (default 30 min) */\n boxTimeGapMs: number;\n /** Max memories per box before forced seal */\n boxMaxMemories: number;\n traceWeaverEnabled: boolean;\n /** Days back to search for trace links */\n traceWeaverLookbackDays: number;\n /** Minimum Jaccard overlap to assign the same traceId (0-1, default 0.4) */\n traceWeaverOverlapThreshold: number;\n /** Number of recent days of boxes to inject during recall */\n boxRecallDays: number;\n // v8.0 Phase 2B: Episode/Note dual store (HiMem)\n /** Classify extracted memories as episode or note and tag with memoryKind */\n episodeNoteModeEnabled: boolean;\n // v8.1 Temporal + Tag Indexes (SwiftMem-inspired)\n /** Build and maintain temporal (state/index_time.json) and tag (state/index_tags.json) indexes */\n queryAwareIndexingEnabled: boolean;\n /** Max candidate paths returned from index prefilter (0 = no cap) */\n queryAwareIndexingMaxCandidates: number;\n temporalIndexWindowDays: number;\n temporalIndexMaxEntries: number;\n temporalBoostRecentDays: number;\n temporalBoostScore: number;\n temporalDecayEnabled: boolean;\n tagMemoryEnabled: boolean;\n tagMaxPerMemory: number;\n tagIndexMaxEntries: number;\n tagRecallBoost: number;\n tagRecallMaxMatches: number;\n // v8.2 multi-graph memory (PR 18)\n multiGraphMemoryEnabled: boolean;\n // v8.2 PR 19A: graph recall planner gating\n graphRecallEnabled: boolean;\n graphRecallMaxExpansions: number;\n graphRecallMaxPerSeed: number;\n graphRecallMinEdgeWeight: number;\n graphRecallShadowEnabled: boolean;\n graphRecallSnapshotEnabled: boolean;\n graphRecallShadowSampleRate: number;\n graphRecallExplainToolEnabled: boolean;\n graphRecallStoreColdMirror: boolean;\n graphRecallColdMirrorCollection?: string;\n graphRecallColdMirrorMinAgeDays: number;\n graphRecallUseEntityPriors: boolean;\n graphRecallEntityPriorBoost: number;\n graphRecallPreferHubSeeds: boolean;\n graphRecallHubBias: number;\n graphRecallRecencyHalfLifeDays: number;\n graphRecallDampingFactor: number;\n graphRecallMaxSeedNodes: number;\n graphRecallMaxExpandedNodes: number;\n graphRecallMaxTrailPerNode: number;\n graphRecallMinSeedScore: number;\n graphRecallExpansionScoreThreshold: number;\n graphRecallExplainMaxPaths: number;\n graphRecallExplainMaxChars: number;\n graphRecallExplainEdgeLimit: number;\n graphRecallExplainEnabled: boolean;\n graphRecallEntityHintsEnabled: boolean;\n graphRecallEntityHintMax: number;\n graphRecallEntityHintMaxChars: number;\n graphRecallSnapshotDir: string;\n graphRecallEnableTrace: boolean;\n graphRecallEnableDebug: boolean;\n /** Allow graph_mode escalation for broader causal/timeline phrasing beyond strict keywords. */\n graphExpandedIntentEnabled?: boolean;\n /** Run bounded graph expansion in full mode when enough recall seeds exist. */\n graphAssistInFullModeEnabled?: boolean;\n /** In full mode, compute graph assist for telemetry/snapshotting but do not inject merged results. */\n graphAssistShadowEvalEnabled?: boolean;\n /** Minimum seed results required before full-mode graph assist runs. */\n graphAssistMinSeedResults?: number;\n entityGraphEnabled: boolean;\n timeGraphEnabled: boolean;\n /** When true, write fallback temporal adjacency edges for consecutive extracted memories. */\n graphWriteSessionAdjacencyEnabled?: boolean;\n causalGraphEnabled: boolean;\n maxGraphTraversalSteps: number;\n graphActivationDecay: number;\n /** Weight of graph activation score when blending with seed QMD score (0-1). */\n graphExpansionActivationWeight: number;\n /** Lower bound for blended graph-expanded recall scores (0-1). */\n graphExpansionBlendMin: number;\n /** Upper bound for blended graph-expanded recall scores (0-1). */\n graphExpansionBlendMax: number;\n maxEntityGraphEdgesPerMemory: number;\n /** SimpleMem-inspired de-linearization: resolve pronouns and anchor relative dates after extraction. */\n delinearizeEnabled: boolean;\n /** Synapse-inspired confidence gate — skip memory injection when top score is below threshold. */\n recallConfidenceGateEnabled: boolean;\n recallConfidenceGateThreshold: number;\n /** PlugMem-inspired causal rule extraction: mine IF→THEN rules during consolidation. */\n causalRuleExtractionEnabled: boolean;\n /** E-Mem-inspired memory reconstruction: targeted retrieval for missing entity context. */\n memoryReconstructionEnabled: boolean;\n /** Maximum number of entity expansions per recall. */\n memoryReconstructionMaxExpansions: number;\n /** Synapse-inspired lateral inhibition to suppress hub-node dominance. */\n graphLateralInhibitionEnabled: boolean;\n /** Inhibition strength (default 0.15). Higher = more suppression. */\n graphLateralInhibitionBeta: number;\n /** Number of top competing nodes considered for inhibition (default 7). */\n graphLateralInhibitionTopM: number;\n // v8.2: Temporal Memory Tree\n temporalMemoryTreeEnabled: boolean;\n tmtHourlyMinMemories: number;\n tmtSummaryMaxTokens: number;\n // Lossless Context Management (LCM)\n lcmEnabled: boolean;\n lcmLeafBatchSize: number;\n lcmRollupFanIn: number;\n lcmFreshTailTurns: number;\n lcmMaxDepth: number;\n lcmRecallBudgetShare: number;\n lcmDeterministicMaxTokens: number;\n lcmArchiveRetentionDays: number;\n\n // v9.1 Parallel Specialized Retrieval (ASMR-inspired)\n /** Enable three-agent parallel retrieval (DirectFact + Contextual + Temporal). Default false. */\n parallelRetrievalEnabled: boolean;\n /** Per-agent source weights for score blending during merge. */\n parallelAgentWeights: { direct: number; contextual: number; temporal: number };\n /** Max results fetched per agent before merge. */\n parallelMaxResultsPerAgent: number;\n}\n\nexport interface BootstrapOptions {\n dryRun?: boolean;\n sessionsDir?: string;\n limit?: number;\n since?: Date;\n}\n\nexport interface BootstrapResult {\n sessionsScanned: number;\n turnsProcessed: number;\n highSignalTurns: number;\n memoriesCreated: number;\n skipped: number;\n}\n\nexport interface PrincipalRule {\n match: string;\n principal: string;\n}\n\nexport interface NamespacePolicy {\n name: string;\n readPrincipals: string[];\n writePrincipals: string[];\n includeInRecallByDefault?: boolean;\n}\n\nexport interface RelevanceFeedback {\n up: number;\n down: number;\n lastUpdatedAt: string;\n notes?: string[];\n}\n\nexport interface BufferTurn {\n role: \"user\" | \"assistant\";\n content: string;\n timestamp: string;\n sessionKey?: string;\n}\n\nexport interface BufferState {\n turns: BufferTurn[];\n lastExtractionAt: string | null;\n extractionCount: number;\n}\n\nexport interface BehaviorLoopAdjustment {\n parameter: string;\n previousValue: number;\n nextValue: number;\n delta: number;\n evidenceCount: number;\n confidence: number;\n reason: string;\n appliedAt: string;\n}\n\nexport interface BehaviorLoopPolicyState {\n version: number;\n windowDays: number;\n minSignalCount: number;\n maxDeltaPerCycle: number;\n protectedParams: string[];\n adjustments: BehaviorLoopAdjustment[];\n updatedAt: string;\n}\n\nexport type BehaviorSignalType = \"correction_override\" | \"preference_affinity\" | \"topic_revisitation\" | \"action_pattern\" | \"outcome_preference\" | \"phrasing_style\";\nexport type BehaviorSignalDirection = \"positive\" | \"negative\";\n\nexport interface BehaviorSignalEvent {\n timestamp: string;\n namespace: string;\n memoryId: string;\n category: Extract<MemoryCategory, \"correction\" | \"preference\">;\n signalType: BehaviorSignalType;\n direction: BehaviorSignalDirection;\n confidence: number;\n signalHash: string;\n source: \"extraction\" | \"correction\";\n}\n\n/** Memory status for lifecycle management */\nexport type MemoryStatus = \"active\" | \"pending_review\" | \"rejected\" | \"quarantined\" | \"superseded\" | \"archived\";\nexport type LifecycleState = \"candidate\" | \"validated\" | \"active\" | \"stale\" | \"archived\";\nexport type VerificationState = \"unverified\" | \"user_confirmed\" | \"system_inferred\" | \"disputed\";\nexport type PolicyClass = \"ephemeral\" | \"durable\" | \"protected\";\n\n/** Importance level tiers */\nexport type ImportanceLevel = \"critical\" | \"high\" | \"normal\" | \"low\" | \"trivial\";\n\n/** Importance scoring result */\nexport interface ImportanceScore {\n /** Numeric score 0-1 */\n score: number;\n /** Tier level */\n level: ImportanceLevel;\n /** Reasons for this score */\n reasons: string[];\n /** Salient keywords extracted */\n keywords: string[];\n}\n\nexport interface MemoryFrontmatter {\n id: string;\n category: MemoryCategory;\n created: string;\n updated: string;\n source: string;\n confidence: number;\n confidenceTier: ConfidenceTier;\n tags: string[];\n entityRef?: string;\n supersedes?: string;\n /** ISO 8601 date — memory expires and gets cleaned up after this date */\n expiresAt?: string;\n /** IDs of parent memories this was derived from (lineage tracking) */\n lineage?: string[];\n /** Memory status: active (default), pending_review, rejected, quarantined, superseded, or archived */\n status?: MemoryStatus;\n /** ID of memory that superseded this one */\n supersededBy?: string;\n /** Timestamp when superseded */\n supersededAt?: string;\n /** Timestamp when archived */\n archivedAt?: string;\n /** Policy-driven lifecycle state used for retrieval eligibility/ranking. */\n lifecycleState?: LifecycleState;\n /** Verification provenance used by lifecycle policy. */\n verificationState?: VerificationState;\n /** Policy class used by lifecycle guardrails. */\n policyClass?: PolicyClass;\n /** Last lifecycle validation timestamp (ISO 8601). */\n lastValidatedAt?: string;\n /** Lifecycle decay score in [0,1]. */\n decayScore?: number;\n /** Lifecycle heat score in [0,1]. */\n heatScore?: number;\n // Access tracking (Phase 1A)\n /** Number of times this memory has been retrieved */\n accessCount?: number;\n /** Last time this memory was accessed (ISO 8601) */\n lastAccessed?: string;\n // Importance scoring (Phase 1B)\n /** Importance score with level, reasons, and keywords */\n importance?: ImportanceScore;\n // Chunking (Phase 2A)\n /** Parent memory ID if this is a chunk */\n parentId?: string;\n /** Chunk index within parent (0-based) */\n chunkIndex?: number;\n /** Total number of chunks for this parent */\n chunkTotal?: number;\n // Memory Linking (Phase 3A)\n /** Links to other memories */\n links?: MemoryLink[];\n // Intent-grounded memory routing (v8.0 phase 1)\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n // Verbatim artifact lineage (v8.0 phase 1)\n artifactType?: \"decision\" | \"constraint\" | \"todo\" | \"definition\" | \"commitment\" | \"correction\" | \"fact\";\n sourceMemoryId?: string;\n sourceTurnId?: string;\n // v8.0 Phase 2B: HiMem episode/note classification\n /** episode = time-specific event; note = stable belief/preference/decision */\n memoryKind?: \"episode\" | \"note\";\n /** Structured key-value attributes extracted from the content (e.g., product attributes, dates, quantities). */\n structuredAttributes?: Record<string, string>;\n}\n\n/** Memory link relationship types */\nexport type MemoryLinkType = \"follows\" | \"references\" | \"contradicts\" | \"supports\" | \"related\";\n\n/** A link between memories */\nexport interface MemoryLink {\n targetId: string;\n linkType: MemoryLinkType;\n strength: number;\n reason?: string;\n}\n\n// Conversation Threading (Phase 3B)\nexport interface ConversationThread {\n id: string;\n title: string;\n createdAt: string;\n updatedAt: string;\n sessionKey?: string;\n episodeIds: string[];\n linkedThreadIds: string[];\n}\n\n// Memory Summarization (Phase 4A)\nexport interface MemorySummary {\n id: string;\n createdAt: string;\n timeRangeStart: string;\n timeRangeEnd: string;\n summaryText: string;\n keyFacts: string[];\n keyEntities: string[];\n sourceEpisodeIds: string[];\n}\n\nexport interface DaySummaryResult {\n summary: string;\n bullets: string[];\n next_actions: string[];\n risks_or_open_loops: string[];\n}\n\n// Topic Extraction (Phase 4B)\nexport interface TopicScore {\n term: string;\n score: number;\n count: number;\n}\n\nexport interface MemoryFile {\n path: string;\n frontmatter: MemoryFrontmatter;\n content: string;\n}\n\nexport interface ExtractedFact {\n category: MemoryCategory;\n content: string;\n confidence: number;\n tags: string[];\n entityRef?: string;\n source?: ExtractionPassSource;\n promptedByQuestion?: string;\n /** Structured key-value attributes extracted from the content (e.g., product attributes, dates, quantities). */\n structuredAttributes?: Record<string, string>;\n}\n\nexport interface MemoryIntent {\n goal: string;\n actionType: string;\n entityTypes: string[];\n}\n\nexport interface ExtractedQuestion {\n question: string;\n context: string;\n priority: number;\n}\n\nexport interface QuestionEntry {\n id: string;\n question: string;\n context: string;\n priority: number; // 0-1, higher = more important\n created: string;\n resolved: boolean;\n resolvedAt?: string;\n}\n\nexport interface ExtractionResult {\n facts: ExtractedFact[];\n profileUpdates: string[];\n entities: EntityMention[];\n questions: ExtractedQuestion[];\n identityReflection?: string;\n relationships?: ExtractedRelationship[];\n}\n\nexport interface EntityMention {\n name: string;\n type: \"person\" | \"project\" | \"tool\" | \"company\" | \"place\" | \"other\";\n facts: string[];\n source?: ExtractionPassSource;\n promptedByQuestion?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Knowledge Graph Enhancement (Entity Relationships, Activity, Scoring)\n// ---------------------------------------------------------------------------\n\nexport interface EntityRelationship {\n target: string;\n label: string;\n}\n\nexport interface EntityActivityEntry {\n date: string;\n note: string;\n}\n\nexport interface EntityFile {\n name: string;\n type: string;\n updated: string;\n facts: string[];\n summary?: string;\n relationships: EntityRelationship[];\n activity: EntityActivityEntry[];\n aliases: string[];\n}\n\nexport interface ScoredEntity {\n name: string;\n type: string;\n score: number;\n factCount: number;\n summary?: string;\n topRelationships: string[];\n}\n\nexport interface ExtractedRelationship {\n source: string;\n target: string;\n label: string;\n extractionSource?: ExtractionPassSource;\n promptedByQuestion?: string;\n}\n\nexport interface ConsolidationItem {\n existingId: string;\n action: ConsolidationAction;\n mergeWith?: string;\n updatedContent?: string;\n reason: string;\n}\n\nexport interface ConsolidationResult {\n items: ConsolidationItem[];\n profileUpdates: string[];\n entityUpdates: EntityMention[];\n}\n\nexport interface QmdSearchResult {\n docid: string;\n path: string;\n snippet: string;\n score: number;\n explain?: QmdSearchExplain;\n transport?: \"daemon\" | \"subprocess\" | \"hybrid\" | \"scoped_prefilter\";\n}\n\nexport interface QmdSearchExplain {\n ftsScores?: number[];\n vectorScores?: number[];\n rrf?: number;\n rerankScore?: number;\n blendedScore?: number;\n}\n\nexport interface MetaState {\n extractionCount: number;\n lastExtractionAt: string | null;\n lastConsolidationAt: string | null;\n totalMemories: number;\n totalEntities: number;\n}\n\nexport type MemoryActionType =\n | \"store_episode\"\n | \"store_note\"\n | \"update_note\"\n | \"create_artifact\"\n | \"summarize_node\"\n | \"discard\"\n | \"link_graph\";\n\nexport type MemoryActionOutcome = \"applied\" | \"skipped\" | \"failed\";\n\nexport type MemoryActionPolicyDecision = \"allow\" | \"defer\" | \"deny\";\n\nexport type MemoryActionStatus = \"validated\" | \"applied\" | \"rejected\";\n\nexport type MemoryActionEligibilitySource =\n | \"extraction\"\n | \"consolidation\"\n | \"replay\"\n | \"manual\"\n | \"unknown\";\n\nexport interface MemoryActionEligibilityContext {\n confidence: number;\n lifecycleState: LifecycleState;\n importance: number;\n source: MemoryActionEligibilitySource;\n}\n\nexport interface MemoryActionPolicyResult {\n action: MemoryActionType;\n decision: MemoryActionPolicyDecision;\n rationale: string;\n eligibility: MemoryActionEligibilityContext;\n}\n\nexport interface MemoryActionEvent {\n schemaVersion?: number;\n actionId?: string;\n timestamp: string;\n action: MemoryActionType;\n outcome: MemoryActionOutcome;\n status?: MemoryActionStatus;\n actor?: string;\n subsystem?: string;\n reason?: string;\n memoryId?: string;\n namespace?: string;\n sessionKey?: string;\n sourceSessionKey?: string;\n checkpointCapturedAt?: string;\n checkpointTtl?: string;\n checkpointTurnCount?: number;\n inputSummary?: string;\n outputMemoryIds?: string[];\n dryRun?: boolean;\n policyVersion?: string;\n promptHash?: string;\n policyDecision?: MemoryActionPolicyDecision;\n policyRationale?: string;\n policyEligibility?: MemoryActionEligibilityContext;\n}\n\nexport type MemoryLifecycleEventType =\n | \"created\"\n | \"updated\"\n | \"superseded\"\n | \"archived\"\n | \"rejected\"\n | \"restored\"\n | \"merged\"\n | \"imported\"\n | \"promoted\"\n | \"explicit_capture_accepted\"\n | \"explicit_capture_queued\";\n\nexport interface MemoryLifecycleStateSummary {\n category?: MemoryCategory;\n path?: string;\n status?: MemoryStatus;\n lifecycleState?: LifecycleState;\n}\n\nexport interface MemoryLifecycleEvent {\n eventId: string;\n memoryId: string;\n eventType: MemoryLifecycleEventType;\n timestamp: string;\n actor: string;\n reasonCode?: string;\n ruleVersion: string;\n relatedMemoryIds?: string[];\n before?: MemoryLifecycleStateSummary;\n after?: MemoryLifecycleStateSummary;\n correlationId?: string;\n}\n\nexport interface MemoryProjectionCurrentState {\n memoryId: string;\n category: MemoryCategory;\n status: MemoryStatus;\n lifecycleState?: LifecycleState;\n path: string;\n pathRel: string;\n created: string;\n updated: string;\n archivedAt?: string;\n supersededAt?: string;\n entityRef?: string;\n source: string;\n confidence: number;\n confidenceTier: ConfidenceTier;\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n accessCount?: number;\n lastAccessed?: string;\n tags?: string[];\n preview?: string;\n}\n\nexport interface CompressionGuidelineOptimizerSourceWindow {\n from: string;\n to: string;\n}\n\nexport interface CompressionGuidelineOptimizerEventCounts {\n total: number;\n applied: number;\n skipped: number;\n failed: number;\n}\n\nexport type CompressionGuidelineActivationState = \"draft\" | \"active\";\n\nexport interface CompressionGuidelineOptimizerActionSummary {\n action: MemoryActionType;\n total: number;\n outcomes: Record<MemoryActionOutcome, number>;\n quality: {\n good: number;\n poor: number;\n unknown: number;\n };\n}\n\nexport interface CompressionGuidelineOptimizerRuleUpdate {\n action: MemoryActionType;\n delta: number;\n direction: \"increase\" | \"decrease\" | \"hold\";\n confidence: \"low\" | \"medium\" | \"high\";\n notes: string[];\n}\n\nexport interface CompressionGuidelineOptimizerState {\n version: number;\n updatedAt: string;\n sourceWindow: CompressionGuidelineOptimizerSourceWindow;\n eventCounts: CompressionGuidelineOptimizerEventCounts;\n guidelineVersion: number;\n contentHash?: string;\n activationState?: CompressionGuidelineActivationState;\n actionSummaries?: CompressionGuidelineOptimizerActionSummary[];\n ruleUpdates?: CompressionGuidelineOptimizerRuleUpdate[];\n}\n\nexport type ContinuityIncidentState = \"open\" | \"closed\";\n\nexport interface ContinuityIncidentRecord {\n id: string;\n state: ContinuityIncidentState;\n openedAt: string;\n updatedAt: string;\n triggerWindow?: string;\n symptom: string;\n suspectedCause?: string;\n fixApplied?: string;\n verificationResult?: string;\n preventiveRule?: string;\n closedAt?: string;\n filePath?: string;\n}\n\nexport interface ContinuityIncidentOpenInput {\n triggerWindow?: string;\n symptom: string;\n suspectedCause?: string;\n}\n\nexport interface ContinuityIncidentCloseInput {\n fixApplied: string;\n verificationResult: string;\n preventiveRule?: string;\n}\n\nexport type ContinuityLoopCadence = \"daily\" | \"weekly\" | \"monthly\" | \"quarterly\";\nexport type ContinuityLoopStatus = \"active\" | \"paused\" | \"retired\";\n\nexport interface ContinuityImprovementLoop {\n id: string;\n cadence: ContinuityLoopCadence;\n purpose: string;\n status: ContinuityLoopStatus;\n killCondition: string;\n lastReviewed: string;\n notes?: string;\n}\n\nexport interface ContinuityLoopUpsertInput {\n id: string;\n cadence: ContinuityLoopCadence;\n purpose: string;\n status: ContinuityLoopStatus;\n killCondition: string;\n lastReviewed?: string;\n notes?: string;\n}\n\nexport interface ContinuityLoopReviewInput {\n status?: ContinuityLoopStatus;\n notes?: string;\n reviewedAt?: string;\n}\n\n/** Entry in the access tracking buffer (batched updates) */\nexport interface AccessTrackingEntry {\n memoryId: string;\n newCount: number;\n lastAccessed: string;\n}\n\nexport interface SignalScanResult {\n level: SignalLevel;\n patterns: string[];\n}\n\n// ============================================================================\n// LLM Trace Callback (for external observability plugins)\n// ============================================================================\n\nexport interface LlmTraceEvent {\n kind: \"llm_start\" | \"llm_end\" | \"llm_error\";\n traceId: string;\n model: string;\n operation: \"extraction\" | \"consolidation\" | \"profile_consolidation\" | \"identity_consolidation\" | \"day_summary\";\n input?: string;\n output?: string;\n durationMs?: number;\n error?: string;\n tokenUsage?: { input?: number; output?: number; total?: number };\n}\n\nexport interface RecallTraceEvent {\n kind: \"recall_summary\";\n traceId: string;\n operation: \"recall\";\n sessionKey?: string;\n promptHash: string;\n promptLength: number;\n retrievalQueryHash: string;\n retrievalQueryLength: number;\n recallMode: RecallPlanMode;\n recallResultLimit: number;\n qmdEnabled: boolean;\n qmdAvailable: boolean;\n recallNamespaces: string[];\n source: \"none\" | \"hot_qmd\" | \"hot_embedding\" | \"cold_fallback\" | \"recent_scan\";\n recalledMemoryCount: number;\n injected: boolean;\n contextChars: number;\n policyVersion?: string;\n identityInjectionMode?: IdentityInjectionMode | \"none\";\n identityInjectedChars?: number;\n identityInjectionTruncated?: boolean;\n durationMs: number;\n timings?: Record<string, string>;\n /**\n * The full recalled memory context injected into the system prompt.\n * Only populated when `traceRecallContent` config option is `true`.\n * Omitted by default to avoid sending potentially sensitive memory content\n * to external trace collectors unless explicitly opted in.\n */\n recalledContent?: string;\n}\n\nexport type EngramTraceEvent = LlmTraceEvent | RecallTraceEvent;\nexport type LlmTraceCallback = (event: EngramTraceEvent) => void;\n\n// ============================================================================\n// Gateway Configuration Types (for fallback AI)\n// ============================================================================\n\nexport type ModelApi = \"openai-completions\" | \"anthropic-messages\" | \"google-generative\" | string;\n\nexport type ModelProviderAuthMode = \"bearer\" | \"header\" | \"query\";\n\nexport interface ModelDefinitionConfig {\n id: string;\n name?: string;\n contextWindow?: number;\n maxOutputTokens?: number;\n costPer1MInput?: number;\n costPer1MOutput?: number;\n aliases?: string[];\n}\n\nexport interface ModelProviderConfig {\n baseUrl: string;\n apiKey?: string | Record<string, unknown>;\n auth?: ModelProviderAuthMode;\n api?: ModelApi;\n headers?: Record<string, string>;\n authHeader?: boolean;\n models: ModelDefinitionConfig[];\n}\n\nexport interface AgentDefaultsConfig {\n model?: {\n primary?: string;\n backup?: string;\n fallbacks?: string[];\n };\n thinking?: {\n mode?: \"off\" | \"on\" | \"adaptive\";\n budget?: number;\n };\n}\n\nexport interface AgentPersonaModelConfig {\n primary?: string;\n fallbacks?: string[];\n}\n\nexport interface AgentPersona {\n id: string;\n name?: string;\n model?: AgentPersonaModelConfig;\n}\n\nexport interface GatewayConfig {\n agents?: {\n defaults?: AgentDefaultsConfig;\n list?: AgentPersona[];\n };\n models?: {\n providers?: Record<string, ModelProviderConfig>;\n };\n}\n\n// ============================================================================\n// Transcript & Context Preservation (v2.0)\n// ============================================================================\n\nexport interface TranscriptEntry {\n timestamp: string;\n role: \"user\" | \"assistant\";\n content: string;\n sessionKey: string;\n turnId: string;\n metadata?: {\n compactAfter?: boolean;\n compactionId?: string | null;\n };\n}\n\nexport interface Checkpoint {\n sessionKey: string;\n capturedAt: string;\n turns: TranscriptEntry[];\n ttl: string; // ISO timestamp when checkpoint expires\n}\n\nexport interface HourlySummary {\n hour: string; // \"2026-02-08T14:00:00Z\"\n sessionKey: string;\n bullets: string[];\n turnCount: number;\n generatedAt: string;\n}\n","import path from \"node:path\";\nimport { readFileSync } from \"node:fs\";\nimport Database from \"better-sqlite3\";\nimport type {\n MemoryGovernanceAppliedAction,\n MemoryGovernanceMetrics,\n MemoryGovernanceReviewQueueEntry,\n MemoryGovernanceSummary,\n} from \"./maintenance/memory-governance.js\";\nimport type {\n MemoryCategory,\n MemoryLifecycleEvent,\n MemoryProjectionCurrentState,\n MemoryStatus,\n} from \"./types.js\";\n\nexport const MEMORY_PROJECTION_SCHEMA_VERSION = 2;\n\nexport interface ProjectedMemoryBrowseOptions {\n query?: string;\n status?: string;\n category?: string;\n sort?: \"updated_desc\" | \"updated_asc\" | \"created_desc\" | \"created_asc\";\n limit: number;\n offset: number;\n}\n\nexport interface ProjectedMemoryBrowseRow {\n id: string;\n path: string;\n category: MemoryCategory;\n status: MemoryStatus;\n created?: string;\n updated?: string;\n tags: string[];\n entityRef?: string;\n preview: string;\n}\n\nexport interface ProjectedMemoryBrowsePage {\n total: number;\n memories: ProjectedMemoryBrowseRow[];\n}\n\nexport interface ProjectedEntityMentionRow {\n memoryId: string;\n entityRef: string;\n mentionSource: string;\n created: string;\n updated: string;\n}\n\nexport interface ProjectedNativeKnowledgeChunkRow {\n chunkId: string;\n sourcePath: string;\n title: string;\n sourceKind: string;\n startLine: number;\n endLine: number;\n derivedDate?: string;\n sessionKey?: string;\n workflowKey?: string;\n author?: string;\n agent?: string;\n namespace?: string;\n privacyClass?: string;\n sourceHash?: string;\n preview: string;\n}\n\nexport interface MemoryProjectionGovernanceReviewQueueRow {\n runId: string;\n entryId: string;\n memoryId: string;\n path: string;\n reasonCode: MemoryGovernanceReviewQueueEntry[\"reasonCode\"];\n severity: MemoryGovernanceReviewQueueEntry[\"severity\"];\n suggestedAction: MemoryGovernanceReviewQueueEntry[\"suggestedAction\"];\n suggestedStatus?: MemoryGovernanceReviewQueueEntry[\"suggestedStatus\"];\n relatedMemoryIds: string[];\n}\n\nexport interface MemoryProjectionGovernanceAppliedActionRow {\n runId: string;\n rowKey: string;\n action: MemoryGovernanceAppliedAction[\"action\"];\n memoryId: string;\n reasonCode: MemoryGovernanceAppliedAction[\"reasonCode\"];\n beforeStatus: MemoryGovernanceAppliedAction[\"beforeStatus\"];\n afterStatus?: MemoryGovernanceAppliedAction[\"afterStatus\"];\n originalPath: string;\n currentPath: string;\n}\n\nexport interface ProjectedReviewQueueSnapshot {\n found: boolean;\n runId?: string;\n summary?: MemoryGovernanceSummary;\n metrics?: MemoryGovernanceMetrics;\n reviewQueue?: MemoryGovernanceReviewQueueEntry[];\n appliedActions?: MemoryGovernanceAppliedAction[];\n report?: string;\n}\n\nexport function getMemoryProjectionPath(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"memory-projection.sqlite\");\n}\n\nfunction listTableColumns(db: Database.Database, tableName: string): Set<string> {\n try {\n const rows = db.prepare(`PRAGMA table_info(${tableName})`).all() as Array<{ name?: unknown }>;\n return new Set(rows.map((row) => row.name).filter((name): name is string => typeof name === \"string\"));\n } catch {\n return new Set<string>();\n }\n}\n\nfunction migrateMemoryCurrentTable(db: Database.Database): void {\n const columns = listTableColumns(db, \"memory_current\");\n if (columns.size === 0) return;\n\n if (!columns.has(\"tags_json\")) {\n db.exec(`ALTER TABLE memory_current ADD COLUMN tags_json TEXT NOT NULL DEFAULT '[]'`);\n }\n if (!columns.has(\"preview_text\")) {\n db.exec(`ALTER TABLE memory_current ADD COLUMN preview_text TEXT NOT NULL DEFAULT ''`);\n }\n}\n\nfunction memoryCurrentRequiresMigration(db: Database.Database): boolean {\n const columns = listTableColumns(db, \"memory_current\");\n return columns.size > 0 && (!columns.has(\"tags_json\") || !columns.has(\"preview_text\"));\n}\n\nfunction migrateProjectionSchemaIfNeeded(memoryDir: string): void {\n const dbPath = getMemoryProjectionPath(memoryDir);\n try {\n const db = new Database(dbPath, { fileMustExist: true });\n try {\n if (!memoryCurrentRequiresMigration(db)) return;\n initializeMemoryProjectionDb(db);\n } finally {\n db.close();\n }\n } catch {\n // Fail open on migration attempts so readonly consumers can still use legacy rows.\n }\n}\n\nexport function memoryCurrentSelectExpressions(db: Database.Database): {\n tagsJson: string;\n previewText: string;\n} {\n const columns = listTableColumns(db, \"memory_current\");\n return {\n tagsJson: columns.has(\"tags_json\") ? \"tags_json\" : `'[]' AS tags_json`,\n previewText: columns.has(\"preview_text\") ? \"preview_text\" : `'' AS preview_text`,\n };\n}\n\nexport function initializeMemoryProjectionDb(db: Database.Database): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS memory_current (\n memory_id TEXT PRIMARY KEY,\n category TEXT NOT NULL,\n status TEXT NOT NULL,\n lifecycle_state TEXT,\n path_rel TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n archived_at TEXT,\n superseded_at TEXT,\n entity_ref TEXT,\n source TEXT NOT NULL,\n confidence REAL NOT NULL,\n confidence_tier TEXT NOT NULL,\n memory_kind TEXT,\n access_count INTEGER,\n last_accessed TEXT,\n tags_json TEXT NOT NULL DEFAULT '[]',\n preview_text TEXT NOT NULL DEFAULT ''\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_current_status\n ON memory_current(status);\n\n CREATE INDEX IF NOT EXISTS idx_memory_current_category\n ON memory_current(category);\n\n CREATE INDEX IF NOT EXISTS idx_memory_current_updated\n ON memory_current(updated_at DESC);\n\n CREATE TABLE IF NOT EXISTS memory_timeline (\n event_id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL,\n event_type TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n event_order INTEGER NOT NULL,\n actor TEXT NOT NULL,\n reason_code TEXT,\n rule_version TEXT NOT NULL,\n related_memory_ids_json TEXT,\n before_json TEXT,\n after_json TEXT,\n correlation_id TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_timeline_memory_ts\n ON memory_timeline(memory_id, timestamp, event_order);\n\n CREATE TABLE IF NOT EXISTS memory_entity_mentions (\n memory_id TEXT NOT NULL,\n entity_ref TEXT NOT NULL,\n mention_source TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (memory_id, entity_ref, mention_source)\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_entity_mentions_entity\n ON memory_entity_mentions(entity_ref, updated_at DESC);\n\n CREATE TABLE IF NOT EXISTS native_knowledge_chunks (\n chunk_id TEXT PRIMARY KEY,\n source_path TEXT NOT NULL,\n title TEXT NOT NULL,\n source_kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n derived_date TEXT,\n session_key TEXT,\n workflow_key TEXT,\n author TEXT,\n agent TEXT,\n namespace TEXT,\n privacy_class TEXT,\n source_hash TEXT,\n preview_text TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_native_knowledge_source_kind\n ON native_knowledge_chunks(source_kind);\n\n CREATE INDEX IF NOT EXISTS idx_native_knowledge_namespace\n ON native_knowledge_chunks(namespace);\n\n CREATE TABLE IF NOT EXISTS memory_review_runs (\n run_id TEXT PRIMARY KEY,\n created_at TEXT NOT NULL,\n mode TEXT NOT NULL,\n summary_json TEXT NOT NULL,\n metrics_json TEXT NOT NULL,\n applied_actions_json TEXT NOT NULL,\n report_markdown TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_review_runs_created\n ON memory_review_runs(created_at DESC);\n\n CREATE TABLE IF NOT EXISTS memory_review_queue (\n entry_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n memory_id TEXT NOT NULL,\n path TEXT NOT NULL,\n reason_code TEXT NOT NULL,\n severity TEXT NOT NULL,\n suggested_action TEXT NOT NULL,\n suggested_status TEXT,\n related_memory_ids_json TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_review_queue_run\n ON memory_review_queue(run_id, reason_code, memory_id);\n\n CREATE TABLE IF NOT EXISTS memory_review_actions (\n row_key TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n action TEXT NOT NULL,\n memory_id TEXT NOT NULL,\n reason_code TEXT NOT NULL,\n before_status TEXT NOT NULL,\n after_status TEXT,\n original_path TEXT NOT NULL,\n current_path TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_review_actions_run\n ON memory_review_actions(run_id, memory_id);\n `);\n\n migrateMemoryCurrentTable(db);\n db.prepare(\"INSERT OR REPLACE INTO meta(key, value) VALUES (?, ?)\")\n .run(\"schemaVersion\", String(MEMORY_PROJECTION_SCHEMA_VERSION));\n}\n\nfunction openProjectionReadonly(memoryDir: string): Database.Database | null {\n const dbPath = getMemoryProjectionPath(memoryDir);\n try {\n return new Database(dbPath, { readonly: true, fileMustExist: true });\n } catch {\n return null;\n }\n}\n\nfunction withProjectionReadonly<T>(\n memoryDir: string,\n reader: (db: Database.Database) => T,\n): T | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n let needsMigration = false;\n try {\n needsMigration = memoryCurrentRequiresMigration(db);\n return reader(db);\n } catch {\n return null;\n } finally {\n db.close();\n if (needsMigration) {\n migrateProjectionSchemaIfNeeded(memoryDir);\n }\n }\n}\n\nfunction parseStringArray(value: unknown): string[] {\n if (typeof value !== \"string\" || value.length === 0) return [];\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed) ? parsed.filter((entry): entry is string => typeof entry === \"string\") : [];\n } catch {\n return [];\n }\n}\n\nfunction parseJsonObject<T>(value: unknown): T | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n try {\n return JSON.parse(value) as T;\n } catch {\n return undefined;\n }\n}\n\nexport function parseCurrentRow(\n memoryDir: string,\n row: Record<string, unknown> | undefined,\n): MemoryProjectionCurrentState | null {\n if (!row) return null;\n if (\n typeof row.memory_id !== \"string\" ||\n typeof row.category !== \"string\" ||\n typeof row.status !== \"string\" ||\n typeof row.path_rel !== \"string\" ||\n typeof row.created_at !== \"string\" ||\n typeof row.updated_at !== \"string\" ||\n typeof row.source !== \"string\" ||\n typeof row.confidence !== \"number\" ||\n typeof row.confidence_tier !== \"string\"\n ) {\n return null;\n }\n\n return {\n memoryId: row.memory_id,\n category: row.category as MemoryProjectionCurrentState[\"category\"],\n status: row.status as MemoryStatus,\n lifecycleState:\n typeof row.lifecycle_state === \"string\"\n ? (row.lifecycle_state as MemoryProjectionCurrentState[\"lifecycleState\"])\n : undefined,\n path: path.join(memoryDir, row.path_rel),\n pathRel: row.path_rel,\n created: row.created_at,\n updated: row.updated_at,\n archivedAt: typeof row.archived_at === \"string\" ? row.archived_at : undefined,\n supersededAt: typeof row.superseded_at === \"string\" ? row.superseded_at : undefined,\n entityRef: typeof row.entity_ref === \"string\" ? row.entity_ref : undefined,\n source: row.source,\n confidence: row.confidence,\n confidenceTier: row.confidence_tier as MemoryProjectionCurrentState[\"confidenceTier\"],\n memoryKind:\n typeof row.memory_kind === \"string\"\n ? (row.memory_kind as MemoryProjectionCurrentState[\"memoryKind\"])\n : undefined,\n accessCount: typeof row.access_count === \"number\" ? row.access_count : undefined,\n lastAccessed: typeof row.last_accessed === \"string\" ? row.last_accessed : undefined,\n tags: parseStringArray(row.tags_json),\n preview: typeof row.preview_text === \"string\" ? row.preview_text : \"\",\n };\n}\n\nexport function parseTimelineRows(rows: Array<Record<string, unknown>>): MemoryLifecycleEvent[] {\n const out: MemoryLifecycleEvent[] = [];\n for (const row of rows) {\n if (\n typeof row.event_id !== \"string\" ||\n typeof row.memory_id !== \"string\" ||\n typeof row.event_type !== \"string\" ||\n typeof row.timestamp !== \"string\" ||\n typeof row.actor !== \"string\" ||\n typeof row.rule_version !== \"string\"\n ) {\n continue;\n }\n\n out.push({\n eventId: row.event_id,\n memoryId: row.memory_id,\n eventType: row.event_type as MemoryLifecycleEvent[\"eventType\"],\n timestamp: row.timestamp,\n actor: row.actor,\n reasonCode: typeof row.reason_code === \"string\" ? row.reason_code : undefined,\n ruleVersion: row.rule_version,\n relatedMemoryIds: parseStringArray(row.related_memory_ids_json),\n before: parseJsonObject<MemoryLifecycleEvent[\"before\"]>(row.before_json),\n after: parseJsonObject<MemoryLifecycleEvent[\"after\"]>(row.after_json),\n correlationId: typeof row.correlation_id === \"string\" ? row.correlation_id : undefined,\n });\n }\n\n return out;\n}\n\nexport function readProjectedMemoryState(\n memoryDir: string,\n memoryId: string,\n): MemoryProjectionCurrentState | null {\n return withProjectionReadonly(memoryDir, (db) => {\n const currentSelect = memoryCurrentSelectExpressions(db);\n const row = db\n .prepare(\n `\n SELECT\n memory_id,\n category,\n status,\n lifecycle_state,\n path_rel,\n created_at,\n updated_at,\n archived_at,\n superseded_at,\n entity_ref,\n source,\n confidence,\n confidence_tier,\n memory_kind,\n access_count,\n last_accessed,\n ${currentSelect.tagsJson},\n ${currentSelect.previewText}\n FROM memory_current\n WHERE memory_id = ?\n `,\n )\n .get(memoryId) as Record<string, unknown> | undefined;\n return parseCurrentRow(memoryDir, row);\n });\n}\n\nexport function readProjectedMemoryTimeline(\n memoryDir: string,\n memoryId: string,\n limit: number,\n): MemoryLifecycleEvent[] | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const rows = db\n .prepare(\n `\n SELECT * FROM (\n SELECT\n event_id,\n memory_id,\n event_type,\n timestamp,\n event_order,\n actor,\n reason_code,\n rule_version,\n related_memory_ids_json,\n before_json,\n after_json,\n correlation_id\n FROM memory_timeline\n WHERE memory_id = ?\n ORDER BY timestamp DESC, event_order DESC\n LIMIT ?\n )\n ORDER BY timestamp ASC, event_order ASC\n `,\n )\n .all(memoryId, limit) as Array<Record<string, unknown>>;\n if (rows.length === 0) return null;\n return parseTimelineRows(rows);\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedMemoryBrowse(\n memoryDir: string,\n options: ProjectedMemoryBrowseOptions,\n): ProjectedMemoryBrowsePage | null {\n return withProjectionReadonly(memoryDir, (db) => {\n const normalizedQuery = options.query?.trim().toLowerCase() ?? \"\";\n\n const currentSelect = memoryCurrentSelectExpressions(db);\n const whereClauses: string[] = [];\n const params: unknown[] = [];\n\n if (options.status) {\n whereClauses.push(\"status = ?\");\n params.push(options.status);\n }\n if (options.category) {\n whereClauses.push(\"category = ?\");\n params.push(options.category);\n }\n const sort = options.sort ?? \"updated_desc\";\n const orderBySql = (() => {\n switch (sort) {\n case \"updated_asc\":\n return \"updated_at ASC, created_at ASC, memory_id ASC\";\n case \"created_desc\":\n return \"created_at DESC, updated_at DESC, memory_id ASC\";\n case \"created_asc\":\n return \"created_at ASC, updated_at ASC, memory_id ASC\";\n case \"updated_desc\":\n default:\n return \"updated_at DESC, created_at DESC, memory_id ASC\";\n }\n })();\n const whereSql = whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\";\n\n if (normalizedQuery) {\n // Query-based browse: fetch all matching rows, filter by full file content, then paginate in JS\n const allRows = db\n .prepare(`\n SELECT\n memory_id,\n path_rel,\n category,\n status,\n created_at,\n updated_at,\n entity_ref,\n ${currentSelect.tagsJson},\n ${currentSelect.previewText}\n FROM memory_current\n ${whereSql}\n ORDER BY ${orderBySql}\n `)\n .all(...params) as Array<Record<string, unknown>>;\n\n const filtered = allRows.filter((row) => {\n if (typeof row.memory_id !== \"string\" || typeof row.path_rel !== \"string\") return false;\n // Check preview, category, entity_ref, tags first (fast)\n const preview = typeof row.preview_text === \"string\" ? row.preview_text.toLowerCase() : \"\";\n const category = typeof row.category === \"string\" ? row.category.toLowerCase() : \"\";\n const entityRef = typeof row.entity_ref === \"string\" ? row.entity_ref.toLowerCase() : \"\";\n const tags = typeof row.tags_json === \"string\" ? row.tags_json.toLowerCase() : \"\";\n if (preview.includes(normalizedQuery) || category.includes(normalizedQuery) ||\n entityRef.includes(normalizedQuery) || tags.includes(normalizedQuery)) {\n return true;\n }\n // Fall back to reading full file content from disk\n try {\n const filePath = path.join(memoryDir, row.path_rel as string);\n const content = readFileSync(filePath, \"utf-8\").toLowerCase();\n return content.includes(normalizedQuery);\n } catch {\n return false;\n }\n });\n\n const pageRows = filtered.slice(options.offset, options.offset + options.limit);\n return {\n total: filtered.length,\n memories: pageRows\n .filter(\n (row) =>\n typeof row.memory_id === \"string\" &&\n typeof row.path_rel === \"string\" &&\n typeof row.category === \"string\" &&\n typeof row.status === \"string\",\n )\n .map((row) => ({\n id: row.memory_id as string,\n path: path.join(memoryDir, row.path_rel as string),\n category: row.category as MemoryCategory,\n status: row.status as MemoryStatus,\n created: typeof row.created_at === \"string\" ? row.created_at : undefined,\n updated: typeof row.updated_at === \"string\" ? row.updated_at : undefined,\n tags: parseStringArray(row.tags_json),\n entityRef: typeof row.entity_ref === \"string\" ? row.entity_ref : undefined,\n preview: typeof row.preview_text === \"string\" ? row.preview_text : \"\",\n })),\n };\n }\n\n // No query: use SQL pagination directly\n const totalRow = db\n .prepare(`SELECT COUNT(*) AS total FROM memory_current ${whereSql}`)\n .get(...params) as { total?: number } | undefined;\n const rows = db\n .prepare(`\n SELECT\n memory_id,\n path_rel,\n category,\n status,\n created_at,\n updated_at,\n entity_ref,\n ${currentSelect.tagsJson},\n ${currentSelect.previewText}\n FROM memory_current\n ${whereSql}\n ORDER BY ${orderBySql}\n LIMIT ? OFFSET ?\n `)\n .all(...params, options.limit, options.offset) as Array<Record<string, unknown>>;\n\n return {\n total: typeof totalRow?.total === \"number\" ? totalRow.total : 0,\n memories: rows\n .filter(\n (row) =>\n typeof row.memory_id === \"string\" &&\n typeof row.path_rel === \"string\" &&\n typeof row.category === \"string\" &&\n typeof row.status === \"string\",\n )\n .map((row) => ({\n id: row.memory_id as string,\n path: path.join(memoryDir, row.path_rel as string),\n category: row.category as MemoryCategory,\n status: row.status as MemoryStatus,\n created: typeof row.created_at === \"string\" ? row.created_at : undefined,\n updated: typeof row.updated_at === \"string\" ? row.updated_at : undefined,\n tags: parseStringArray(row.tags_json),\n entityRef: typeof row.entity_ref === \"string\" ? row.entity_ref : undefined,\n preview: typeof row.preview_text === \"string\" ? row.preview_text : \"\",\n })),\n };\n });\n}\n\nexport function readProjectedEntityMentions(\n memoryDir: string,\n memoryIds?: Set<string>,\n): ProjectedEntityMentionRow[] | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const rows = db\n .prepare(`\n SELECT\n memory_id,\n entity_ref,\n mention_source,\n created_at,\n updated_at\n FROM memory_entity_mentions\n ORDER BY entity_ref ASC, updated_at DESC, memory_id ASC\n `)\n .all() as Array<Record<string, unknown>>;\n\n return rows\n .filter(\n (row) =>\n typeof row.memory_id === \"string\" &&\n typeof row.entity_ref === \"string\" &&\n typeof row.mention_source === \"string\" &&\n typeof row.created_at === \"string\" &&\n typeof row.updated_at === \"string\" &&\n (!memoryIds || memoryIds.has(row.memory_id)),\n )\n .map((row) => ({\n memoryId: row.memory_id as string,\n entityRef: row.entity_ref as string,\n mentionSource: row.mention_source as string,\n created: row.created_at as string,\n updated: row.updated_at as string,\n }));\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedNativeKnowledgeChunks(\n memoryDir: string,\n): ProjectedNativeKnowledgeChunkRow[] | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const rows = db\n .prepare(`\n SELECT\n chunk_id,\n source_path,\n title,\n source_kind,\n start_line,\n end_line,\n derived_date,\n session_key,\n workflow_key,\n author,\n agent,\n namespace,\n privacy_class,\n source_hash,\n preview_text\n FROM native_knowledge_chunks\n ORDER BY source_kind ASC, source_path ASC, start_line ASC\n `)\n .all() as Array<Record<string, unknown>>;\n\n return rows\n .filter(\n (row) =>\n typeof row.chunk_id === \"string\" &&\n typeof row.source_path === \"string\" &&\n typeof row.title === \"string\" &&\n typeof row.source_kind === \"string\" &&\n typeof row.start_line === \"number\" &&\n typeof row.end_line === \"number\" &&\n typeof row.preview_text === \"string\",\n )\n .map((row) => ({\n chunkId: row.chunk_id as string,\n sourcePath: row.source_path as string,\n title: row.title as string,\n sourceKind: row.source_kind as string,\n startLine: row.start_line as number,\n endLine: row.end_line as number,\n derivedDate: typeof row.derived_date === \"string\" ? row.derived_date : undefined,\n sessionKey: typeof row.session_key === \"string\" ? row.session_key : undefined,\n workflowKey: typeof row.workflow_key === \"string\" ? row.workflow_key : undefined,\n author: typeof row.author === \"string\" ? row.author : undefined,\n agent: typeof row.agent === \"string\" ? row.agent : undefined,\n namespace: typeof row.namespace === \"string\" ? row.namespace : undefined,\n privacyClass: typeof row.privacy_class === \"string\" ? row.privacy_class : undefined,\n sourceHash: typeof row.source_hash === \"string\" ? row.source_hash : undefined,\n preview: row.preview_text as string,\n }));\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedLatestReviewQueue(\n memoryDir: string,\n): ProjectedReviewQueueSnapshot | null {\n const db = openProjectionReadonly(memoryDir);\n if (!db) return null;\n\n try {\n const latestRunId =\n (db.prepare(`SELECT value FROM meta WHERE key = 'latestGovernanceRunId'`).get() as { value?: string } | undefined)\n ?.value\n ?? (db.prepare(`SELECT run_id AS value FROM memory_review_runs ORDER BY created_at DESC LIMIT 1`).get() as {\n value?: string;\n } | undefined)?.value;\n if (!latestRunId) {\n return { found: false };\n }\n\n const runRow = db\n .prepare(`\n SELECT\n run_id,\n summary_json,\n metrics_json,\n applied_actions_json,\n report_markdown\n FROM memory_review_runs\n WHERE run_id = ?\n `)\n .get(latestRunId) as Record<string, unknown> | undefined;\n if (!runRow || typeof runRow.run_id !== \"string\") {\n return { found: false };\n }\n\n const queueRows = db\n .prepare(`\n SELECT\n entry_id,\n memory_id,\n path,\n reason_code,\n severity,\n suggested_action,\n suggested_status,\n related_memory_ids_json\n FROM memory_review_queue\n WHERE run_id = ?\n ORDER BY reason_code ASC, memory_id ASC\n `)\n .all(latestRunId) as Array<Record<string, unknown>>;\n\n const actionRows = db\n .prepare(`\n SELECT\n row_key,\n action,\n memory_id,\n reason_code,\n before_status,\n after_status,\n original_path,\n current_path\n FROM memory_review_actions\n WHERE run_id = ?\n ORDER BY memory_id ASC, action ASC\n `)\n .all(latestRunId) as Array<Record<string, unknown>>;\n\n const reviewQueue: MemoryGovernanceReviewQueueEntry[] = queueRows\n .filter(\n (row) =>\n typeof row.entry_id === \"string\" &&\n typeof row.memory_id === \"string\" &&\n typeof row.path === \"string\" &&\n typeof row.reason_code === \"string\" &&\n typeof row.severity === \"string\" &&\n typeof row.suggested_action === \"string\",\n )\n .map((row) => ({\n entryId: row.entry_id as string,\n memoryId: row.memory_id as string,\n path: row.path as string,\n reasonCode: row.reason_code as MemoryGovernanceReviewQueueEntry[\"reasonCode\"],\n severity: row.severity as MemoryGovernanceReviewQueueEntry[\"severity\"],\n suggestedAction: row.suggested_action as MemoryGovernanceReviewQueueEntry[\"suggestedAction\"],\n suggestedStatus:\n typeof row.suggested_status === \"string\"\n ? (row.suggested_status as MemoryGovernanceReviewQueueEntry[\"suggestedStatus\"])\n : undefined,\n relatedMemoryIds: parseStringArray(row.related_memory_ids_json),\n }));\n\n return {\n found: true,\n runId: latestRunId,\n summary: parseJsonObject<MemoryGovernanceSummary>(runRow.summary_json),\n metrics: parseJsonObject<MemoryGovernanceMetrics>(runRow.metrics_json),\n reviewQueue,\n appliedActions:\n actionRows.length > 0\n ? actionRows\n .filter(\n (row) =>\n typeof row.action === \"string\" &&\n typeof row.memory_id === \"string\" &&\n typeof row.reason_code === \"string\" &&\n typeof row.before_status === \"string\" &&\n typeof row.original_path === \"string\" &&\n typeof row.current_path === \"string\",\n )\n .map((row) => ({\n action: row.action as MemoryGovernanceAppliedAction[\"action\"],\n memoryId: row.memory_id as string,\n reasonCode: row.reason_code as MemoryGovernanceAppliedAction[\"reasonCode\"],\n beforeStatus: row.before_status as MemoryGovernanceAppliedAction[\"beforeStatus\"],\n afterStatus:\n typeof row.after_status === \"string\"\n ? (row.after_status as MemoryGovernanceAppliedAction[\"afterStatus\"])\n : undefined,\n originalPath: row.original_path as string,\n currentPath: row.current_path as string,\n }))\n : (parseJsonObject<MemoryGovernanceAppliedAction[]>(runRow.applied_actions_json) ?? []),\n report: typeof runRow.report_markdown === \"string\" ? runRow.report_markdown : undefined,\n };\n } catch {\n return null;\n } finally {\n db.close();\n }\n}\n\nexport function readProjectedGovernanceRecord(\n memoryDir: string,\n): {\n runId: string;\n summary: unknown;\n metrics: unknown;\n reviewQueueRows: MemoryProjectionGovernanceReviewQueueRow[];\n appliedActionRows: MemoryProjectionGovernanceAppliedActionRow[];\n report: string;\n} | null {\n const snapshot = readProjectedLatestReviewQueue(memoryDir);\n if (!snapshot?.found || !snapshot.runId) return null;\n\n return {\n runId: snapshot.runId,\n summary: snapshot.summary ?? {},\n metrics: snapshot.metrics ?? {},\n reviewQueueRows: (snapshot.reviewQueue ?? []).map((entry) => ({\n runId: snapshot.runId as string,\n entryId: entry.entryId,\n memoryId: entry.memoryId,\n path: entry.path,\n reasonCode: entry.reasonCode,\n severity: entry.severity,\n suggestedAction: entry.suggestedAction,\n suggestedStatus: entry.suggestedStatus,\n relatedMemoryIds: [...entry.relatedMemoryIds],\n })),\n appliedActionRows: (snapshot.appliedActions ?? []).map((action) => ({\n runId: snapshot.runId as string,\n rowKey: [\n action.action,\n action.memoryId,\n action.reasonCode,\n action.originalPath,\n action.currentPath,\n ].join(\"::\"),\n action: action.action,\n memoryId: action.memoryId,\n reasonCode: action.reasonCode,\n beforeStatus: action.beforeStatus,\n afterStatus: action.afterStatus,\n originalPath: action.originalPath,\n currentPath: action.currentPath,\n })),\n report: snapshot.report ?? \"\",\n };\n}\n","import path from \"node:path\";\nimport type {\n MemoryFile,\n MemoryLifecycleEvent,\n MemoryLifecycleEventType,\n MemoryLifecycleStateSummary,\n MemoryFrontmatter,\n MemoryStatus,\n} from \"./types.js\";\n\nexport const MEMORY_LIFECYCLE_RULE_VERSION = \"memory-lifecycle-ledger.v1\";\n\nexport const MEMORY_LIFECYCLE_EVENT_SORT_ORDER: Record<MemoryLifecycleEventType, number> = {\n created: 0,\n updated: 1,\n promoted: 2,\n explicit_capture_accepted: 3,\n explicit_capture_queued: 4,\n imported: 5,\n merged: 6,\n restored: 7,\n superseded: 8,\n rejected: 9,\n archived: 10,\n};\n\nexport function toMemoryPathRel(baseDir: string, filePath: string): string {\n if (!baseDir) return filePath.split(path.sep).join(\"/\");\n return path.relative(baseDir, filePath).split(path.sep).join(\"/\");\n}\n\nexport function isArchivedMemoryPath(pathRel: string): boolean {\n return pathRel === \"archive\" || pathRel.startsWith(\"archive/\");\n}\n\nexport function inferMemoryStatus(\n frontmatter: MemoryFrontmatter,\n pathRel: string,\n fallbackStatus: MemoryStatus = \"active\",\n): MemoryStatus {\n if (frontmatter.status && frontmatter.status !== \"active\") return frontmatter.status;\n if (frontmatter.archivedAt) return \"archived\";\n if (isArchivedMemoryPath(pathRel)) return \"archived\";\n if (frontmatter.status) return frontmatter.status;\n return fallbackStatus;\n}\n\nexport function summarizeMemoryLifecycleState(memory: MemoryFile): MemoryLifecycleStateSummary {\n return {\n category: memory.frontmatter.category,\n path: memory.path,\n status: memory.frontmatter.status ?? \"active\",\n lifecycleState: memory.frontmatter.lifecycleState,\n };\n}\n\nexport function makeRebuiltMemoryLifecycleEvent(\n memory: MemoryFile,\n eventType: MemoryLifecycleEventType,\n timestamp: string,\n): MemoryLifecycleEvent {\n return {\n eventId: `rebuild-${memory.frontmatter.id}-${eventType}-${timestamp}`,\n memoryId: memory.frontmatter.id,\n eventType,\n timestamp,\n actor: \"maintenance.rebuildMemoryLifecycleLedger\",\n ruleVersion: MEMORY_LIFECYCLE_RULE_VERSION,\n after: summarizeMemoryLifecycleState(memory),\n relatedMemoryIds: [\n ...(memory.frontmatter.supersededBy ? [memory.frontmatter.supersededBy] : []),\n ...(memory.frontmatter.supersedes ? [memory.frontmatter.supersedes] : []),\n ...((memory.frontmatter.lineage ?? []).filter(Boolean)),\n ],\n };\n}\n\nexport function buildLifecycleEventsForMemory(memory: MemoryFile): MemoryLifecycleEvent[] {\n const events: MemoryLifecycleEvent[] = [];\n const created = memory.frontmatter.created;\n const updated = memory.frontmatter.updated;\n const archivedAt = memory.frontmatter.archivedAt;\n const supersededAt = memory.frontmatter.supersededAt;\n const effectiveArchivedAt =\n archivedAt ?? (memory.frontmatter.status === \"archived\" && updated ? updated : undefined);\n\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"created\", created));\n if (\n updated &&\n updated !== created &&\n updated !== effectiveArchivedAt &&\n updated !== supersededAt\n ) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"updated\", updated));\n }\n if (supersededAt) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"superseded\", supersededAt));\n }\n if (effectiveArchivedAt) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"archived\", effectiveArchivedAt));\n }\n\n return events;\n}\n\nexport function sortMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): MemoryLifecycleEvent[] {\n return [...events].sort((a, b) => {\n if (a.memoryId !== b.memoryId) return a.memoryId.localeCompare(b.memoryId);\n if (a.timestamp !== b.timestamp) return a.timestamp.localeCompare(b.timestamp);\n return MEMORY_LIFECYCLE_EVENT_SORT_ORDER[a.eventType] - MEMORY_LIFECYCLE_EVENT_SORT_ORDER[b.eventType];\n });\n}\n","export function normalizeProjectionPreview(content: string, maxChars = 180): string {\n return content.replace(/\\s+/g, \" \").trim().slice(0, maxChars);\n}\n\nexport function normalizeProjectionTags(tags: string[] | undefined): string[] {\n return [...new Set(\n (tags ?? [])\n .map((value) => value.trim())\n .filter((value) => value.length > 0),\n )].sort();\n}\n","import type {\n ContinuityIncidentCloseInput,\n ContinuityIncidentOpenInput,\n ContinuityImprovementLoop,\n ContinuityLoopCadence,\n ContinuityLoopReviewInput,\n ContinuityLoopStatus,\n ContinuityLoopUpsertInput,\n ContinuityIncidentRecord,\n ContinuityIncidentState,\n} from \"./types.js\";\n\nfunction parseFrontmatterValue(raw: string): unknown {\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n}\n\nfunction parseFrontmatter(raw: string): Record<string, unknown> {\n const parsed: Record<string, unknown> = {};\n for (const line of raw.split(\"\\n\")) {\n const idx = line.indexOf(\":\");\n if (idx <= 0) continue;\n const key = line.slice(0, idx).trim();\n const value = line.slice(idx + 1).trim();\n parsed[key] = parseFrontmatterValue(value);\n }\n return parsed;\n}\n\nfunction emitSection(lines: string[], title: string, value?: string): void {\n if (!value || value.trim().length === 0) return;\n lines.push(`## ${title}`, \"\", value.trim(), \"\");\n}\n\nfunction parseSection(body: string, title: string): string | undefined {\n const escaped = title.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const re = new RegExp(`## ${escaped}\\\\n\\\\n([\\\\s\\\\S]*?)(?=\\\\n## |$)`);\n const match = body.match(re);\n if (!match) return undefined;\n const value = match[1].trim();\n return value.length > 0 ? value : undefined;\n}\n\nexport function serializeContinuityIncident(incident: ContinuityIncidentRecord): string {\n const lines = [\n \"---\",\n `id: ${JSON.stringify(incident.id)}`,\n `state: ${JSON.stringify(incident.state)}`,\n `openedAt: ${JSON.stringify(incident.openedAt)}`,\n `updatedAt: ${JSON.stringify(incident.updatedAt)}`,\n ];\n if (incident.closedAt) lines.push(`closedAt: ${JSON.stringify(incident.closedAt)}`);\n if (incident.triggerWindow) lines.push(`triggerWindow: ${JSON.stringify(incident.triggerWindow)}`);\n lines.push(\"---\", \"\");\n\n emitSection(lines, \"Symptom\", incident.symptom);\n emitSection(lines, \"Suspected Cause\", incident.suspectedCause);\n emitSection(lines, \"Fix Applied\", incident.fixApplied);\n emitSection(lines, \"Verification Result\", incident.verificationResult);\n emitSection(lines, \"Preventive Rule\", incident.preventiveRule);\n\n return lines.join(\"\\n\").trimEnd() + \"\\n\";\n}\n\nexport function parseContinuityIncident(raw: string): ContinuityIncidentRecord | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (!match) return null;\n const frontmatter = parseFrontmatter(match[1]);\n const body = match[2] ?? \"\";\n\n const id = typeof frontmatter.id === \"string\" ? frontmatter.id : \"\";\n const stateRaw = frontmatter.state;\n const state: ContinuityIncidentState = stateRaw === \"closed\" ? \"closed\" : \"open\";\n const openedAt = typeof frontmatter.openedAt === \"string\" ? frontmatter.openedAt : \"\";\n const updatedAt = typeof frontmatter.updatedAt === \"string\" ? frontmatter.updatedAt : openedAt;\n const symptom = parseSection(body, \"Symptom\");\n\n if (!id || !openedAt || !updatedAt || !symptom) return null;\n\n return {\n id,\n state,\n openedAt,\n updatedAt,\n triggerWindow: typeof frontmatter.triggerWindow === \"string\" ? frontmatter.triggerWindow : undefined,\n symptom,\n suspectedCause: parseSection(body, \"Suspected Cause\"),\n fixApplied: parseSection(body, \"Fix Applied\"),\n verificationResult: parseSection(body, \"Verification Result\"),\n preventiveRule: parseSection(body, \"Preventive Rule\"),\n closedAt: typeof frontmatter.closedAt === \"string\" ? frontmatter.closedAt : undefined,\n };\n}\n\nexport function createContinuityIncidentRecord(\n id: string,\n input: ContinuityIncidentOpenInput,\n nowIso: string,\n): ContinuityIncidentRecord {\n return {\n id,\n state: \"open\",\n openedAt: nowIso,\n updatedAt: nowIso,\n triggerWindow: input.triggerWindow?.trim() || undefined,\n symptom: input.symptom.trim(),\n suspectedCause: input.suspectedCause?.trim() || undefined,\n };\n}\n\nexport function closeContinuityIncidentRecord(\n incident: ContinuityIncidentRecord,\n closure: ContinuityIncidentCloseInput,\n nowIso: string,\n): ContinuityIncidentRecord {\n return {\n ...incident,\n state: \"closed\",\n updatedAt: nowIso,\n closedAt: nowIso,\n fixApplied: closure.fixApplied.trim(),\n verificationResult: closure.verificationResult.trim(),\n preventiveRule: closure.preventiveRule?.trim() || incident.preventiveRule,\n };\n}\n\nconst LOOP_HEADER = \"# Continuity Improvement Loops\";\nconst LOOP_CADENCES = new Set<ContinuityLoopCadence>([\"daily\", \"weekly\", \"monthly\", \"quarterly\"]);\nconst LOOP_STATUSES = new Set<ContinuityLoopStatus>([\"active\", \"paused\", \"retired\"]);\nconst STALE_LAST_REVIEWED_FALLBACK = \"1970-01-01T00:00:00.000Z\";\n\nfunction normalizeLoopField(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n return trimmed.replace(/\\s+/g, \" \");\n}\n\nfunction isValidIso(value: string): boolean {\n const ts = Date.parse(value);\n return Number.isFinite(ts);\n}\n\nfunction normalizeContinuityLoop(\n input: ContinuityLoopUpsertInput | ContinuityImprovementLoop,\n nowIso: string,\n): ContinuityImprovementLoop | null {\n const id = normalizeLoopField(input.id);\n const cadence = normalizeLoopField(input.cadence) as ContinuityLoopCadence | undefined;\n const status = normalizeLoopField(input.status) as ContinuityLoopStatus | undefined;\n const purpose = normalizeLoopField(input.purpose);\n const killCondition = normalizeLoopField(input.killCondition);\n const notes = normalizeLoopField(input.notes);\n const lastReviewedRaw =\n \"lastReviewed\" in input && typeof input.lastReviewed === \"string\" ? input.lastReviewed : undefined;\n const lastReviewed = normalizeLoopField(lastReviewedRaw) ?? nowIso;\n\n if (!id || !cadence || !status || !purpose || !killCondition) return null;\n if (!LOOP_CADENCES.has(cadence)) return null;\n if (!LOOP_STATUSES.has(status)) return null;\n if (!isValidIso(lastReviewed)) return null;\n\n return {\n id,\n cadence,\n purpose,\n status,\n killCondition,\n lastReviewed,\n notes,\n };\n}\n\nfunction serializeContinuityLoopSection(loop: ContinuityImprovementLoop): string {\n const lines = [\n `## ${loop.id}`,\n `cadence: ${loop.cadence}`,\n `purpose: ${loop.purpose}`,\n `status: ${loop.status}`,\n `killCondition: ${loop.killCondition}`,\n `lastReviewed: ${loop.lastReviewed}`,\n ];\n if (loop.notes) lines.push(`notes: ${loop.notes}`);\n return lines.join(\"\\n\");\n}\n\ntype MarkdownSection = {\n title: string;\n body: string;\n};\n\nfunction splitLoopMarkdown(raw: string | null): { header: string; sections: MarkdownSection[] } {\n const text = (raw ?? \"\").replace(/\\r/g, \"\");\n const lines = text.split(\"\\n\");\n const headerLines: string[] = [];\n const sections: MarkdownSection[] = [];\n let current: MarkdownSection | null = null;\n\n for (const line of lines) {\n const sectionMatch = line.match(/^##\\s+(.+?)\\s*$/);\n if (sectionMatch) {\n if (current) sections.push({ title: current.title, body: current.body.trimEnd() });\n current = { title: sectionMatch[1].trim(), body: \"\" };\n continue;\n }\n if (!current) {\n headerLines.push(line);\n continue;\n }\n current.body += current.body.length > 0 ? `\\n${line}` : line;\n }\n if (current) sections.push({ title: current.title, body: current.body.trimEnd() });\n\n const headerRaw = headerLines.join(\"\\n\").trim();\n const header = headerRaw.length > 0 ? headerRaw : LOOP_HEADER;\n return { header, sections };\n}\n\nfunction parseLoopFromSection(section: MarkdownSection, nowIso: string): ContinuityImprovementLoop | null {\n const fields: Record<string, string> = {};\n for (const line of section.body.split(\"\\n\")) {\n const kv = line.match(/^([A-Za-z][A-Za-z0-9_]*):\\s*(.+?)\\s*$/);\n if (!kv) continue;\n fields[kv[1]] = kv[2];\n }\n const parsedLastReviewed = normalizeLoopField(fields.lastReviewed);\n const safeLastReviewed =\n parsedLastReviewed && isValidIso(parsedLastReviewed) ? parsedLastReviewed : STALE_LAST_REVIEWED_FALLBACK;\n return normalizeContinuityLoop(\n {\n id: section.title,\n cadence: (fields.cadence ?? \"\") as ContinuityLoopCadence,\n purpose: fields.purpose ?? \"\",\n status: (fields.status ?? \"\") as ContinuityLoopStatus,\n killCondition: fields.killCondition ?? \"\",\n lastReviewed: safeLastReviewed,\n notes: fields.notes,\n },\n nowIso,\n );\n}\n\nfunction joinLoopMarkdown(header: string, sections: MarkdownSection[]): string {\n const lines: string[] = [header.trim(), \"\"];\n for (const section of sections) {\n lines.push(`## ${section.title}`);\n if (section.body.trim().length > 0) {\n lines.push(section.body.trimEnd());\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trimEnd() + \"\\n\";\n}\n\nexport function parseContinuityImprovementLoops(raw: string): ContinuityImprovementLoop[] {\n const parsed = splitLoopMarkdown(raw);\n const nowIso = new Date().toISOString();\n return parsed.sections\n .map((section) => parseLoopFromSection(section, nowIso))\n .filter((loop): loop is ContinuityImprovementLoop => loop !== null);\n}\n\nexport function upsertContinuityLoopInMarkdown(\n raw: string | null,\n input: ContinuityLoopUpsertInput,\n nowIso: string,\n): { markdown: string; loop: ContinuityImprovementLoop } {\n const normalized = normalizeContinuityLoop(input, nowIso);\n if (!normalized) {\n throw new Error(\"Invalid continuity loop input\");\n }\n\n const parsed = splitLoopMarkdown(raw);\n let replaced = false;\n const nextSections = parsed.sections.map((section) => {\n if (normalizeLoopField(section.title) !== normalized.id) return section;\n replaced = true;\n return { title: normalized.id, body: serializeContinuityLoopSection(normalized).split(\"\\n\").slice(1).join(\"\\n\") };\n });\n\n if (!replaced) {\n nextSections.push({\n title: normalized.id,\n body: serializeContinuityLoopSection(normalized).split(\"\\n\").slice(1).join(\"\\n\"),\n });\n }\n\n return { markdown: joinLoopMarkdown(parsed.header, nextSections), loop: normalized };\n}\n\nexport function reviewContinuityLoopInMarkdown(\n raw: string | null,\n id: string,\n input: ContinuityLoopReviewInput,\n nowIso: string,\n): { markdown: string; loop: ContinuityImprovementLoop | null } {\n const parsed = splitLoopMarkdown(raw);\n const normalizedId = normalizeLoopField(id);\n if (!normalizedId) {\n return { markdown: joinLoopMarkdown(parsed.header, parsed.sections), loop: null };\n }\n let updatedLoop: ContinuityImprovementLoop | null = null;\n const nextSections = parsed.sections.map((section) => {\n if (normalizeLoopField(section.title) !== normalizedId) return section;\n const existing = parseLoopFromSection(section, nowIso);\n if (!existing) return section;\n const reviewed = applyContinuityLoopReview(existing, input, nowIso);\n updatedLoop = reviewed;\n return { title: reviewed.id, body: serializeContinuityLoopSection(reviewed).split(\"\\n\").slice(1).join(\"\\n\") };\n });\n\n return { markdown: joinLoopMarkdown(parsed.header, nextSections), loop: updatedLoop };\n}\n\nfunction applyContinuityLoopReview(\n existing: ContinuityImprovementLoop,\n input: ContinuityLoopReviewInput,\n nowIso: string,\n): ContinuityImprovementLoop {\n const nextStatus = normalizeLoopField(input.status) as ContinuityLoopStatus | undefined;\n const nextNotes = normalizeLoopField(input.notes);\n const reviewedAt = normalizeLoopField(input.reviewedAt) ?? nowIso;\n\n return {\n ...existing,\n status: nextStatus && LOOP_STATUSES.has(nextStatus) ? nextStatus : existing.status,\n notes: nextNotes ?? existing.notes,\n lastReviewed: isValidIso(reviewedAt) ? reviewedAt : nowIso,\n };\n}\n"],"mappings":";;;;;;AAAA,SAAS,QAAQ,SAAS,YAAAA,WAAU,QAAAC,OAAM,aAAAC,YAAW,SAAAC,QAAO,QAAQ,QAAQ,kBAAkB;AAC9F,SAAS,gBAAgB,WAAW,gBAAgB;AACpD,SAAS,kBAAkB;AAC3B,OAAOC,WAAU;;;ACiDjB,IAAM,mBAAmB,oBAAI,IAA2E;AAEjG,SAAS,kBAAkB,SAAiB,gBAA6C;AAC9F,MAAI,mBAAmB,EAAG,QAAO;AACjC,QAAM,QAAQ,iBAAiB,IAAI,OAAO;AAC1C,MAAI,CAAC,SAAS,MAAM,YAAY,eAAgB,QAAO;AACvD,SAAO,MAAM;AACf;AAEO,SAAS,kBAAkB,SAAiB,UAAwB,SAAuB;AAChG,mBAAiB,IAAI,SAAS,EAAE,UAAU,SAAS,UAAU,KAAK,IAAI,EAAE,CAAC;AAC3E;AASA,IAAM,kBAAkB,oBAAI,IAAwD;AACpF,IAAM,oBAAoB,oBAAI,IAAqF;AAG5G,SAAS,oBAAoB,SAAiB,gBAAwD;AAC3G,MAAI,mBAAmB,EAAG,QAAO;AACjC,QAAM,QAAQ,gBAAgB,IAAI,OAAO;AACzC,MAAI,CAAC,SAAS,MAAM,kBAAkB,eAAgB,QAAO;AAC7D,SAAO,MAAM;AACf;AAGO,SAAS,oBAAoB,SAAiB,UAAwB,SAA0C;AACrH,QAAM,MAAM,oBAAI,IAAwB;AACxC,aAAW,KAAK,UAAU;AACxB,QAAI,EAAE,YAAY,WAAW,WAAY;AACzC,QAAI,EAAE,YAAY,eAAe,UAAW;AAC5C,QAAI,IAAI,EAAE,YAAY,IAAI,CAAC;AAAA,EAC7B;AACA,kBAAgB,IAAI,SAAS,EAAE,MAAM,KAAK,eAAe,QAAQ,CAAC;AAClE,SAAO;AACT;AAGO,SAAS,sBAAsB,SAAiB,gBAAqF;AAC1I,MAAI,mBAAmB,EAAG,QAAO;AACjC,QAAM,QAAQ,kBAAkB,IAAI,OAAO;AAC3C,MAAI,CAAC,SAAS,MAAM,kBAAkB,eAAgB,QAAO;AAC7D,SAAO,MAAM;AACf;AAGO,SAAS,sBAAsB,SAAiB,UAAwB,SAAuE;AACpJ,QAAM,OAAO,oBAAI,IAAwB;AACzC,QAAM,MAAoB,CAAC;AAC3B,aAAW,KAAK,UAAU;AACxB,SAAK,IAAI,EAAE,YAAY,IAAI,CAAC;AAC5B,QAAI,EAAE,YAAY,aAAa,UAAU,EAAE,YAAY,WAAW,YAAY;AAC5E,UAAI,KAAK,CAAC;AAAA,IACZ;AAAA,EACF;AACA,QAAM,SAAS,EAAE,KAAK,KAAK;AAC3B,oBAAkB,IAAI,SAAS,EAAE,MAAM,QAAQ,eAAe,QAAQ,CAAC;AACvE,SAAO;AACT;AAQA,IAAM,mBAAmB;AACzB,IAAM,iBAAiB,oBAAI,IAA2B;AAE/C,SAAS,mBAAmB,UAAoC;AACrE,QAAM,QAAQ,eAAe,IAAI,QAAQ;AACzC,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,KAAK,IAAI,IAAI,MAAM,WAAW,kBAAkB;AAClD,mBAAe,OAAO,QAAQ;AAC9B,WAAO;AAAA,EACT;AACA,SAAO,MAAM;AACf;AAEO,SAAS,mBAAmB,UAAkB,SAA0B;AAC7E,iBAAe,IAAI,UAAU,EAAE,SAAS,UAAU,KAAK,IAAI,EAAE,CAAC;AAE9D,MAAI,eAAe,OAAO,KAAK;AAC7B,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB;AACzC,UAAI,MAAM,MAAM,WAAW,iBAAkB,gBAAe,OAAO,GAAG;AAAA,IACxE;AAAA,EACF;AACF;;;AClJA,SAAS,OAAO,UAAU,MAAM,iBAAiB;AACjD,OAAO,UAAU;AAUjB,SAAS,gBAAgB,IAAkB;AAEzC,SAAO,GAAG,YAAY,EAAE,QAAQ,SAAS,EAAE;AAC7C;AAEA,eAAsB,mBAAmB,MAKX;AAC5B,QAAM,WAA6B,CAAC;AACpC,QAAM,cAAc,KAAK,MAAM,KAAK,cAAc,KAAK,SAAS;AAEhE,aAAW,KAAK,KAAK,OAAO;AAC1B,UAAM,MAAM,KAAK,WAAW,CAAC,IAAI,IAAI,KAAK,KAAK,KAAK,cAAc,CAAC;AACnE,QAAI;AACF,YAAM,KAAK,MAAM,KAAK,GAAG;AACzB,UAAI,CAAC,GAAG,OAAO,EAAG;AAClB,YAAM,QAAQ,GAAG;AACjB,UAAI,SAAS,aAAa;AACxB,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN;AAAA,UACA,aAAa,KAAK;AAAA,UAClB;AAAA,UACA,SAAS,mBAAmB,CAAC,gCAAgC,KAAK,aAAa,WAAW;AAAA,QAC5F,CAAC;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,4BAA4B,MAKQ;AACxD,QAAM,WAAW,MAAM,SAAS,KAAK,UAAU,OAAO;AACtD,QAAM,KAAK,gBAAgB,oBAAI,KAAK,CAAC;AACrC,QAAM,cAAc,GAAG,KAAK,aAAa,IAAI,EAAE;AAC/C,QAAM,MAAM,KAAK,YAAY,EAAE,WAAW,KAAK,CAAC;AAChD,QAAM,eAAe,KAAK,KAAK,KAAK,YAAY,WAAW;AAC3D,QAAM,UAAU,cAAc,UAAU,OAAO;AAE/C,QAAM,OACJ,KAAK,gBAAgB,KAAK,SAAS,SAAS,KAAK,gBAC7C,SAAS,MAAM,CAAC,KAAK,aAAa,IAClC;AAEN,QAAM,UAAU,KAAK,SAAS,KAAK,QAAQ,KAAK,QAAQ,GAAG,YAAY;AAEvE,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,WAAW,KAAK,OAAO;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,KAAK;AAAA,IACV;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,SAAO,EAAE,cAAc,WAAW;AACpC;;;ACrFA,IAAM,qBAA+B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQA,IAAM,uBAAuB;AAEtB,SAAS,sBAAsB,MAA8B;AAClE,QAAM,SAAS,OAAO,SAAS,WAAW,OAAO;AACjD,QAAM,aAAuB,CAAC;AAE9B,aAAW,WAAW,oBAAoB;AACxC,QAAI,QAAQ,KAAK,MAAM,GAAG;AACxB,iBAAW,KAAK,QAAQ,MAAM;AAAA,IAChC;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,EAAE,OAAO,MAAM,MAAM,QAAQ,YAAY,CAAC,EAAE;AAAA,EACrD;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN;AAAA,EACF;AACF;;;AC+EO,SAAS,eAAe,OAA+B;AAC5D,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,SAAS,IAAM,QAAO;AAC1B,MAAI,SAAS,IAAM,QAAO;AAC1B,SAAO;AACT;AAGO,IAAM,uBAAuB;;;AChIpC,OAAOC,WAAU;AACjB,SAAS,oBAAoB;AAC7B,OAAO,cAAc;AAcd,IAAM,mCAAmC;AAwFzC,SAAS,wBAAwB,WAA2B;AACjE,SAAOA,MAAK,KAAK,WAAW,SAAS,0BAA0B;AACjE;AAEA,SAAS,iBAAiB,IAAuB,WAAgC;AAC/E,MAAI;AACF,UAAM,OAAO,GAAG,QAAQ,qBAAqB,SAAS,GAAG,EAAE,IAAI;AAC/D,WAAO,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ,CAAC;AAAA,EACvG,QAAQ;AACN,WAAO,oBAAI,IAAY;AAAA,EACzB;AACF;AAEA,SAAS,0BAA0B,IAA6B;AAC9D,QAAM,UAAU,iBAAiB,IAAI,gBAAgB;AACrD,MAAI,QAAQ,SAAS,EAAG;AAExB,MAAI,CAAC,QAAQ,IAAI,WAAW,GAAG;AAC7B,OAAG,KAAK,4EAA4E;AAAA,EACtF;AACA,MAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;AAChC,OAAG,KAAK,6EAA6E;AAAA,EACvF;AACF;AAEA,SAAS,+BAA+B,IAAgC;AACtE,QAAM,UAAU,iBAAiB,IAAI,gBAAgB;AACrD,SAAO,QAAQ,OAAO,MAAM,CAAC,QAAQ,IAAI,WAAW,KAAK,CAAC,QAAQ,IAAI,cAAc;AACtF;AAEA,SAAS,gCAAgC,WAAyB;AAChE,QAAM,SAAS,wBAAwB,SAAS;AAChD,MAAI;AACF,UAAM,KAAK,IAAI,SAAS,QAAQ,EAAE,eAAe,KAAK,CAAC;AACvD,QAAI;AACF,UAAI,CAAC,+BAA+B,EAAE,EAAG;AACzC,mCAA6B,EAAE;AAAA,IACjC,UAAE;AACA,SAAG,MAAM;AAAA,IACX;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,+BAA+B,IAG7C;AACA,QAAM,UAAU,iBAAiB,IAAI,gBAAgB;AACrD,SAAO;AAAA,IACL,UAAU,QAAQ,IAAI,WAAW,IAAI,cAAc;AAAA,IACnD,aAAa,QAAQ,IAAI,cAAc,IAAI,iBAAiB;AAAA,EAC9D;AACF;AAEO,SAAS,6BAA6B,IAA6B;AACxE,KAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAoIP;AAED,4BAA0B,EAAE;AAC5B,KAAG,QAAQ,uDAAuD,EAC/D,IAAI,iBAAiB,OAAO,gCAAgC,CAAC;AAClE;AAEA,SAAS,uBAAuB,WAA6C;AAC3E,QAAM,SAAS,wBAAwB,SAAS;AAChD,MAAI;AACF,WAAO,IAAI,SAAS,QAAQ,EAAE,UAAU,MAAM,eAAe,KAAK,CAAC;AAAA,EACrE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,uBACP,WACA,QACU;AACV,QAAM,KAAK,uBAAuB,SAAS;AAC3C,MAAI,CAAC,GAAI,QAAO;AAEhB,MAAI,iBAAiB;AACrB,MAAI;AACF,qBAAiB,+BAA+B,EAAE;AAClD,WAAO,OAAO,EAAE;AAAA,EAClB,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,OAAG,MAAM;AACT,QAAI,gBAAgB;AAClB,sCAAgC,SAAS;AAAA,IAC3C;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,OAA0B;AAClD,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAAG,QAAO,CAAC;AAC7D,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,WAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,IAAI,CAAC;AAAA,EACzG,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,gBAAmB,OAA+B;AACzD,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAAG,QAAO;AAC5D,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBACd,WACA,KACqC;AACrC,MAAI,CAAC,IAAK,QAAO;AACjB,MACE,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,WAAW,YACtB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,WAAW,YACtB,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,oBAAoB,UAC/B;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,UAAU,IAAI;AAAA,IACd,UAAU,IAAI;AAAA,IACd,QAAQ,IAAI;AAAA,IACZ,gBACE,OAAO,IAAI,oBAAoB,WAC1B,IAAI,kBACL;AAAA,IACN,MAAMA,MAAK,KAAK,WAAW,IAAI,QAAQ;AAAA,IACvC,SAAS,IAAI;AAAA,IACb,SAAS,IAAI;AAAA,IACb,SAAS,IAAI;AAAA,IACb,YAAY,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc;AAAA,IACpE,cAAc,OAAO,IAAI,kBAAkB,WAAW,IAAI,gBAAgB;AAAA,IAC1E,WAAW,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,IACjE,QAAQ,IAAI;AAAA,IACZ,YAAY,IAAI;AAAA,IAChB,gBAAgB,IAAI;AAAA,IACpB,YACE,OAAO,IAAI,gBAAgB,WACtB,IAAI,cACL;AAAA,IACN,aAAa,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe;AAAA,IACvE,cAAc,OAAO,IAAI,kBAAkB,WAAW,IAAI,gBAAgB;AAAA,IAC1E,MAAM,iBAAiB,IAAI,SAAS;AAAA,IACpC,SAAS,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe;AAAA,EACrE;AACF;AAEO,SAAS,kBAAkB,MAA8D;AAC9F,QAAM,MAA8B,CAAC;AACrC,aAAW,OAAO,MAAM;AACtB,QACE,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,UAAU,YACrB,OAAO,IAAI,iBAAiB,UAC5B;AACA;AAAA,IACF;AAEA,QAAI,KAAK;AAAA,MACP,SAAS,IAAI;AAAA,MACb,UAAU,IAAI;AAAA,MACd,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,MACf,OAAO,IAAI;AAAA,MACX,YAAY,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc;AAAA,MACpE,aAAa,IAAI;AAAA,MACjB,kBAAkB,iBAAiB,IAAI,uBAAuB;AAAA,MAC9D,QAAQ,gBAAgD,IAAI,WAAW;AAAA,MACvE,OAAO,gBAA+C,IAAI,UAAU;AAAA,MACpE,eAAe,OAAO,IAAI,mBAAmB,WAAW,IAAI,iBAAiB;AAAA,IAC/E,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,yBACd,WACA,UACqC;AACrC,SAAO,uBAAuB,WAAW,CAAC,OAAO;AAC/C,UAAM,gBAAgB,+BAA+B,EAAE;AACvD,UAAM,MAAM,GACT;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAkBM,cAAc,QAAQ;AAAA,cACtB,cAAc,WAAW;AAAA;AAAA;AAAA;AAAA,IAIjC,EACC,IAAI,QAAQ;AACf,WAAO,gBAAgB,WAAW,GAAG;AAAA,EACvC,CAAC;AACH;AAEO,SAAS,4BACd,WACA,UACA,OAC+B;AAC/B,QAAM,KAAK,uBAAuB,SAAS;AAC3C,MAAI,CAAC,GAAI,QAAO;AAEhB,MAAI;AACF,UAAM,OAAO,GACV;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAsBF,EACC,IAAI,UAAU,KAAK;AACtB,QAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,WAAO,kBAAkB,IAAI;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEO,SAAS,0BACd,WACA,SACkC;AAClC,SAAO,uBAAuB,WAAW,CAAC,OAAO;AAC/C,UAAM,kBAAkB,QAAQ,OAAO,KAAK,EAAE,YAAY,KAAK;AAE/D,UAAM,gBAAgB,+BAA+B,EAAE;AACvD,UAAM,eAAyB,CAAC;AAChC,UAAM,SAAoB,CAAC;AAE3B,QAAI,QAAQ,QAAQ;AAClB,mBAAa,KAAK,YAAY;AAC9B,aAAO,KAAK,QAAQ,MAAM;AAAA,IAC5B;AACA,QAAI,QAAQ,UAAU;AACpB,mBAAa,KAAK,cAAc;AAChC,aAAO,KAAK,QAAQ,QAAQ;AAAA,IAC9B;AACA,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,cAAc,MAAM;AACxB,cAAQ,MAAM;AAAA,QACZ,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AAAA,QACL;AACE,iBAAO;AAAA,MACX;AAAA,IACF,GAAG;AACH,UAAM,WAAW,aAAa,SAAS,IAAI,SAAS,aAAa,KAAK,OAAO,CAAC,KAAK;AAEnF,QAAI,iBAAiB;AAEnB,YAAM,UAAU,GACb,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cASH,cAAc,QAAQ;AAAA,cACtB,cAAc,WAAW;AAAA;AAAA,YAE3B,QAAQ;AAAA,qBACC,UAAU;AAAA,SACtB,EACA,IAAI,GAAG,MAAM;AAEhB,YAAM,WAAW,QAAQ,OAAO,CAAC,QAAQ;AACvC,YAAI,OAAO,IAAI,cAAc,YAAY,OAAO,IAAI,aAAa,SAAU,QAAO;AAElF,cAAM,UAAU,OAAO,IAAI,iBAAiB,WAAW,IAAI,aAAa,YAAY,IAAI;AACxF,cAAM,WAAW,OAAO,IAAI,aAAa,WAAW,IAAI,SAAS,YAAY,IAAI;AACjF,cAAM,YAAY,OAAO,IAAI,eAAe,WAAW,IAAI,WAAW,YAAY,IAAI;AACtF,cAAM,OAAO,OAAO,IAAI,cAAc,WAAW,IAAI,UAAU,YAAY,IAAI;AAC/E,YAAI,QAAQ,SAAS,eAAe,KAAK,SAAS,SAAS,eAAe,KACtE,UAAU,SAAS,eAAe,KAAK,KAAK,SAAS,eAAe,GAAG;AACzE,iBAAO;AAAA,QACT;AAEA,YAAI;AACF,gBAAM,WAAWA,MAAK,KAAK,WAAW,IAAI,QAAkB;AAC5D,gBAAM,UAAU,aAAa,UAAU,OAAO,EAAE,YAAY;AAC5D,iBAAO,QAAQ,SAAS,eAAe;AAAA,QACzC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAED,YAAM,WAAW,SAAS,MAAM,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,KAAK;AAC9E,aAAO;AAAA,QACL,OAAO,SAAS;AAAA,QAChB,UAAU,SACP;AAAA,UACC,CAAC,QACC,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,WAAW;AAAA,QAC1B,EACC,IAAI,CAAC,SAAS;AAAA,UACb,IAAI,IAAI;AAAA,UACR,MAAMA,MAAK,KAAK,WAAW,IAAI,QAAkB;AAAA,UACjD,UAAU,IAAI;AAAA,UACd,QAAQ,IAAI;AAAA,UACZ,SAAS,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,UAC/D,SAAS,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,UAC/D,MAAM,iBAAiB,IAAI,SAAS;AAAA,UACpC,WAAW,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,UACjE,SAAS,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe;AAAA,QACrE,EAAE;AAAA,MACN;AAAA,IACF;AAGA,UAAM,WAAW,GACd,QAAQ,gDAAgD,QAAQ,EAAE,EAClE,IAAI,GAAG,MAAM;AAChB,UAAM,OAAO,GACV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YASH,cAAc,QAAQ;AAAA,YACtB,cAAc,WAAW;AAAA;AAAA,UAE3B,QAAQ;AAAA,mBACC,UAAU;AAAA;AAAA,OAEtB,EACA,IAAI,GAAG,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AAE/C,WAAO;AAAA,MACL,OAAO,OAAO,UAAU,UAAU,WAAW,SAAS,QAAQ;AAAA,MAC9D,UAAU,KACP;AAAA,QACC,CAAC,QACC,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,WAAW;AAAA,MAC1B,EACC,IAAI,CAAC,SAAS;AAAA,QACb,IAAI,IAAI;AAAA,QACR,MAAMA,MAAK,KAAK,WAAW,IAAI,QAAkB;AAAA,QACjD,UAAU,IAAI;AAAA,QACd,QAAQ,IAAI;AAAA,QACZ,SAAS,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,QAC/D,SAAS,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,QAC/D,MAAM,iBAAiB,IAAI,SAAS;AAAA,QACpC,WAAW,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,QACjE,SAAS,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe;AAAA,MACrE,EAAE;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEO,SAAS,4BACd,WACA,WACoC;AACpC,QAAM,KAAK,uBAAuB,SAAS;AAC3C,MAAI,CAAC,GAAI,QAAO;AAEhB,MAAI;AACF,UAAM,OAAO,GACV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OASR,EACA,IAAI;AAEP,WAAO,KACJ;AAAA,MACC,CAAC,QACC,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,mBAAmB,YAC9B,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,eAAe,aACzB,CAAC,aAAa,UAAU,IAAI,IAAI,SAAS;AAAA,IAC9C,EACC,IAAI,CAAC,SAAS;AAAA,MACb,UAAU,IAAI;AAAA,MACd,WAAW,IAAI;AAAA,MACf,eAAe,IAAI;AAAA,MACnB,SAAS,IAAI;AAAA,MACb,SAAS,IAAI;AAAA,IACf,EAAE;AAAA,EACN,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEO,SAAS,mCACd,WAC2C;AAC3C,QAAM,KAAK,uBAAuB,SAAS;AAC3C,MAAI,CAAC,GAAI,QAAO;AAEhB,MAAI;AACF,UAAM,OAAO,GACV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAmBR,EACA,IAAI;AAEP,WAAO,KACJ;AAAA,MACC,CAAC,QACC,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,gBAAgB,YAC3B,OAAO,IAAI,UAAU,YACrB,OAAO,IAAI,gBAAgB,YAC3B,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,iBAAiB;AAAA,IAChC,EACC,IAAI,CAAC,SAAS;AAAA,MACb,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,MAChB,OAAO,IAAI;AAAA,MACX,YAAY,IAAI;AAAA,MAChB,WAAW,IAAI;AAAA,MACf,SAAS,IAAI;AAAA,MACb,aAAa,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe;AAAA,MACvE,YAAY,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc;AAAA,MACpE,aAAa,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe;AAAA,MACvE,QAAQ,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAAA,MACtD,OAAO,OAAO,IAAI,UAAU,WAAW,IAAI,QAAQ;AAAA,MACnD,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;AAAA,MAC/D,cAAc,OAAO,IAAI,kBAAkB,WAAW,IAAI,gBAAgB;AAAA,MAC1E,YAAY,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc;AAAA,MACpE,SAAS,IAAI;AAAA,IACf,EAAE;AAAA,EACN,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEO,SAAS,+BACd,WACqC;AACrC,QAAM,KAAK,uBAAuB,SAAS;AAC3C,MAAI,CAAC,GAAI,QAAO;AAEhB,MAAI;AACF,UAAM,cACH,GAAG,QAAQ,4DAA4D,EAAE,IAAI,GAC1E,SACA,GAAG,QAAQ,iFAAiF,EAAE,IAAI,GAEtF;AAClB,QAAI,CAAC,aAAa;AAChB,aAAO,EAAE,OAAO,MAAM;AAAA,IACxB;AAEA,UAAM,SAAS,GACZ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OASR,EACA,IAAI,WAAW;AAClB,QAAI,CAAC,UAAU,OAAO,OAAO,WAAW,UAAU;AAChD,aAAO,EAAE,OAAO,MAAM;AAAA,IACxB;AAEA,UAAM,YAAY,GACf,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAaR,EACA,IAAI,WAAW;AAElB,UAAM,aAAa,GAChB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAaR,EACA,IAAI,WAAW;AAElB,UAAM,cAAkD,UACrD;AAAA,MACC,CAAC,QACC,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,SAAS,YACpB,OAAO,IAAI,gBAAgB,YAC3B,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,qBAAqB;AAAA,IACpC,EACC,IAAI,CAAC,SAAS;AAAA,MACb,SAAS,IAAI;AAAA,MACb,UAAU,IAAI;AAAA,MACd,MAAM,IAAI;AAAA,MACV,YAAY,IAAI;AAAA,MAChB,UAAU,IAAI;AAAA,MACd,iBAAiB,IAAI;AAAA,MACrB,iBACE,OAAO,IAAI,qBAAqB,WAC3B,IAAI,mBACL;AAAA,MACN,kBAAkB,iBAAiB,IAAI,uBAAuB;AAAA,IAChE,EAAE;AAEJ,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS,gBAAyC,OAAO,YAAY;AAAA,MACrE,SAAS,gBAAyC,OAAO,YAAY;AAAA,MACrE;AAAA,MACA,gBACE,WAAW,SAAS,IAChB,WACC;AAAA,QACC,CAAC,QACC,OAAO,IAAI,WAAW,YACtB,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,gBAAgB,YAC3B,OAAO,IAAI,kBAAkB,YAC7B,OAAO,IAAI,kBAAkB,YAC7B,OAAO,IAAI,iBAAiB;AAAA,MAChC,EACC,IAAI,CAAC,SAAS;AAAA,QACb,QAAQ,IAAI;AAAA,QACZ,UAAU,IAAI;AAAA,QACd,YAAY,IAAI;AAAA,QAChB,cAAc,IAAI;AAAA,QAClB,aACE,OAAO,IAAI,iBAAiB,WACvB,IAAI,eACL;AAAA,QACN,cAAc,IAAI;AAAA,QAClB,aAAa,IAAI;AAAA,MACnB,EAAE,IACD,gBAAiD,OAAO,oBAAoB,KAAK,CAAC;AAAA,MACzF,QAAQ,OAAO,OAAO,oBAAoB,WAAW,OAAO,kBAAkB;AAAA,IAChF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEO,SAAS,8BACd,WAQO;AACP,QAAM,WAAW,+BAA+B,SAAS;AACzD,MAAI,CAAC,UAAU,SAAS,CAAC,SAAS,MAAO,QAAO;AAEhD,SAAO;AAAA,IACL,OAAO,SAAS;AAAA,IAChB,SAAS,SAAS,WAAW,CAAC;AAAA,IAC9B,SAAS,SAAS,WAAW,CAAC;AAAA,IAC9B,kBAAkB,SAAS,eAAe,CAAC,GAAG,IAAI,CAAC,WAAW;AAAA,MAC5D,OAAO,SAAS;AAAA,MAChB,SAAS,MAAM;AAAA,MACf,UAAU,MAAM;AAAA,MAChB,MAAM,MAAM;AAAA,MACZ,YAAY,MAAM;AAAA,MAClB,UAAU,MAAM;AAAA,MAChB,iBAAiB,MAAM;AAAA,MACvB,iBAAiB,MAAM;AAAA,MACvB,kBAAkB,CAAC,GAAG,MAAM,gBAAgB;AAAA,IAC9C,EAAE;AAAA,IACF,oBAAoB,SAAS,kBAAkB,CAAC,GAAG,IAAI,CAAC,YAAY;AAAA,MAClE,OAAO,SAAS;AAAA,MAChB,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT,EAAE,KAAK,IAAI;AAAA,MACX,QAAQ,OAAO;AAAA,MACf,UAAU,OAAO;AAAA,MACjB,YAAY,OAAO;AAAA,MACnB,cAAc,OAAO;AAAA,MACrB,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,aAAa,OAAO;AAAA,IACtB,EAAE;AAAA,IACF,QAAQ,SAAS,UAAU;AAAA,EAC7B;AACF;;;ACn7BA,OAAOC,WAAU;AAUV,IAAM,gCAAgC;AAEtC,IAAM,oCAA8E;AAAA,EACzF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AACZ;AAEO,SAAS,gBAAgB,SAAiB,UAA0B;AACzE,MAAI,CAAC,QAAS,QAAO,SAAS,MAAMA,MAAK,GAAG,EAAE,KAAK,GAAG;AACtD,SAAOA,MAAK,SAAS,SAAS,QAAQ,EAAE,MAAMA,MAAK,GAAG,EAAE,KAAK,GAAG;AAClE;AAEO,SAAS,qBAAqB,SAA0B;AAC7D,SAAO,YAAY,aAAa,QAAQ,WAAW,UAAU;AAC/D;AAEO,SAAS,kBACd,aACA,SACA,iBAA+B,UACjB;AACd,MAAI,YAAY,UAAU,YAAY,WAAW,SAAU,QAAO,YAAY;AAC9E,MAAI,YAAY,WAAY,QAAO;AACnC,MAAI,qBAAqB,OAAO,EAAG,QAAO;AAC1C,MAAI,YAAY,OAAQ,QAAO,YAAY;AAC3C,SAAO;AACT;AAEO,SAAS,8BAA8B,QAAiD;AAC7F,SAAO;AAAA,IACL,UAAU,OAAO,YAAY;AAAA,IAC7B,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO,YAAY,UAAU;AAAA,IACrC,gBAAgB,OAAO,YAAY;AAAA,EACrC;AACF;AAEO,SAAS,gCACd,QACA,WACA,WACsB;AACtB,SAAO;AAAA,IACL,SAAS,WAAW,OAAO,YAAY,EAAE,IAAI,SAAS,IAAI,SAAS;AAAA,IACnE,UAAU,OAAO,YAAY;AAAA,IAC7B;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO,8BAA8B,MAAM;AAAA,IAC3C,kBAAkB;AAAA,MAChB,GAAI,OAAO,YAAY,eAAe,CAAC,OAAO,YAAY,YAAY,IAAI,CAAC;AAAA,MAC3E,GAAI,OAAO,YAAY,aAAa,CAAC,OAAO,YAAY,UAAU,IAAI,CAAC;AAAA,MACvE,IAAK,OAAO,YAAY,WAAW,CAAC,GAAG,OAAO,OAAO;AAAA,IACvD;AAAA,EACF;AACF;AAEO,SAAS,8BAA8B,QAA4C;AACxF,QAAM,SAAiC,CAAC;AACxC,QAAM,UAAU,OAAO,YAAY;AACnC,QAAM,UAAU,OAAO,YAAY;AACnC,QAAM,aAAa,OAAO,YAAY;AACtC,QAAM,eAAe,OAAO,YAAY;AACxC,QAAM,sBACJ,eAAe,OAAO,YAAY,WAAW,cAAc,UAAU,UAAU;AAEjF,SAAO,KAAK,gCAAgC,QAAQ,WAAW,OAAO,CAAC;AACvE,MACE,WACA,YAAY,WACZ,YAAY,uBACZ,YAAY,cACZ;AACA,WAAO,KAAK,gCAAgC,QAAQ,WAAW,OAAO,CAAC;AAAA,EACzE;AACA,MAAI,cAAc;AAChB,WAAO,KAAK,gCAAgC,QAAQ,cAAc,YAAY,CAAC;AAAA,EACjF;AACA,MAAI,qBAAqB;AACvB,WAAO,KAAK,gCAAgC,QAAQ,YAAY,mBAAmB,CAAC;AAAA,EACtF;AAEA,SAAO;AACT;AAEO,SAAS,0BAA0B,QAAwD;AAChG,SAAO,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM;AAChC,QAAI,EAAE,aAAa,EAAE,SAAU,QAAO,EAAE,SAAS,cAAc,EAAE,QAAQ;AACzE,QAAI,EAAE,cAAc,EAAE,UAAW,QAAO,EAAE,UAAU,cAAc,EAAE,SAAS;AAC7E,WAAO,kCAAkC,EAAE,SAAS,IAAI,kCAAkC,EAAE,SAAS;AAAA,EACvG,CAAC;AACH;;;AC/GO,SAAS,2BAA2B,SAAiB,WAAW,KAAa;AAClF,SAAO,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;AAC9D;AAEO,SAAS,wBAAwB,MAAsC;AAC5E,SAAO,CAAC,GAAG,IAAI;AAAA,KACZ,QAAQ,CAAC,GACP,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,EACvC,CAAC,EAAE,KAAK;AACV;;;ACEA,SAAS,sBAAsB,KAAsB;AACnD,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,KAAsC;AAC9D,QAAM,SAAkC,CAAC;AACzC,aAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,UAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,QAAI,OAAO,EAAG;AACd,UAAM,MAAM,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK;AACpC,UAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,EAAE,KAAK;AACvC,WAAO,GAAG,IAAI,sBAAsB,KAAK;AAAA,EAC3C;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAiB,OAAe,OAAsB;AACzE,MAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,EAAG;AACzC,QAAM,KAAK,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,GAAG,EAAE;AAChD;AAEA,SAAS,aAAa,MAAc,OAAmC;AACrE,QAAM,UAAU,MAAM,QAAQ,uBAAuB,MAAM;AAC3D,QAAM,KAAK,IAAI,OAAO,MAAM,OAAO,gCAAgC;AACnE,QAAM,QAAQ,KAAK,MAAM,EAAE;AAC3B,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAC5B,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAEO,SAAS,4BAA4B,UAA4C;AACtF,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,OAAO,KAAK,UAAU,SAAS,EAAE,CAAC;AAAA,IAClC,UAAU,KAAK,UAAU,SAAS,KAAK,CAAC;AAAA,IACxC,aAAa,KAAK,UAAU,SAAS,QAAQ,CAAC;AAAA,IAC9C,cAAc,KAAK,UAAU,SAAS,SAAS,CAAC;AAAA,EAClD;AACA,MAAI,SAAS,SAAU,OAAM,KAAK,aAAa,KAAK,UAAU,SAAS,QAAQ,CAAC,EAAE;AAClF,MAAI,SAAS,cAAe,OAAM,KAAK,kBAAkB,KAAK,UAAU,SAAS,aAAa,CAAC,EAAE;AACjG,QAAM,KAAK,OAAO,EAAE;AAEpB,cAAY,OAAO,WAAW,SAAS,OAAO;AAC9C,cAAY,OAAO,mBAAmB,SAAS,cAAc;AAC7D,cAAY,OAAO,eAAe,SAAS,UAAU;AACrD,cAAY,OAAO,uBAAuB,SAAS,kBAAkB;AACrE,cAAY,OAAO,mBAAmB,SAAS,cAAc;AAE7D,SAAO,MAAM,KAAK,IAAI,EAAE,QAAQ,IAAI;AACtC;AAEO,SAAS,wBAAwB,KAA8C;AACpF,QAAM,QAAQ,IAAI,MAAM,oCAAoC;AAC5D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,cAAc,iBAAiB,MAAM,CAAC,CAAC;AAC7C,QAAM,OAAO,MAAM,CAAC,KAAK;AAEzB,QAAM,KAAK,OAAO,YAAY,OAAO,WAAW,YAAY,KAAK;AACjE,QAAM,WAAW,YAAY;AAC7B,QAAM,QAAiC,aAAa,WAAW,WAAW;AAC1E,QAAM,WAAW,OAAO,YAAY,aAAa,WAAW,YAAY,WAAW;AACnF,QAAM,YAAY,OAAO,YAAY,cAAc,WAAW,YAAY,YAAY;AACtF,QAAM,UAAU,aAAa,MAAM,SAAS;AAE5C,MAAI,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,QAAS,QAAO;AAEvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,OAAO,YAAY,kBAAkB,WAAW,YAAY,gBAAgB;AAAA,IAC3F;AAAA,IACA,gBAAgB,aAAa,MAAM,iBAAiB;AAAA,IACpD,YAAY,aAAa,MAAM,aAAa;AAAA,IAC5C,oBAAoB,aAAa,MAAM,qBAAqB;AAAA,IAC5D,gBAAgB,aAAa,MAAM,iBAAiB;AAAA,IACpD,UAAU,OAAO,YAAY,aAAa,WAAW,YAAY,WAAW;AAAA,EAC9E;AACF;AAEO,SAAS,+BACd,IACA,OACA,QAC0B;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX,eAAe,MAAM,eAAe,KAAK,KAAK;AAAA,IAC9C,SAAS,MAAM,QAAQ,KAAK;AAAA,IAC5B,gBAAgB,MAAM,gBAAgB,KAAK,KAAK;AAAA,EAClD;AACF;AAEO,SAAS,8BACd,UACA,SACA,QAC0B;AAC1B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY,QAAQ,WAAW,KAAK;AAAA,IACpC,oBAAoB,QAAQ,mBAAmB,KAAK;AAAA,IACpD,gBAAgB,QAAQ,gBAAgB,KAAK,KAAK,SAAS;AAAA,EAC7D;AACF;AAEA,IAAM,cAAc;AACpB,IAAM,gBAAgB,oBAAI,IAA2B,CAAC,SAAS,UAAU,WAAW,WAAW,CAAC;AAChG,IAAM,gBAAgB,oBAAI,IAA0B,CAAC,UAAU,UAAU,SAAS,CAAC;AACnF,IAAM,+BAA+B;AAErC,SAAS,mBAAmB,OAA+C;AACzE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO,QAAQ,QAAQ,QAAQ,GAAG;AACpC;AAEA,SAAS,WAAW,OAAwB;AAC1C,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,SAAO,OAAO,SAAS,EAAE;AAC3B;AAEA,SAAS,wBACP,OACA,QACkC;AAClC,QAAM,KAAK,mBAAmB,MAAM,EAAE;AACtC,QAAM,UAAU,mBAAmB,MAAM,OAAO;AAChD,QAAM,SAAS,mBAAmB,MAAM,MAAM;AAC9C,QAAM,UAAU,mBAAmB,MAAM,OAAO;AAChD,QAAM,gBAAgB,mBAAmB,MAAM,aAAa;AAC5D,QAAM,QAAQ,mBAAmB,MAAM,KAAK;AAC5C,QAAM,kBACJ,kBAAkB,SAAS,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe;AAC3F,QAAM,eAAe,mBAAmB,eAAe,KAAK;AAE5D,MAAI,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,cAAe,QAAO;AACrE,MAAI,CAAC,cAAc,IAAI,OAAO,EAAG,QAAO;AACxC,MAAI,CAAC,cAAc,IAAI,MAAM,EAAG,QAAO;AACvC,MAAI,CAAC,WAAW,YAAY,EAAG,QAAO;AAEtC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,+BAA+B,MAAyC;AAC/E,QAAM,QAAQ;AAAA,IACZ,MAAM,KAAK,EAAE;AAAA,IACb,YAAY,KAAK,OAAO;AAAA,IACxB,YAAY,KAAK,OAAO;AAAA,IACxB,WAAW,KAAK,MAAM;AAAA,IACtB,kBAAkB,KAAK,aAAa;AAAA,IACpC,iBAAiB,KAAK,YAAY;AAAA,EACpC;AACA,MAAI,KAAK,MAAO,OAAM,KAAK,UAAU,KAAK,KAAK,EAAE;AACjD,SAAO,MAAM,KAAK,IAAI;AACxB;AAOA,SAAS,kBAAkB,KAAqE;AAC9F,QAAM,QAAQ,OAAO,IAAI,QAAQ,OAAO,EAAE;AAC1C,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,cAAwB,CAAC;AAC/B,QAAM,WAA8B,CAAC;AACrC,MAAI,UAAkC;AAEtC,aAAW,QAAQ,OAAO;AACxB,UAAM,eAAe,KAAK,MAAM,iBAAiB;AACjD,QAAI,cAAc;AAChB,UAAI,QAAS,UAAS,KAAK,EAAE,OAAO,QAAQ,OAAO,MAAM,QAAQ,KAAK,QAAQ,EAAE,CAAC;AACjF,gBAAU,EAAE,OAAO,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG;AACpD;AAAA,IACF;AACA,QAAI,CAAC,SAAS;AACZ,kBAAY,KAAK,IAAI;AACrB;AAAA,IACF;AACA,YAAQ,QAAQ,QAAQ,KAAK,SAAS,IAAI;AAAA,EAAK,IAAI,KAAK;AAAA,EAC1D;AACA,MAAI,QAAS,UAAS,KAAK,EAAE,OAAO,QAAQ,OAAO,MAAM,QAAQ,KAAK,QAAQ,EAAE,CAAC;AAEjF,QAAM,YAAY,YAAY,KAAK,IAAI,EAAE,KAAK;AAC9C,QAAM,SAAS,UAAU,SAAS,IAAI,YAAY;AAClD,SAAO,EAAE,QAAQ,SAAS;AAC5B;AAEA,SAAS,qBAAqB,SAA0B,QAAkD;AACxG,QAAM,SAAiC,CAAC;AACxC,aAAW,QAAQ,QAAQ,KAAK,MAAM,IAAI,GAAG;AAC3C,UAAM,KAAK,KAAK,MAAM,uCAAuC;AAC7D,QAAI,CAAC,GAAI;AACT,WAAO,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;AAAA,EACtB;AACA,QAAM,qBAAqB,mBAAmB,OAAO,YAAY;AACjE,QAAM,mBACJ,sBAAsB,WAAW,kBAAkB,IAAI,qBAAqB;AAC9E,SAAO;AAAA,IACL;AAAA,MACE,IAAI,QAAQ;AAAA,MACZ,SAAU,OAAO,WAAW;AAAA,MAC5B,SAAS,OAAO,WAAW;AAAA,MAC3B,QAAS,OAAO,UAAU;AAAA,MAC1B,eAAe,OAAO,iBAAiB;AAAA,MACvC,cAAc;AAAA,MACd,OAAO,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAAgB,UAAqC;AAC7E,QAAM,QAAkB,CAAC,OAAO,KAAK,GAAG,EAAE;AAC1C,aAAW,WAAW,UAAU;AAC9B,UAAM,KAAK,MAAM,QAAQ,KAAK,EAAE;AAChC,QAAI,QAAQ,KAAK,KAAK,EAAE,SAAS,GAAG;AAClC,YAAM,KAAK,QAAQ,KAAK,QAAQ,CAAC;AAAA,IACnC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO,MAAM,KAAK,IAAI,EAAE,QAAQ,WAAW,MAAM,EAAE,QAAQ,IAAI;AACjE;AAEO,SAAS,gCAAgC,KAA0C;AACxF,QAAM,SAAS,kBAAkB,GAAG;AACpC,QAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,SAAO,OAAO,SACX,IAAI,CAAC,YAAY,qBAAqB,SAAS,MAAM,CAAC,EACtD,OAAO,CAAC,SAA4C,SAAS,IAAI;AACtE;AAEO,SAAS,+BACd,KACA,OACA,QACuD;AACvD,QAAM,aAAa,wBAAwB,OAAO,MAAM;AACxD,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAEA,QAAM,SAAS,kBAAkB,GAAG;AACpC,MAAI,WAAW;AACf,QAAM,eAAe,OAAO,SAAS,IAAI,CAAC,YAAY;AACpD,QAAI,mBAAmB,QAAQ,KAAK,MAAM,WAAW,GAAI,QAAO;AAChE,eAAW;AACX,WAAO,EAAE,OAAO,WAAW,IAAI,MAAM,+BAA+B,UAAU,EAAE,MAAM,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE;AAAA,EAClH,CAAC;AAED,MAAI,CAAC,UAAU;AACb,iBAAa,KAAK;AAAA,MAChB,OAAO,WAAW;AAAA,MAClB,MAAM,+BAA+B,UAAU,EAAE,MAAM,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,IACjF,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,UAAU,iBAAiB,OAAO,QAAQ,YAAY,GAAG,MAAM,WAAW;AACrF;AAEO,SAAS,+BACd,KACA,IACA,OACA,QAC8D;AAC9D,QAAM,SAAS,kBAAkB,GAAG;AACpC,QAAM,eAAe,mBAAmB,EAAE;AAC1C,MAAI,CAAC,cAAc;AACjB,WAAO,EAAE,UAAU,iBAAiB,OAAO,QAAQ,OAAO,QAAQ,GAAG,MAAM,KAAK;AAAA,EAClF;AACA,MAAI,cAAgD;AACpD,QAAM,eAAe,OAAO,SAAS,IAAI,CAAC,YAAY;AACpD,QAAI,mBAAmB,QAAQ,KAAK,MAAM,aAAc,QAAO;AAC/D,UAAM,WAAW,qBAAqB,SAAS,MAAM;AACrD,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,WAAW,0BAA0B,UAAU,OAAO,MAAM;AAClE,kBAAc;AACd,WAAO,EAAE,OAAO,SAAS,IAAI,MAAM,+BAA+B,QAAQ,EAAE,MAAM,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE;AAAA,EAC9G,CAAC;AAED,SAAO,EAAE,UAAU,iBAAiB,OAAO,QAAQ,YAAY,GAAG,MAAM,YAAY;AACtF;AAEA,SAAS,0BACP,UACA,OACA,QAC2B;AAC3B,QAAM,aAAa,mBAAmB,MAAM,MAAM;AAClD,QAAM,YAAY,mBAAmB,MAAM,KAAK;AAChD,QAAM,aAAa,mBAAmB,MAAM,UAAU,KAAK;AAE3D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,cAAc,cAAc,IAAI,UAAU,IAAI,aAAa,SAAS;AAAA,IAC5E,OAAO,aAAa,SAAS;AAAA,IAC7B,cAAc,WAAW,UAAU,IAAI,aAAa;AAAA,EACtD;AACF;;;ARlQA,IAAM,4BAA4B,oBAAI,IAAI;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAkBD,SAAS,2BAA2B,OAAyB;AAC3D,SAAO,MACJ,YAAY,EACZ,MAAM,aAAa,EACnB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,EAC3B,OAAO,CAAC,MAAM,CAAC,0BAA0B,IAAI,CAAC,CAAC;AACpD;AAEA,SAAS,qBAAqB,IAA+B;AAC3D,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,OAAO,GAAG,EAAE;AAAA,IACZ,aAAa,GAAG,QAAQ;AAAA,IACxB,YAAY,GAAG,OAAO;AAAA,IACtB,YAAY,GAAG,OAAO;AAAA,IACtB,WAAW,GAAG,MAAM;AAAA,IACpB,eAAe,GAAG,UAAU;AAAA,IAC5B,mBAAmB,GAAG,cAAc;AAAA,IACpC,UAAU,GAAG,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,EACnD;AACA,MAAI,GAAG,UAAW,OAAM,KAAK,cAAc,GAAG,SAAS,EAAE;AACzD,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC5D,MAAI,GAAG,UAAW,OAAM,KAAK,cAAc,GAAG,SAAS,EAAE;AACzD,MAAI,GAAG,WAAW,GAAG,QAAQ,SAAS,GAAG;AACvC,UAAM,KAAK,aAAa,GAAG,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG;AAAA,EACvE;AAEA,MAAI,GAAG,UAAU,GAAG,WAAW,SAAU,OAAM,KAAK,WAAW,GAAG,MAAM,EAAE;AAC1E,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAClE,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAClE,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAE5D,MAAI,GAAG,eAAgB,OAAM,KAAK,mBAAmB,GAAG,cAAc,EAAE;AACxE,MAAI,GAAG,kBAAmB,OAAM,KAAK,sBAAsB,GAAG,iBAAiB,EAAE;AACjF,MAAI,GAAG,YAAa,OAAM,KAAK,gBAAgB,GAAG,WAAW,EAAE;AAC/D,MAAI,GAAG,gBAAiB,OAAM,KAAK,oBAAoB,GAAG,eAAe,EAAE;AAC3E,MAAI,GAAG,eAAe,OAAW,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC1E,MAAI,GAAG,cAAc,OAAW,OAAM,KAAK,cAAc,GAAG,SAAS,EAAE;AAEvE,MAAI,GAAG,gBAAgB,UAAa,GAAG,cAAc,GAAG;AACtD,UAAM,KAAK,gBAAgB,GAAG,WAAW,EAAE;AAAA,EAC7C;AACA,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAElE,MAAI,GAAG,YAAY;AACjB,UAAM,KAAK,oBAAoB,GAAG,WAAW,KAAK,EAAE;AACpD,UAAM,KAAK,oBAAoB,GAAG,WAAW,KAAK,EAAE;AACpD,QAAI,GAAG,WAAW,QAAQ,SAAS,GAAG;AACpC,YAAM;AAAA,QACJ,uBAAuB,GAAG,WAAW,QAClC,IAAI,CAAC,MAAM,IAAI,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC,GAAG,EAC/D,KAAK,IAAI,CAAC;AAAA,MACf;AAAA,IACF;AACA,QAAI,GAAG,WAAW,SAAS,SAAS,GAAG;AACrC,YAAM,KAAK,wBAAwB,GAAG,WAAW,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG;AAAA,IAC9F;AAAA,EACF;AAEA,MAAI,GAAG,SAAU,OAAM,KAAK,aAAa,GAAG,QAAQ,EAAE;AACtD,MAAI,GAAG,eAAe,OAAW,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC1E,MAAI,GAAG,eAAe,OAAW,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAE1E,MAAI,GAAG,SAAS,GAAG,MAAM,SAAS,GAAG;AACnC,UAAM,KAAK,QAAQ;AACnB,eAAW,QAAQ,GAAG,OAAO;AAC3B,YAAM,KAAK,iBAAiB,KAAK,QAAQ,EAAE;AAC3C,YAAM,KAAK,iBAAiB,KAAK,QAAQ,EAAE;AAC3C,YAAM,KAAK,iBAAiB,KAAK,QAAQ,EAAE;AAC3C,UAAI,KAAK,OAAQ,OAAM,KAAK,eAAe,KAAK,UAAU,KAAK,MAAM,CAAC,EAAE;AAAA,IAC1E;AAAA,EACF;AACA,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC5D,MAAI,GAAG,iBAAkB,OAAM,KAAK,qBAAqB,GAAG,gBAAgB,EAAE;AAC9E,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;AAC3D,UAAM,KAAK,uBAAuB,GAAG,kBAAkB,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG;AAAA,EAC3F;AACA,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAClE,MAAI,GAAG,eAAgB,OAAM,KAAK,mBAAmB,GAAG,cAAc,EAAE;AACxE,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAElE,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAE5D,MAAI,GAAG,wBAAwB,OAAO,KAAK,GAAG,oBAAoB,EAAE,SAAS,GAAG;AAC9E,UAAM,KAAK,yBAAyB,KAAK,UAAU,GAAG,oBAAoB,CAAC,EAAE;AAAA,EAC/E;AACA,QAAM,KAAK,KAAK;AAChB,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,0BAA0B,KAA6D;AAC9F,MAAI,CAAC,OAAO,CAAC,IAAI,KAAK,EAAG,QAAO;AAChC,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC3E,YAAM,SAAiC,CAAC;AACxC,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,YAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAClD,iBAAO,CAAC,IAAI;AAAA,QACd;AAAA,MACF;AACA,aAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AAAA,IACnD;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,UAA0B;AACtD,QAAM,cAAc,SAAS,QAAQ,QAAQ,GAAG;AAChD,QAAM,sBACJ,CAAC,SAAS,SAAS,MAAM,MACxB,qDAAqD,KAAK,QAAQ,KACjE,uCAAuC,KAAK,QAAQ;AAExD,MAAI,qBAAqB;AACvB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,IAAI,QAAQ,GAAG;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,kBACP,KAC4D;AAC5D,QAAM,QAAQ,IAAI,MAAM,oCAAoC;AAC5D,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,UAAU,MAAM,CAAC;AACvB,QAAM,UAAU,MAAM,CAAC,EAAE,KAAK;AAC9B,QAAM,KAA6B,CAAC;AAEpC,aAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,UAAM,WAAW,KAAK,QAAQ,GAAG;AACjC,QAAI,aAAa,GAAI;AACrB,UAAM,MAAM,KAAK,MAAM,GAAG,QAAQ,EAAE,KAAK;AACzC,UAAM,QAAQ,KAAK,MAAM,WAAW,CAAC,EAAE,KAAK;AAC5C,OAAG,GAAG,IAAI;AAAA,EACZ;AAEA,MAAI,OAAiB,CAAC;AACtB,QAAM,UAAU,GAAG,QAAQ;AAC3B,QAAM,WAAW,QAAQ,MAAM,SAAS;AACxC,MAAI,UAAU;AACZ,WAAO,SAAS,CAAC,EACd,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,EACnB;AAEA,MAAI;AACJ,QAAM,uBAAuB,GAAG,qBAAqB;AACrD,QAAM,yBAAyB,qBAAqB,MAAM,SAAS;AACnE,MAAI,wBAAwB;AAC1B,wBAAoB,uBAAuB,CAAC,EACzC,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,EACnB;AAEA,QAAM,OAAO,WAAW,GAAG,cAAc,KAAK;AAG9C,MAAI;AACJ,QAAM,aAAa,GAAG,WAAW;AACjC,QAAM,eAAe,WAAW,MAAM,SAAS;AAC/C,MAAI,cAAc;AAChB,cAAU,aAAa,CAAC,EACrB,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,EACnB;AAGA,QAAM,cAAc,GAAG,cAAc,SAAS,GAAG,aAAa,EAAE,IAAI;AACpE,QAAM,aAAa,GAAG,eAAe,SAAY,WAAW,GAAG,UAAU,IAAI;AAC7E,QAAM,YAAY,GAAG,cAAc,SAAY,WAAW,GAAG,SAAS,IAAI;AAG1E,MAAI;AACJ,MAAI,GAAG,iBAAiB;AACtB,UAAM,QAAQ,WAAW,GAAG,eAAe;AAC3C,UAAM,QAAS,GAAG,mBAAuC;AAGzD,QAAI,UAAoB,CAAC;AACzB,UAAM,aAAa,GAAG,qBAAqB;AAC3C,QAAI,WAAW,KAAK,EAAE,WAAW,GAAG,KAAK,WAAW,KAAK,EAAE,SAAS,GAAG,GAAG;AACxE,YAAM,gBAAgB,WAAW,SAAS,sBAAsB;AAChE,iBAAWC,UAAS,eAAe;AACjC,cAAM,SAAS,qBAAqBA,OAAM,CAAC,CAAC;AAC5C,YAAI,OAAO,SAAS,GAAG;AACrB,kBAAQ,KAAK,MAAM;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAGA,QAAI,WAAqB,CAAC;AAC1B,UAAM,cAAc,GAAG,sBAAsB;AAC7C,UAAM,gBAAgB,YAAY,MAAM,SAAS;AACjD,QAAI,eAAe;AACjB,iBAAW,cAAc,CAAC,EACvB,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,IACnB;AAEA,iBAAa,EAAE,OAAO,OAAO,SAAS,SAAS;AAAA,EACjD;AAEA,QAAM,SAA8D;AAAA,IAClE,aAAa;AAAA,MACX,IAAI,GAAG,MAAM;AAAA,MACb,UAAW,GAAG,YAAY;AAAA,MAC1B,SAAS,GAAG,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC9C,SAAS,GAAG,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC9C,QAAQ,GAAG,UAAU;AAAA,MACrB,YAAY;AAAA,MACZ,gBAAiB,GAAG,kBAAqC,eAAe,IAAI;AAAA,MAC5E;AAAA,MACA,WAAW,GAAG,aAAa;AAAA,MAC3B,YAAY,GAAG,cAAc;AAAA,MAC7B,WAAW,GAAG,aAAa;AAAA,MAC3B,SAAS,WAAW,QAAQ,SAAS,IAAI,UAAU;AAAA;AAAA,MAEnD,QAAS,GAAG,UAA2B;AAAA,MACvC,cAAc,GAAG,gBAAgB;AAAA,MACjC,cAAc,GAAG,gBAAgB;AAAA,MACjC,YAAY,GAAG,cAAc;AAAA,MAC7B,gBAAiB,GAAG,kBAAqC;AAAA,MACzD,mBAAoB,GAAG,qBAA2C;AAAA,MAClE,aAAc,GAAG,eAA+B;AAAA,MAChD,iBAAiB,GAAG,mBAAmB;AAAA,MACvC,YAAY,OAAO,SAAS,UAAU,IAAI,aAAa;AAAA,MACvD,WAAW,OAAO,SAAS,SAAS,IAAI,YAAY;AAAA;AAAA,MAEpD,aAAa,eAAe,cAAc,IAAI,cAAc;AAAA,MAC5D,cAAc,GAAG,gBAAgB;AAAA;AAAA,MAEjC;AAAA;AAAA,MAEA,UAAU,GAAG,YAAY;AAAA,MACzB,YAAY,GAAG,aAAa,SAAS,GAAG,YAAY,EAAE,IAAI;AAAA,MAC1D,YAAY,GAAG,aAAa,SAAS,GAAG,YAAY,EAAE,IAAI;AAAA;AAAA,MAE1D,YAAY,GAAG,cAAc;AAAA,MAC7B,kBAAkB,GAAG,oBAAoB;AAAA,MACzC,mBAAmB,qBAAqB,kBAAkB,SAAS,IAAI,oBAAoB;AAAA,MAC3F,cAAe,GAAG,gBAAsD;AAAA,MACxE,gBAAgB,GAAG,kBAAkB;AAAA,MACrC,cAAc,GAAG,gBAAgB;AAAA;AAAA,MAEjC,YAAa,GAAG,cAAkD;AAAA;AAAA,MAElE,sBAAsB,0BAA0B,GAAG,oBAAoB;AAAA,IACzE;AAAA,IACA;AAAA,EACF;AAIA,MAAI,QAAQ,SAAS,QAAQ,GAAG;AAC9B,UAAM,QAAsB,CAAC;AAC7B,UAAM,cAAc,QAAQ;AAAA,MAC1B;AAAA,IACF;AACA,eAAWA,UAAS,aAAa;AAC/B,YAAM,KAAK;AAAA,QACT,UAAUA,OAAM,CAAC;AAAA,QACjB,UAAUA,OAAM,CAAC;AAAA,QACjB,UAAU,WAAWA,OAAM,CAAC,CAAC;AAAA,QAC7B,QAAQA,OAAM,CAAC,IAAI,qBAAqBA,OAAM,CAAC,CAAC,IAAI;AAAA,MACtD,CAAC;AAAA,IACH;AACA,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,YAAY,QAAQ;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,4BAA4B,aAAgC,SAAoC;AACvG,MAAI,qBAAqB,OAAO,MAAM,CAAC,YAAY,UAAU,YAAY,WAAW,WAAW;AAC7F,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,wBACP,aACA,SACA,gBACc;AACd,SAAO,kBAAkB,aAAa,SAAS,cAAc;AAC/D;AAOA,IAAI,cAAsC,CAAC;AAG3C,IAAM,kBAA0C;AAAA,EAC9C,UAAU;AAAA,EACV,aAAa;AACf;AASO,SAAS,oBAAoB,KAAa,MAAsB;AAErE,QAAM,SAAS,OAAO,QAAQ,WAAW,MAAM;AAC/C,QAAM,UAAU,OAAO,SAAS,YAAY,KAAK,KAAK,EAAE,SAAS,IAAI,OAAO;AAE5E,MAAI,OAAO,OAAO,YAAY,EAAE,KAAK;AACrC,QAAM,aAAa,GAAG,QAAQ,YAAY,CAAC;AAC3C,MAAI,KAAK,WAAW,UAAU,GAAG;AAC/B,WAAO,KAAK,MAAM,WAAW,MAAM;AAAA,EACrC;AAGA,MAAI,aAAa,KACd,QAAQ,eAAe,GAAG,EAC1B,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,EAAE;AAGvB,MAAI,YAAY,UAAU,GAAG;AAC3B,iBAAa,YAAY,UAAU;AAAA,EACrC,WAAW,gBAAgB,UAAU,GAAG;AACtC,iBAAa,gBAAgB,UAAU;AAAA,EACzC;AAEA,SAAO,GAAG,QAAQ,YAAY,CAAC,IAAI,UAAU;AAC/C;AAKA,SAAS,YAAY,GAAW,GAAmB;AACjD,QAAM,IAAI,EAAE;AACZ,QAAM,IAAI,EAAE;AACZ,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,MAAM,EAAG,QAAO;AAEpB,QAAM,KAAiB,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAAG,MAAM,IAAI,MAAM,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;AACnF,WAAS,IAAI,GAAG,KAAK,GAAG,IAAK,IAAG,CAAC,EAAE,CAAC,IAAI;AACxC,WAAS,IAAI,GAAG,KAAK,GAAG,IAAK,IAAG,CAAC,EAAE,CAAC,IAAI;AAExC,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,SAAG,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAC3B,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,IACf,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;AAAA,IAC/D;AAAA,EACF;AACA,SAAO,GAAG,CAAC,EAAE,CAAC;AAChB;AAGA,SAAS,YAAY,GAAmB;AACtC,SAAO,EAAE,QAAQ,MAAM,EAAE;AAC3B;AAQO,IAAM,mBAAN,MAAM,kBAAiB;AAAA,EACpB,SAAsB,oBAAI,IAAI;AAAA,EAC9B,QAAQ;AAAA,EACC;AAAA,EAEjB,YAAY,UAAkB;AAC5B,SAAK,WAAWC,MAAK,KAAK,UAAU,iBAAiB;AAAA,EACvD;AAAA;AAAA,EAGA,MAAM,OAAsB;AAC1B,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,KAAK,UAAU,OAAO;AACjD,iBAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,cAAM,UAAU,KAAK,KAAK;AAC1B,YAAI,QAAQ,SAAS,GAAG;AACtB,eAAK,OAAO,IAAI,OAAO;AAAA,QACzB;AAAA,MACF;AACA,UAAI,MAAM,8BAA8B,KAAK,OAAO,IAAI,SAAS;AAAA,IACnE,QAAQ;AACN,UAAI,MAAM,6DAAwD;AAAA,IACpE;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,SAA0B;AAC5B,WAAO,KAAK,OAAO,IAAI,kBAAiB,YAAY,OAAO,CAAC;AAAA,EAC9D;AAAA;AAAA,EAGA,IAAI,SAAuB;AACzB,UAAM,OAAO,kBAAiB,YAAY,OAAO;AACjD,QAAI,CAAC,KAAK,OAAO,IAAI,IAAI,GAAG;AAC1B,WAAK,OAAO,IAAI,IAAI;AACpB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA,EAGA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,MAAO;AACjB,UAAMC,OAAMF,MAAK,QAAQ,KAAK,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5D,UAAMG,WAAU,KAAK,UAAU,CAAC,GAAG,KAAK,MAAM,EAAE,KAAK,IAAI,IAAI,MAAM,OAAO;AAC1E,SAAK,QAAQ;AACb,QAAI,MAAM,6BAA6B,KAAK,OAAO,IAAI,SAAS;AAAA,EAClE;AAAA;AAAA,EAGA,OAAO,SAAuB;AAC5B,UAAM,OAAO,kBAAiB,YAAY,OAAO;AACjD,QAAI,KAAK,OAAO,OAAO,IAAI,GAAG;AAC5B,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,iBAAiB,SAAyB;AAC/C,WAAO,QACJ,YAAY,EACZ,QAAQ,gBAAgB,GAAG,EAC3B,QAAQ,QAAQ,GAAG,EACnB,KAAK;AAAA,EACV;AAAA;AAAA,EAGA,OAAO,YAAY,SAAyB;AAC1C,UAAM,aAAa,kBAAiB,iBAAiB,OAAO;AAC5D,WAAO,WAAW,QAAQ,EAAE,OAAO,UAAU,EAAE,OAAO,KAAK;AAAA,EAC7D;AACF;AAUO,SAAS,gBAAgB,SAA6B;AAC3D,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAGhC,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,UAAU;AACd,MAAI;AACJ,QAAM,QAAkB,CAAC;AACzB,QAAM,gBAAsC,CAAC;AAC7C,QAAM,WAAkC,CAAC;AACzC,QAAM,UAAoB,CAAC;AAG3B,QAAM,cAAc,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC;AACxD,MAAI,YAAa,QAAO,YAAY,MAAM,CAAC,EAAE,KAAK;AAGlD,QAAM,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AAC5D,MAAI,SAAU,QAAO,SAAS,QAAQ,aAAa,EAAE,EAAE,KAAK;AAG5D,QAAM,cAAc,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,cAAc,CAAC;AAClE,MAAI,YAAa,WAAU,YAAY,QAAQ,gBAAgB,EAAE,EAAE,KAAK;AAGxE,MAAI,UAAU;AACd,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,KAAK,GAAG;AAC1B,gBAAU,KAAK,MAAM,CAAC,EAAE,KAAK,EAAE,YAAY;AAC3C;AAAA,IACF;AACA,QAAI,CAAC,KAAK,WAAW,IAAI,EAAG;AAE5B,UAAM,SAAS,KAAK,MAAM,CAAC,EAAE,KAAK;AAClC,QAAI,CAAC,OAAQ;AAEb,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,cAAM,KAAK,MAAM;AACjB;AAAA,MACF,KAAK;AAEH;AAAA,MACF,KAAK,gBAAgB;AAEnB,cAAM,WAAW,OAAO,MAAM,mCAAmC;AACjE,YAAI,UAAU;AACZ,wBAAc,KAAK,EAAE,QAAQ,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,QAC9E;AACA;AAAA,MACF;AAAA,MACA,KAAK,YAAY;AAEf,cAAM,WAAW,OAAO,MAAM,+BAA+B;AAC7D,YAAI,UAAU;AACZ,mBAAS,KAAK,EAAE,MAAM,SAAS,CAAC,GAAG,MAAM,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,QAC/D;AACA;AAAA,MACF;AAAA,MACA,KAAK;AACH,gBAAQ,KAAK,MAAM;AACnB;AAAA,IACJ;AAAA,EACF;AAGA,QAAM,aAAa,MAAM,UAAU,CAAC,MAAM,EAAE,WAAW,YAAY,CAAC;AACpE,MAAI,eAAe,IAAI;AACrB,UAAM,eAAyB,CAAC;AAChC,aAAS,IAAI,aAAa,GAAG,IAAI,MAAM,QAAQ,KAAK;AAClD,UAAI,MAAM,CAAC,EAAE,WAAW,KAAK,EAAG;AAChC,YAAM,UAAU,MAAM,CAAC,EAAE,KAAK;AAC9B,UAAI,QAAS,cAAa,KAAK,OAAO;AAAA,IACxC;AACA,QAAI,aAAa,SAAS,EAAG,WAAU,aAAa,KAAK,GAAG;AAAA,EAC9D;AAEA,SAAO,EAAE,MAAM,MAAM,SAAS,OAAO,SAAS,eAAe,UAAU,QAAQ;AACjF;AAMO,SAAS,oBAAoB,QAA4B;AAC9D,QAAM,QAAkB;AAAA,IACtB,KAAK,OAAO,IAAI;AAAA,IAChB;AAAA,IACA,aAAa,OAAO,IAAI;AAAA,IACxB,gBAAgB,OAAO,YAAW,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,IAC1D;AAAA,EACF;AAGA,MAAI,OAAO,SAAS;AAClB,UAAM,KAAK,cAAc,IAAI,OAAO,SAAS,EAAE;AAAA,EACjD;AAGA,QAAM,KAAK,YAAY,EAAE;AACzB,aAAW,KAAK,OAAO,OAAO;AAC5B,UAAM,KAAK,KAAK,CAAC,EAAE;AAAA,EACrB;AACA,QAAM,KAAK,EAAE;AAGb,MAAI,OAAO,cAAc,SAAS,GAAG;AACnC,UAAM,KAAK,mBAAmB,EAAE;AAChC,eAAW,OAAO,OAAO,eAAe;AACtC,YAAM,KAAK,OAAO,IAAI,MAAM,aAAQ,IAAI,KAAK,EAAE;AAAA,IACjD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,KAAK,eAAe,EAAE;AAC5B,eAAW,OAAO,OAAO,UAAU;AACjC,YAAM,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;AAAA,IACzC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,UAAM,KAAK,cAAc,EAAE;AAC3B,eAAW,SAAS,OAAO,SAAS;AAClC,YAAM,KAAK,KAAK,KAAK,EAAE;AAAA,IACzB;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,IAAM,iBAAN,MAAM,gBAAe;AAAA,EA4C1B,YAA6B,SAAiB;AAAjB;AAAA,EAAkB;AAAA,EA3CvC,sBAAkE;AAAA,EAC1E,OAAwB,+BAA+B;AAAA;AAAA,EAC/C,qBAAkG;AAAA,EAC1G,OAAwB,8BAA8B;AAAA;AAAA,EACtD,OAAwB,4BAA4B,oBAAI,IAAoB;AAAA,EAC5E,OAAwB,2BAA2B,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY3E,OAAwB,sBAAsB,oBAAI,IAAmC;AAAA;AAAA;AAAA;AAAA,EAKrF,OAAwB,yBAAyB;AAAA;AAAA,EACjD,OAAwB,iBAAiB,oBAAI,IAc3C;AAAA,EACM,gBAAyC;AAAA,EACzC,2BAA6D;AAAA,EAC7D,6BAA6C;AAAA,EAC7C,oCAA0D;AAAA;AAAA,EAKlE,IAAI,MAAc;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,iBAAiB,cAAsB,WAA4B;AACzE,UAAM,eAAe,OAAO,cAAc,WAAW,UAAU,KAAK,IAAI;AACxE,QAAI,CAAC,aAAc,QAAOH,MAAK,KAAK,cAAc,aAAa;AAC/D,UAAM,gBAAgB,aAAa,QAAQ,oBAAoB,GAAG;AAClE,WAAOA,MAAK,KAAK,cAAc,YAAY,aAAa,KAAK;AAAA,EAC/D;AAAA,EAEQ,gBAAgB,MAAkD;AACxE,UAAM,WACJ,SAAS,kBAAkB,+BAA+B;AAC5D,WAAOA,MAAK,KAAK,KAAK,UAAU,QAAQ;AAAA,EAC1C;AAAA,EAEQ,kBACN,MACA,aACQ;AACR,UAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,QAAI;AACF,gBAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,qBAAe,UAAU,GAAG;AAC5B,YAAM,OAAO,SAAS,QAAQ,EAAE;AAChC,kBAAY,IAAI,KAAK,SAAS,IAAI;AAClC,aAAO;AAAA,IACT,QAAQ;AACN,YAAM,QAAQ,YAAY,IAAI,KAAK,OAAO,KAAK,KAAK;AACpD,kBAAY,IAAI,KAAK,SAAS,IAAI;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,kBACN,MACA,aACQ;AACR,UAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,QAAI;AACF,aAAO,SAAS,QAAQ,EAAE;AAAA,IAC5B,QAAQ;AACN,aAAO,YAAY,IAAI,KAAK,OAAO,KAAK;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,0BAAgC;AACtC,SAAK,kBAAkB,iBAAiB,gBAAe,wBAAwB;AAAA,EACjF;AAAA,EAEA,yBAAiC;AAC/B,WAAO,KAAK,kBAAkB,iBAAiB,gBAAe,wBAAwB;AAAA,EACxF;AAAA,EAEQ,2BAAmC;AACzC,WAAO,KAAK,kBAAkB,kBAAkB,gBAAe,yBAAyB;AAAA,EAC1F;AAAA,EAEQ,0BAAkC;AACxC,WAAO,KAAK,kBAAkB,kBAAkB,gBAAe,yBAAyB;AAAA,EAC1F;AAAA,EAEA,IAAY,WAAmB;AAC7B,WAAOA,MAAK,KAAK,KAAK,SAAS,OAAO;AAAA,EACxC;AAAA,EACA,IAAY,iBAAyB;AACnC,WAAOA,MAAK,KAAK,KAAK,SAAS,aAAa;AAAA,EAC9C;AAAA,EACA,IAAY,cAAsB;AAChC,WAAOA,MAAK,KAAK,KAAK,SAAS,UAAU;AAAA,EAC3C;AAAA,EACA,IAAY,WAAmB;AAC7B,WAAOA,MAAK,KAAK,KAAK,SAAS,OAAO;AAAA,EACxC;AAAA,EACA,IAAY,yBAAiC;AAC3C,WAAOA,MAAK,KAAK,KAAK,UAAU,mBAAmB;AAAA,EACrD;AAAA,EAEA,MAAc,mBAA8C;AAC1D,QAAI,KAAK,eAAe;AACtB,aAAO,KAAK;AAAA,IACd;AACA,QAAI,CAAC,KAAK,0BAA0B;AAClC,YAAM,QAAQ,IAAI,iBAAiB,KAAK,QAAQ;AAChD,WAAK,2BAA2B,MAC7B,KAAK,EACL,KAAK,MAAM;AACV,aAAK,gBAAgB;AACrB,eAAO;AAAA,MACT,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,aAAK,2BAA2B;AAChC,cAAM;AAAA,MACR,CAAC;AAAA,IACL;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,mCAAkD;AAC9D,QAAI,KAAK,+BAA+B,MAAM;AAC5C;AAAA,IACF;AACA,QAAI,KAAK,mCAAmC;AAC1C,YAAM,KAAK;AACX;AAAA,IACF;AAEA,SAAK,qCAAqC,YAAY;AACpD,UAAI;AACF,cAAM,OAAO,KAAK,sBAAsB;AACxC,aAAK,6BAA6B;AAClC;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,YAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,YAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,iBAAW,UAAU,UAAU;AAC7B,YAAI,OAAO,YAAY,aAAa,OAAQ;AAC5C,YAAI,kBAAkB,OAAO,aAAa,OAAO,IAAI,MAAM,SAAU;AACrE,sBAAc,IAAI,OAAO,OAAO;AAAA,MAClC;AACA,YAAM,cAAc,KAAK;AACzB,YAAME,OAAMF,MAAK,QAAQ,KAAK,sBAAsB,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1E,YAAMG,WAAU,KAAK,wBAAwB,QAAQ,OAAO;AAC5D,WAAK,6BAA6B;AAAA,IACpC,GAAG,EAAE,QAAQ,MAAM;AACjB,WAAK,oCAAoC;AAAA,IAC3C,CAAC;AACD,UAAM,KAAK;AAAA,EACb;AAAA,EACA,IAAY,eAAuB;AACjC,WAAOH,MAAK,KAAK,KAAK,SAAS,WAAW;AAAA,EAC5C;AAAA,EACA,IAAY,eAAuB;AACjC,WAAOA,MAAK,KAAK,KAAK,SAAS,WAAW;AAAA,EAC5C;AAAA,EACA,IAAY,cAAsB;AAChC,WAAOA,MAAK,KAAK,KAAK,SAAS,UAAU;AAAA,EAC3C;AAAA,EACA,IAAY,qBAA6B;AACvC,WAAOA,MAAK,KAAK,KAAK,aAAa,oBAAoB;AAAA,EACzD;AAAA,EACA,IAAY,uBAA+B;AACzC,WAAOA,MAAK,KAAK,KAAK,aAAa,WAAW;AAAA,EAChD;AAAA,EACA,IAAY,0BAAkC;AAC5C,WAAOA,MAAK,KAAK,KAAK,aAAa,UAAU,QAAQ;AAAA,EACvD;AAAA,EACA,IAAY,2BAAmC;AAC7C,WAAOA,MAAK,KAAK,KAAK,aAAa,UAAU,SAAS;AAAA,EACxD;AAAA,EACA,IAAY,+BAAuC;AACjD,WAAOA,MAAK,KAAK,KAAK,aAAa,sBAAsB;AAAA,EAC3D;AAAA,EACA,IAAY,0BAAkC;AAC5C,WAAOA,MAAK,KAAK,KAAK,aAAa,gBAAgB;AAAA,EACrD;AAAA,EACA,IAAY,cAAsB;AAChC,WAAOA,MAAK,KAAK,KAAK,SAAS,YAAY;AAAA,EAC7C;AAAA,EACA,IAAY,oBAA4B;AACtC,WAAOA,MAAK,KAAK,KAAK,UAAU,sBAAsB;AAAA,EACxD;AAAA,EACA,IAAY,4BAAoC;AAC9C,WAAOA,MAAK,KAAK,KAAK,UAAU,+BAA+B;AAAA,EACjE;AAAA,EACA,IAAY,4BAAoC;AAC9C,WAAOA,MAAK,KAAK,KAAK,UAAU,2BAA2B;AAAA,EAC7D;AAAA,EACA,IAAY,gCAAwC;AAClD,WAAOA,MAAK,KAAK,KAAK,UAAU,iCAAiC;AAAA,EACnE;AAAA,EACA,IAAY,gCAAwC;AAClD,WAAOA,MAAK,KAAK,KAAK,UAAU,kCAAkC;AAAA,EACpE;AAAA,EACA,IAAY,qCAA6C;AACvD,WAAOA,MAAK,KAAK,KAAK,UAAU,wCAAwC;AAAA,EAC1E;AAAA,EACA,IAAY,sBAA8B;AACxC,WAAOA,MAAK,KAAK,KAAK,UAAU,wBAAwB;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAA6B;AACjC,UAAM,YAAYA,MAAK,KAAK,KAAK,SAAS,UAAU,cAAc;AAClE,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,WAAW,OAAO;AAC7C,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,sBAAc;AACd,YAAI,MAAM,UAAU,OAAO,KAAK,WAAW,EAAE,MAAM,wBAAwB,SAAS,EAAE;AAAA,MACxF;AAAA,IACF,QAAQ;AAEN,UAAI,MAAM,iEAA4D;AAAA,IACxE;AAAA,EACF;AAAA,EAEA,MAAM,oBAAmC;AACvC,UAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClD,UAAMC,OAAMF,MAAK,KAAK,KAAK,UAAU,KAAK,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,UAAME,OAAM,KAAK,gBAAgB,EAAE,WAAW,KAAK,CAAC;AACpD,UAAMA,OAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAMA,OAAM,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAMA,OAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAClD,UAAMA,OAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAClD,UAAMA,OAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAMA,OAAM,KAAK,sBAAsB,EAAE,WAAW,KAAK,CAAC;AAC1D,UAAMA,OAAM,KAAK,yBAAyB,EAAE,WAAW,KAAK,CAAC;AAC7D,UAAMA,OAAM,KAAK,0BAA0B,EAAE,WAAW,KAAK,CAAC;AAC9D,UAAMA,OAAMF,MAAK,KAAK,KAAK,SAAS,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EACpE;AAAA,EAEA,MAAM,YACJ,UACA,SACA,UAmBI,CAAC,GACY;AACjB,UAAM,KAAK,kBAAkB;AAC7B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AAC3C,UAAM,KAAK,GAAG,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC9E,UAAM,OAAO,QAAQ,cAAc;AACnC,UAAM,OAAO,eAAe,IAAI;AAGhC,QAAI;AACJ,QAAI,OAAO,QAAQ,cAAc,YAAY,QAAQ,UAAU,SAAS,GAAG;AACzE,kBAAY,QAAQ;AAAA,IACtB,WAAW,SAAS,eAAe;AACjC,YAAM,SAAS,IAAI,KAAK,IAAI,QAAQ,IAAI,uBAAuB,KAAK,KAAK,KAAK,GAAI;AAClF,kBAAY,OAAO,YAAY;AAAA,IACjC;AAEA,UAAM,KAAwB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,SAAS,IAAI,YAAY;AAAA,MACzB,SAAS,IAAI,YAAY;AAAA,MACzB,QAAQ,QAAQ,UAAU;AAAA,MAC1B,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,WAAW,QAAQ;AAAA,MACnB,YAAY,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,YAAY,QAAQ;AAAA,MACpB,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ;AAAA,MACpB,kBAAkB,QAAQ;AAAA,MAC1B,mBAAmB,QAAQ;AAAA,MAC3B,cAAc,QAAQ;AAAA,MACtB,gBAAgB,QAAQ;AAAA,MACxB,cAAc,QAAQ;AAAA,MACtB,YAAY,QAAQ;AAAA,MACpB,sBAAsB,QAAQ;AAAA,IAChC;AAGA,QAAI,kBAAkB;AACtB,QAAI,QAAQ,wBAAwB,OAAO,KAAK,QAAQ,oBAAoB,EAAE,SAAS,GAAG;AACxF,YAAM,YAAY,OAAO,QAAQ,QAAQ,oBAAoB,EAC1D,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,EAC5B,KAAK,IAAI;AACZ,wBAAkB,GAAG,OAAO;AAAA,eAAkB,SAAS;AAAA,IACzD;AAEA,UAAM,YAAY,sBAAsB,eAAe;AACvD,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,gCAAgC,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,IAC9F;AACA,UAAM,cAAc,GAAG,qBAAqB,EAAE,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA;AAEpE,QAAI;AACJ,QAAI,aAAa,cAAc;AAC7B,iBAAWA,MAAK,KAAK,KAAK,gBAAgB,GAAG,EAAE,KAAK;AAAA,IACtD,OAAO;AACL,iBAAWA,MAAK,KAAK,KAAK,UAAU,OAAO,GAAG,EAAE,KAAK;AAAA,IACvD;AAEA,UAAMG,WAAU,UAAU,aAAa,OAAO;AAC9C,SAAK,2BAA2B;AAChC,UAAM,KAAK,4CAA4C,uBAAuB;AAAA,MAC5E,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW,GAAG;AAAA,MACd,OAAO,QAAQ,SAAS;AAAA,MACxB,OAAO,KAAK,wBAAwB,IAAI,QAAQ;AAAA,MAChD,kBAAkB;AAAA,QAChB,GAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,QACjD,IAAK,QAAQ,WAAW,CAAC,GAAG,OAAO,OAAO;AAAA,MAC5C;AAAA,IACF,CAAC;AACD,QAAI,aAAa,QAAQ;AACvB,UAAI;AACF,cAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,sBAAc,IAAI,UAAU,IAAI;AAChC,cAAM,cAAc,KAAK;AAAA,MAC3B,SAAS,KAAK;AACZ,YAAI,KAAK,uEAAuE,GAAG,EAAE;AAAA,MACvF;AAAA,IACF;AACA,QAAI,MAAM,gBAAgB,EAAE,OAAO,QAAQ,EAAE;AAC7C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,mBAAmB,SAAmC;AAC1D,UAAM,KAAK,iCAAiC;AAC5C,UAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,UAAM,YAAY,sBAAsB,OAAO;AAC/C,WAAO,cAAc,IAAI,UAAU,IAAI;AAAA,EACzC;AAAA,EAEA,MAAM,iCAAmD;AACvD,UAAM,KAAK,iCAAiC;AAC5C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cACJ,OACA,UAUI,CAAC,GACY;AACjB,UAAM,KAAK,kBAAkB;AAC7B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,MAAM,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AACzC,UAAM,MAAMH,MAAK,KAAK,KAAK,cAAc,GAAG;AAC5C,UAAME,OAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAEpC,UAAM,KAAK,YAAY,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC3E,UAAM,KAAwB;AAAA,MAC5B;AAAA,MACA,UAAU;AAAA,MACV,SAAS,IAAI,YAAY;AAAA,MACzB,SAAS,IAAI,YAAY;AAAA,MACzB,QAAQ;AAAA,MACR,YAAY,QAAQ,cAAc;AAAA,MAClC,gBAAgB,eAAe,QAAQ,cAAc,GAAG;AAAA,MACxD,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,cAAc,QAAQ,gBAAgB;AAAA,MACtC,gBAAgB,QAAQ;AAAA,MACxB,cAAc,QAAQ;AAAA,MACtB,YAAY,QAAQ;AAAA,MACpB,kBAAkB,QAAQ;AAAA,MAC1B,mBAAmB,QAAQ;AAAA,IAC7B;AAEA,UAAM,YAAY,sBAAsB,KAAK;AAC7C,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,iCAAiC,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAC7F,aAAO;AAAA,IACT;AACA,UAAM,WAAWF,MAAK,KAAK,KAAK,GAAG,EAAE,KAAK;AAC1C,UAAMG,WAAU,UAAU,GAAG,qBAAqB,EAAE,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA,GAAM,OAAO;AACvF,UAAM,QACJ,OAAO,QAAQ,UAAU,YAAY,QAAQ,MAAM,SAAS,IACxD,QAAQ,QACR;AACN,UAAM,KAAK,4CAA4C,yBAAyB;AAAA,MAC9E,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW,GAAG;AAAA,MACd;AAAA,MACA,OAAO,KAAK,wBAAwB,IAAI,QAAQ;AAAA,MAChD,kBAAkB,QAAQ,iBAAiB,CAAC,QAAQ,cAAc,IAAI,CAAC;AAAA,IACzE,CAAC;AACD,SAAK,yBAAyB;AAG9B,SAAK,qBAAqB;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,yBAAgD;AAC5D,QACE,KAAK,sBACL,KAAK,IAAI,IAAI,KAAK,mBAAmB,cAAc,gBAAe,+BAClE,KAAK,mBAAmB,iBAAiB,KAAK,wBAAwB,GACtE;AACA,aAAO,KAAK,mBAAmB;AAAA,IACjC;AAEA,UAAM,gBAAgB,YAAmC;AACvD,YAAM,YAA0B,CAAC;AACjC,YAAM,UAAU,OAAO,QAAgB;AACrC,YAAI;AACF,gBAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,qBAAW,SAAS,SAAS;AAC3B,kBAAM,WAAWH,MAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,gBAAI,MAAM,YAAY,GAAG;AACvB,oBAAM,QAAQ,QAAQ;AACtB;AAAA,YACF;AACA,gBAAI,CAAC,MAAM,KAAK,SAAS,KAAK,EAAG;AACjC,kBAAM,SAAS,MAAM,KAAK,iBAAiB,QAAQ;AACnD,gBAAI,CAAC,OAAQ;AACb,sBAAU,KAAK,MAAM;AAAA,UACvB;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,YAAM,QAAQ,KAAK,YAAY;AAC/B,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB;AAC5B,QAAI,kBAAgC,CAAC;AACrC,aAAS,UAAU,GAAG,WAAW,qBAAqB,WAAW,GAAG;AAClE,YAAM,gBAAgB,KAAK,wBAAwB;AACnD,YAAM,YAAY,MAAM,cAAc;AACtC,YAAM,eAAe,KAAK,wBAAwB;AAClD,wBAAkB;AAClB,UAAI,iBAAiB,eAAe;AAClC,aAAK,qBAAqB,EAAE,UAAU,WAAW,YAAY,KAAK,IAAI,GAAG,cAAc,aAAa;AACpG,eAAO;AAAA,MACT;AAAA,IACF;AAIA,SAAK,qBAAqB;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,OAAe,YAA2C;AAC9E,UAAM,SAAS,2BAA2B,KAAK;AAC/C,QAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AAEjC,UAAM,YAAY,MAAM,KAAK,uBAAuB;AACpD,UAAM,OAAqD,CAAC;AAC5D,eAAW,UAAU,WAAW;AAC9B,YAAM,gBAAgB,IAAI;AAAA,QACxB,2BAA2B,GAAG,OAAO,OAAO,KAAK,OAAO,YAAY,QAAQ,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE;AAAA,MAC7F;AACA,YAAM,QAAQ,OAAO,OAAO,CAAC,KAAK,MAAM,OAAO,cAAc,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;AAC/E,UAAI,QAAQ,GAAG;AACb,aAAK,KAAK,EAAE,OAAO,OAAO,CAAC;AAAA,MAC7B;AAAA,IACF;AACA,SAAK,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACrC,WAAO,KAAK,MAAM,GAAG,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,EACtD;AAAA,EAEA,MAAM,YACJ,MACA,MACA,OACiB;AACjB,UAAM,KAAK,kBAAkB;AAC7B,QAAI,OAAO,SAAS,YAAY,CAAC,KAAK,KAAK,KAAK,OAAO,SAAS,YAAY,CAAC,KAAK,KAAK,GAAG;AACxF,UAAI,KAAK,iDAAiD;AAAA,QACxD,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,MACnB,CAAC;AACD,aAAO;AAAA,IACT;AACA,UAAM,YAAY,MAAM,QAAQ,KAAK,IAAI,MAAM,OAAO,CAAC,MAAM,OAAO,MAAM,QAAQ,IAAI,CAAC;AACvF,QAAI,aAAa,oBAAoB,MAAM,IAAI;AAG/C,UAAM,QAAQ,MAAM,KAAK,mBAAmB,MAAM,IAAI;AACtD,QAAI,SAAS,UAAU,YAAY;AACjC,UAAI,MAAM,iBAAiB,UAAU,sBAAiB,KAAK,GAAG;AAC9D,mBAAa;AAAA,IACf;AAEA,UAAM,WAAWA,MAAK,KAAK,KAAK,aAAa,GAAG,UAAU,KAAK;AAG/D,QAAI,SAAqB;AAAA,MACvB;AAAA,MAAM;AAAA,MAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC5C,OAAO,CAAC;AAAA,MAAG,SAAS;AAAA,MAAW,eAAe,CAAC;AAAA,MAAG,UAAU,CAAC;AAAA,MAAG,SAAS,CAAC;AAAA,IAC5E;AACA,QAAI;AACF,YAAM,WAAW,MAAMC,UAAS,UAAU,OAAO;AACjD,eAAS,gBAAgB,QAAQ;AAAA,IACnC,QAAQ;AAAA,IAER;AAGA,WAAO,QAAQ,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,OAAO,GAAG,SAAS,CAAC,CAAC;AAC3D,WAAO,OAAO;AACd,WAAO,OAAO;AACd,WAAO,WAAU,oBAAI,KAAK,GAAE,YAAY;AAExC,UAAME,WAAU,UAAU,oBAAoB,MAAM,GAAG,OAAO;AAC9D,SAAK,8BAA8B;AACnC,SAAK,wBAAwB;AAC7B,QAAI,MAAM,gBAAgB,UAAU,EAAE;AACtC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAA+B;AACnC,QAAI;AACF,aAAO,MAAMF,UAAS,KAAK,aAAa,OAAO;AAAA,IACjD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,SAAgC;AACjD,UAAM,KAAK,kBAAkB;AAC7B,UAAME,WAAU,KAAK,aAAa,SAAS,OAAO;AAClD,QAAI,MAAM,oBAAoB;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,kBAAkB,GAAmB;AAClD,QAAI,OAAO,MAAM,SAAU,QAAO;AAClC,WAAO,EACJ,YAAY,EACZ,QAAQ,gBAAgB,GAAG,EAC3B,QAAQ,QAAQ,GAAG,EACnB,KAAK;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAe,iBAAiB,SAAiB,eAAkC;AACjF,eAAW,YAAY,eAAe;AAEpC,UAAI,YAAY,SAAU,QAAO;AAGjC,YAAM,UAAU,QAAQ,UAAU,SAAS,SAAS,UAAU;AAC9D,YAAM,SAAS,QAAQ,SAAS,SAAS,SAAS,UAAU;AAC5D,UAAI,QAAQ,SAAS,MAAM,QAAQ,SAAS,OAAO,SAAS,OAAO,OAAO,SAAS,OAAO,GAAG;AAC3F,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,SAAkC;AAEtD,cAAU,QAAQ,OAAO,CAAC,MAAM,OAAO,MAAM,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC;AAC5E,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,WAAW,MAAM,KAAK,YAAY;AAExC,UAAM,QAAQ,WAAW,SAAS,MAAM,IAAI,IAAI,CAAC;AACjD,UAAM,oBAAoB,MACvB,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC,EAChC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC;AAC/B,UAAM,gBAAgB,kBAAkB,IAAI,gBAAe,iBAAiB;AAE5E,UAAM,aAAa,QAAQ,OAAO,CAAC,MAAM;AACvC,YAAM,OAAO,gBAAe,kBAAkB,CAAC;AAC/C,aAAO,CAAC,gBAAe,iBAAiB,MAAM,aAAa;AAAA,IAC7D,CAAC;AACD,QAAI,WAAW,WAAW,EAAG;AAE7B,QAAI,CAAC,UAAU;AACb,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,QACA,mBAAkB,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,QAC1C;AAAA,QACA,GAAG,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAAA,QACjC;AAAA,MACF,EAAE,KAAK,IAAI;AACX,YAAM,KAAK,aAAa,OAAO;AAAA,IACjC,OAAO;AACL,YAAM,mBAAmB,SAAS;AAAA,QAChC;AAAA,QACA,mBAAkB,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,MAC5C;AACA,YAAM,cAAc,iBAAiB,QAAQ,IAAI,OAAO,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI;AACrG,YAAM,KAAK,aAAa,WAAW;AAAA,IACrC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,0BAA0B,cAAyC;AACvE,UAAM,UAAU,MAAM,KAAK,YAAY;AACvC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,YAAY,QAAQ,MAAM,IAAI,EAAE;AACtC,UAAM,YAAY,OAAO,iBAAiB,WACtC,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,CAAC,IACpC,gBAAe;AACnB,WAAO,YAAY;AAAA,EACrB;AAAA,EAEA,MAAM,kBAAyC;AAG7C,UAAM,WAAW,gBAAe,oBAAoB,IAAI,KAAK,OAAO;AACpE,QAAI,SAAU,QAAO;AAErB,UAAM,cAAc,KAAK,yBAAyB;AAClD,oBAAe,oBAAoB,IAAI,KAAK,SAAS,WAAW;AAChE,QAAI;AACF,aAAO,MAAM;AAAA,IACf,UAAE;AAGA,UAAI,gBAAe,oBAAoB,IAAI,KAAK,OAAO,MAAM,aAAa;AACxE,wBAAe,oBAAoB,OAAO,KAAK,OAAO;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mCAAyC;AACvC,SAAK,2BAA2B;AAAA,EAClC;AAAA;AAAA;AAAA,EAIA,OAAO,uBAA6B;AAClC,oBAAe,oBAAoB,MAAM;AACzC,oBAAe,eAAe,MAAM;AAAA,EACtC;AAAA;AAAA;AAAA,EAIQ,6BAAmC;AACzC,oBAAe,oBAAoB,OAAO,KAAK,OAAO;AAAA,EACxD;AAAA,EAEA,MAAc,2BAAkD;AAI9D,UAAM,YAAsB,CAAC;AAE7B,UAAM,eAAe,OAAO,QAAgB;AAC1C,UAAI;AACF,cAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,cAAM,UAAoB,CAAC;AAC3B,mBAAW,SAAS,SAAS;AAC3B,gBAAM,WAAWH,MAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,cAAI,MAAM,YAAY,GAAG;AACvB,oBAAQ,KAAK,QAAQ;AAAA,UACvB,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG;AACrC,sBAAU,KAAK,QAAQ;AAAA,UACzB;AAAA,QACF;AAEA,mBAAW,UAAU,SAAS;AAC5B,gBAAM,aAAa,MAAM;AAAA,QAC3B;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,aAAa,KAAK,QAAQ;AAChC,UAAM,aAAa,KAAK,cAAc;AAEtC,QAAI,UAAU,WAAW,EAAG,QAAO,CAAC;AAGpC,UAAM,aAAa;AACnB,UAAM,WAAyB,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,YAAY;AACrD,YAAM,QAAQ,UAAU,MAAM,GAAG,IAAI,UAAU;AAC/C,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B,MAAM,IAAI,OAAO,aAAa;AAC5B,cAAI;AACF,kBAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,kBAAM,SAASH,kBAAiB,GAAG;AACnC,gBAAI,CAAC,OAAQ,QAAO;AACpB,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,aAAa;AAAA,gBACX,OAAO;AAAA,gBACP,gBAAgB,KAAK,SAAS,QAAQ;AAAA,cACxC;AAAA,cACA,SAAS,OAAO;AAAA,YAClB;AAAA,UACF,QAAQ;AACN,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AAAA,MACH;AACA,iBAAW,KAAK,SAAS;AACvB,YAAI,MAAM,KAAM,UAAS,KAAK,CAAC;AAAA,MACjC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,uBAA8C;AAClD,UAAM,WAAyB,CAAC;AAChC,UAAM,OAAO,KAAK;AAElB,UAAM,UAAU,OAAO,QAAgB;AACrC,UAAI;AACF,cAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,mBAAW,SAAS,SAAS;AAC3B,gBAAM,WAAWE,MAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,cAAI,MAAM,YAAY,GAAG;AACvB,kBAAM,QAAQ,QAAQ;AAAA,UACxB,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG;AACrC,gBAAI;AACF,oBAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,oBAAM,SAASH,kBAAiB,GAAG;AACnC,kBAAI,QAAQ;AACV,yBAAS,KAAK;AAAA,kBACZ,MAAM;AAAA,kBACN,aAAa;AAAA,oBACX,OAAO;AAAA,oBACP,gBAAgB,KAAK,SAAS,QAAQ;AAAA,kBACxC;AAAA,kBACA,SAAS,OAAO;AAAA,gBAClB,CAAC;AAAA,cACH;AAAA,YACF,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,iBAAiB,UAA8C;AACnE,QAAI;AACF,YAAM,MAAM,MAAMG,UAAS,UAAU,OAAO;AAC5C,YAAM,SAASH,kBAAiB,GAAG;AACnC,UAAI,QAAQ;AACV,eAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,YACX,OAAO;AAAA,YACP,gBAAgB,KAAK,SAAS,QAAQ;AAAA,UACxC;AAAA,UACA,SAAS,OAAO;AAAA,QAClB;AAAA,MACF;AAMA,YAAM,iBAAiB,SAAS,MAAME,MAAK,GAAG,EAAE,KAAK,GAAG;AACxD,UAAI,eAAe,SAAS,YAAY,KAAK,SAAS,SAAS,KAAK,GAAG;AACrE,cAAM,SAAS,gBAAgB,GAAG;AAClC,YAAI,CAAC,OAAO,KAAM,QAAO;AACzB,cAAM,iBAAiBA,MAAK,SAAS,UAAU,KAAK;AAOpD,cAAM,YAAY,OAAO,WACpB,MAAMI,MAAK,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,YAAY,CAAC,EAAE,MAAM,OAAM,oBAAI,KAAK,CAAC,GAAE,YAAY,CAAC;AAClG,eAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,YACX,IAAI;AAAA,YACJ,UAAU;AAAA,YACV,SAAS;AAAA,YACT,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,gBAAgB,eAAe,GAAG;AAAA,YAClC,MAAM,OAAO,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;AAAA,UACvC;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,mBAAmB,MAA8B;AACvD,WAAO,SAAS,SAASJ,MAAK,KAAK,KAAK,SAAS,MAAM,IAAI,KAAK;AAAA,EAClE;AAAA,EAEQ,qBAAqB,QAA4B;AACvD,UAAM,YAAY,OAAO,YAAY,WAAW,OAAO,YAAY;AACnE,UAAM,aAAa,aAAa,IAAI,MAAM,GAAG,EAAE;AAC/C,WAAO,sBAAsB,KAAK,SAAS,IACvC,aACA,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EAC1C;AAAA,EAEQ,iBAAiB,QAA6B;AACpD,QAAI,OAAO,YAAY,WAAW,WAAY,QAAO;AACrD,QAAI,OAAO,YAAY,iBAAiB,OAAW,QAAO;AAC1D,WAAO,sBAAsB,KAAK,OAAO,IAAI;AAAA,EAC/C;AAAA,EAEA,oBAAoB,QAAoB,MAA8B;AACpE,UAAM,OAAO,KAAK,mBAAmB,IAAI;AACzC,QAAI,KAAK,iBAAiB,MAAM,GAAG;AACjC,aAAOA,MAAK,KAAK,MAAM,aAAa,KAAK,qBAAqB,MAAM,GAAG,GAAG,OAAO,YAAY,EAAE,KAAK;AAAA,IACtG;AACA,QAAI,OAAO,YAAY,aAAa,cAAc;AAChD,aAAOA,MAAK,KAAK,MAAM,eAAe,GAAG,OAAO,YAAY,EAAE,KAAK;AAAA,IACrE;AACA,WAAOA,MAAK,KAAK,MAAM,SAAS,KAAK,qBAAqB,MAAM,GAAG,GAAG,OAAO,YAAY,EAAE,KAAK;AAAA,EAClG;AAAA,EAEA,MAAc,sBAAsB,YAAoB,QAAmC;AACzF,UAAM,cAAc,GAAG,qBAAqB,OAAO,WAAW,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AACpF,UAAME,OAAMF,MAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,UAAM,WAAW,GAAG,UAAU,QAAQ,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;AAC/D,QAAI;AACF,YAAMG,WAAU,UAAU,aAAa,OAAO;AAC9C,YAAM,OAAO,UAAU,UAAU;AACjC,WAAK,2BAA2B;AAAA,IAClC,SAAS,KAAK;AACZ,UAAI;AACF,cAAM,OAAO,QAAQ;AAAA,MACvB,QAAQ;AAAA,MAER;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,QAAoB,YAAmC;AAC5E,UAAM,KAAK,sBAAsB,YAAY,MAAM;AACnD,UAAM,aAAaH,MAAK,QAAQ,OAAO,IAAI;AAC3C,UAAM,WAAWA,MAAK,QAAQ,UAAU;AACxC,QAAI,eAAe,UAAU;AAC3B,UAAI;AACF,cAAM,OAAO,OAAO,IAAI;AAAA,MAC1B,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,YAAI,CAAC,QAAQ,SAAS,QAAQ,GAAG;AAC/B,gBAAM;AAAA,QACR;AAAA,MACF;AAIA,WAAK,2BAA2B;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,MAAM,oBACJ,QACA,YACmD;AACnD,UAAM,aAAa,KAAK,oBAAoB,QAAQ,UAAU;AAC9D,UAAM,aAAaA,MAAK,QAAQ,OAAO,IAAI;AAC3C,UAAM,WAAWA,MAAK,QAAQ,UAAU;AACxC,QAAI,eAAe,UAAU;AAC3B,aAAO,EAAE,SAAS,OAAO,WAAW;AAAA,IACtC;AAEA,UAAM,WAAW,MAAM,KAAK,iBAAiB,UAAU;AACvD,QAAI,UAAU,YAAY,OAAO,OAAO,YAAY,IAAI;AACtD,UAAI;AACF,cAAM,OAAO,OAAO,IAAI;AAAA,MAC1B,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,YAAI,CAAC,QAAQ,SAAS,QAAQ,GAAG;AAC/B,gBAAM;AAAA,QACR;AAAA,MACF;AACA,WAAK,wBAAwB;AAC7B,aAAO,EAAE,SAAS,OAAO,WAAW;AAAA,IACtC;AAEA,UAAM,KAAK,iBAAiB,QAAQ,UAAU;AAC9C,SAAK,2BAA2B;AAChC,SAAK,wBAAwB;AAC7B,WAAO,EAAE,SAAS,MAAM,WAAW;AAAA,EACrC;AAAA,EAEA,IAAY,aAAqB;AAC/B,WAAOA,MAAK,KAAK,KAAK,SAAS,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cACJ,QACA,WACwB;AACxB,QAAI;AACF,YAAM,MAAM,WAAW,MAAM,oBAAI,KAAK;AACtC,YAAM,QAAQ,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AAC3C,YAAM,UAAUA,MAAK,KAAK,KAAK,YAAY,KAAK;AAChD,YAAME,OAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAGxC,YAAM,YAA+B;AAAA,QACnC,GAAG,OAAO;AAAA,QACV,QAAQ;AAAA,QACR,YAAY,IAAI,YAAY;AAAA,QAC5B,SAAS,IAAI,YAAY;AAAA,MAC3B;AAEA,YAAM,cAAc,GAAG,qBAAqB,SAAS,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AAC3E,YAAM,WAAWF,MAAK,KAAK,SAASA,MAAK,SAAS,OAAO,IAAI,CAAC;AAG9D,YAAMG,WAAU,UAAU,aAAa,OAAO;AAC9C,YAAM,OAAO,OAAO,IAAI;AACxB,WAAK,2BAA2B;AAChC,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,UACE,UAAU,OAAO,YAAY;AAAA,UAC7B,WAAW;AAAA,UACX,WAAW,UAAU,cAAc,UAAU;AAAA,UAC7C,OAAO,WAAW,SAAS;AAAA,UAC3B,YAAY,WAAW;AAAA,UACvB,QAAQ,KAAK,wBAAwB,OAAO,aAAa,OAAO,IAAI;AAAA,UACpE,OAAO,KAAK,wBAAwB,WAAW,QAAQ;AAAA,UACvD,kBAAkB,WAAW;AAAA,UAC7B,eAAe,WAAW;AAAA,QAC5B;AAAA,QACA,WAAW;AAAA,MACb;AACA,WAAK,wBAAwB;AAE7B,UAAI,MAAM,mBAAmB,OAAO,YAAY,EAAE,WAAM,QAAQ,EAAE;AAClE,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,KAAK,4BAA4B,OAAO,YAAY,EAAE,KAAK,GAAG,EAAE;AACpE,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,eAAkC;AACtC,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK,WAAW;AAC9C,aAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,IACjF,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,MAA+B;AAC9C,QAAI;AACF,aAAO,MAAMF,UAASD,MAAK,KAAK,KAAK,aAAa,GAAG,IAAI,KAAK,GAAG,OAAO;AAAA,IAC1E,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,kBAAqC;AACzC,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK,WAAW;AAC9C,aAAO,QACJ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC,EAC/B,KAAK;AAAA,IACV,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,mBAAmB,cAAsB,MAAsC;AACnF,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,QAAI,SAAS,WAAW,EAAG,QAAO;AAElC,UAAM,aAAa,GAAG,KAAK,YAAY,CAAC;AAExC,UAAM,eAAe,oBAAoB,cAAc,IAAI;AAC3D,UAAM,mBAAmB,aAAa,WAAW,UAAU,IACvD,aAAa,MAAM,WAAW,MAAM,IACpC;AACJ,UAAM,iBAAiB,YAAY,gBAAgB;AAGnD,UAAM,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU,CAAC;AAEhE,eAAW,UAAU,UAAU;AAC7B,YAAM,iBAAiB,OAAO,MAAM,WAAW,MAAM;AACrD,YAAM,eAAe,YAAY,cAAc;AAG/C,UAAI,WAAW,aAAc,QAAO;AAGpC,UAAI,iBAAiB,eAAgB,QAAO;AAG5C,YAAM,UAAU,eAAe,UAAU,aAAa,SAAS,iBAAiB;AAChF,YAAM,SAAS,eAAe,SAAS,aAAa,SAAS,iBAAiB;AAC9E,UAAI,QAAQ,SAAS,KAAK,QAAQ,SAAS,OAAO,SAAS,OAAO,OAAO,SAAS,OAAO,GAAG;AAC1F,eAAO;AAAA,MACT;AAGA,UAAI,eAAe,UAAU,KAAK,aAAa,UAAU,GAAG;AAC1D,cAAM,OAAO,YAAY,gBAAgB,YAAY;AACrD,YAAI,QAAQ,EAAG,QAAO;AAAA,MACxB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,IAA8B;AACnD,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,EAAE;AAC3D,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI;AACF,YAAM,OAAO,OAAO,IAAI;AACxB,WAAK,2BAA2B;AAChC,WAAK,wBAAwB;AAC7B,UAAI,MAAM,sBAAsB,EAAE,EAAE;AACpC,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,IACA,YACA,SACkB;AAClB,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,EAAE;AAC3D,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,gBAAgB;AAAA,MACpB,GAAI,OAAO,YAAY,WAAW,CAAC;AAAA,MACnC,GAAI,SAAS,WAAW,CAAC;AAAA,IAC3B,EAAE,OAAO,CAAC,GAAG,GAAG,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;AAExC,UAAM,UAA6B;AAAA,MACjC,GAAG,OAAO;AAAA,MACV,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,MAChC,YAAY,SAAS,cAAc,OAAO,YAAY;AAAA,MACtD,SAAS,cAAc,SAAS,IAAI,gBAAgB;AAAA,IACtD;AACA,UAAM,YAAY,sBAAsB,UAAU;AAClD,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,wCAAwC,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,IACtG;AACA,UAAM,cAAc,GAAG,qBAAqB,OAAO,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA;AACzE,UAAMG,WAAU,OAAO,MAAM,aAAa,OAAO;AACjD,SAAK,2BAA2B;AAChC,UAAM,KAAK,4CAA4C,wBAAwB;AAAA,MAC7E,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW,QAAQ;AAAA,MACnB,OAAO,SAAS,SAAS;AAAA,MACzB,QAAQ,KAAK,wBAAwB,OAAO,aAAa,OAAO,IAAI;AAAA,MACpE,OAAO,KAAK,wBAAwB,SAAS,OAAO,IAAI;AAAA,MACxD,kBAAkB;AAAA,QAChB,GAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,QACjD,IAAK,QAAQ,WAAW,CAAC,GAAG,OAAO,OAAO;AAAA,MAC5C;AAAA,IACF,CAAC;AACD,QAAI,MAAM,kBAAkB,EAAE,EAAE;AAChC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,uBACJ,QACA,OACA,WACkB;AAClB,UAAM,eAAe,OAAO,YAAY,UAAU;AAClD,UAAM,UAA6B;AAAA,MACjC,GAAG,OAAO;AAAA,MACV,GAAG;AAAA,IACL;AACA,UAAM,cAAc,QAAQ,UAAU;AAEtC,UAAM,cAAc,GAAG,qBAAqB,OAAO,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AACzE,UAAMA,WAAU,OAAO,MAAM,aAAa,OAAO;AACjD,SAAK,2BAA2B;AAChC,UAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACE,UAAU,QAAQ;AAAA,QAClB,WAAW,KAAK,0BAA0B,OAAO,aAAa,OAAO;AAAA,QACrE,WAAW,QAAQ,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrD,OAAO,WAAW,SAAS;AAAA,QAC3B,YAAY,WAAW;AAAA,QACvB,QAAQ,KAAK,wBAAwB,OAAO,aAAa,OAAO,IAAI;AAAA,QACpE,OAAO,KAAK,wBAAwB,SAAS,OAAO,IAAI;AAAA,QACxD,kBAAkB;AAAA,UAChB,GAAI,WAAW,oBAAoB,CAAC;AAAA,UACpC,GAAI,QAAQ,eAAe,CAAC,QAAQ,YAAY,IAAI,CAAC;AAAA,UACrD,GAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,QACnD;AAAA,QACA,eAAe,WAAW;AAAA,MAC5B;AAAA,MACA,WAAW;AAAA,IACb;AACA,QAAI,iBAAiB,aAAa;AAChC,WAAK,wBAAwB;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,wBACJ,IACA,OACkB;AAClB,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,EAAE;AAC3D,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,KAAK,uBAAuB,QAAQ,KAAK;AAAA,EAClD;AAAA;AAAA,EAGA,MAAM,kBAAyC;AAC7C,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,UAAwB,CAAC;AAE/B,eAAW,KAAK,UAAU;AACxB,UAAI,CAAC,EAAE,YAAY,UAAW;AAC9B,YAAM,YAAY,IAAI,KAAK,EAAE,YAAY,SAAS,EAAE,QAAQ;AAC5D,UAAI,YAAY,KAAK;AACnB,YAAI;AACF,gBAAM,OAAO,EAAE,IAAI;AACnB,kBAAQ,KAAK,CAAC;AACd,cAAI,MAAM,0BAA0B,EAAE,YAAY,EAAE,gBAAgB;AAAA,QACtE,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,GAAG;AACtB,WAAK,2BAA2B;AAChC,WAAK,wBAAwB;AAAA,IAC/B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAmC;AACvC,UAAM,aAAaH,MAAK,KAAK,KAAK,UAAU,aAAa;AACzD,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,YAAY,OAAO;AAC9C,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,QAAQ;AACN,aAAO,EAAE,OAAO,CAAC,GAAG,kBAAkB,MAAM,iBAAiB,EAAE;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,OAAmC;AAClD,UAAM,KAAK,kBAAkB;AAC7B,UAAM,aAAaD,MAAK,KAAK,KAAK,UAAU,aAAa;AACzD,UAAMG,WAAU,YAAY,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AAAA,EACrE;AAAA,EAEA,MAAM,WAA+B;AACnC,UAAM,WAAWH,MAAK,KAAK,KAAK,UAAU,WAAW;AACrD,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,QAAQ;AACN,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,qBAAqB;AAAA,QACrB,eAAe;AAAA,QACf,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,OAAiC;AAC9C,UAAM,KAAK,kBAAkB;AAC7B,UAAM,WAAWD,MAAK,KAAK,KAAK,UAAU,WAAW;AACrD,UAAMG,WAAU,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AAAA,EACnE;AAAA,EAEA,MAAM,yBAAyB,QAA8C;AAC3E,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAE7B,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,UAAM,UAAU,OAAO,IAAI,CAAC,UAAU;AACpC,YAAM,aAAgC;AAAA,QACpC,GAAG;AAAA,QACH,WAAW,MAAM,aAAa,MAAM,UAAU,SAAS,IAAI,MAAM,YAAY;AAAA,MAC/E;AACA,aAAO,GAAG,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,IACtC,CAAC,EAAE,KAAK,EAAE;AAEV,UAAM,WAAW,KAAK,mBAAmB,SAAS,OAAO;AACzD,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,4BAA4B,QAAiD;AACjF,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAE7B,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,UAAM,UAAU,OAAO,IAAI,CAAC,UAAU;AACpC,YAAM,aAAmC;AAAA,QACvC,GAAG;AAAA,QACH,WAAW,MAAM,aAAa,MAAM,UAAU,SAAS,IAAI,MAAM,YAAY;AAAA,MAC/E;AACA,aAAO,GAAG,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,IACtC,CAAC,EAAE,KAAK,EAAE;AAEV,UAAM,WAAW,KAAK,2BAA2B,SAAS,OAAO;AACjE,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,sBAAsB,QAAgD;AAC1E,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAE7B,QAAI,eAAe,oBAAI,IAAY;AACnC,QAAI;AACF,YAAM,MAAM,MAAMF,UAAS,KAAK,qBAAqB,OAAO;AAC5D,YAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,iBAAW,QAAQ,OAAO;AACxB,cAAM,MAAM,KAAK,KAAK;AACtB,YAAI,CAAC,IAAK;AACV,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,cAAI,OAAO,OAAO,aAAa,YAAY,OAAO,OAAO,eAAe,UAAU;AAChF,yBAAa,IAAI,GAAG,OAAO,QAAQ,IAAI,OAAO,UAAU,EAAE;AAAA,UAC5D;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF,QAAQ;AACN,qBAAe,oBAAI,IAAY;AAAA,IACjC;AAEA,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,UAAM,UAAiC,CAAC;AACxC,eAAW,SAAS,QAAQ;AAC1B,YAAM,MAAM,GAAG,MAAM,QAAQ,IAAI,MAAM,UAAU;AACjD,UAAI,aAAa,IAAI,GAAG,EAAG;AAC3B,mBAAa,IAAI,GAAG;AACpB,cAAQ,KAAK;AAAA,QACX,GAAG;AAAA,QACH,WAAW,MAAM,aAAa,MAAM,UAAU,SAAS,IAAI,MAAM,YAAY;AAAA,MAC/E,CAAC;AAAA,IACH;AAEA,QAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,UAAM,UAAU,QAAQ,IAAI,CAAC,UAAU,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA,CAAI,EAAE,KAAK,EAAE;AAC5E,UAAM,WAAW,KAAK,qBAAqB,SAAS,OAAO;AAC3D,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,oBAAoB,QAAgD;AACxE,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAC7B,UAAM,WAAWD,MAAK,KAAK,KAAK,UAAU,sBAAsB;AAChE,UAAM,QAAQ,OAAO,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EAAE,KAAK,IAAI,IAAI;AACxE,QAAI;AACF,YAAM,WAAW,UAAU,OAAO,OAAO;AACzC,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,QAAgB,KAAqC;AAC3E,UAAM,YAAY,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,KAAK,MAAM,KAAK,CAAC,CAAC,IAAI;AAC5F,UAAM,WAAWA,MAAK,KAAK,KAAK,UAAU,sBAAsB;AAChE,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,YAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC;AACrE,YAAM,SAAgC,CAAC;AACvC,iBAAW,QAAQ,OAAO;AACxB,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cACE,OAAO,OAAO,aAAa,YAC3B,OAAO,SAAS,WAAW,KAC3B,OAAO,OAAO,UAAU,YACxB,OAAO,MAAM,WAAW,KACxB,OAAO,OAAO,gBAAgB,YAC9B,OAAO,YAAY,WAAW,KAC9B,OAAO,WAAW,eAClB;AACA;AAAA,UACF;AACA,iBAAO,KAAK;AAAA,YACV,UAAU,OAAO;AAAA,YACjB,OAAO,OAAO;AAAA,YACd,aAAa,OAAO;AAAA,YACpB,QAAQ;AAAA,UACV,CAAC;AAAA,QACH,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AACA,aAAO,OAAO,MAAM,CAAC,SAAS;AAAA,IAChC,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,QAAgB,KAAqC;AAC7E,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACjD,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAE/B,QAAI;AACF,YAAM,MAAM,MAAMA,UAAS,KAAK,qBAAqB,OAAO;AAC5D,YAAM,MAA6B,CAAC;AACpC,YAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,eAAS,IAAI,MAAM,SAAS,GAAG,KAAK,KAAK,IAAI,SAAS,aAAa,KAAK,GAAG;AACzE,cAAM,MAAM,MAAM,CAAC,GAAG,KAAK;AAC3B,YAAI,CAAC,IAAK;AACV,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,cACE,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,aAAa,YAC3B,OAAO,OAAO,aAAa,YAC3B,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,WAAW,UACzB;AACA,gBAAI,KAAK,MAA6B;AAAA,UACxC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,aAAO,IAAI,QAAQ;AAAA,IACrB,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,QAAgB,KAAmC;AAC9E,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACjD,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAE/B,QAAI;AACF,YAAM,MAAM,MAAMA,UAAS,KAAK,mBAAmB,OAAO;AAC1D,YAAM,MAA2B,CAAC;AAClC,YAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,eAAS,IAAI,MAAM,SAAS,GAAG,KAAK,KAAK,IAAI,SAAS,aAAa,KAAK,GAAG;AACzE,cAAM,OAAO,MAAM,CAAC,GAAG,KAAK;AAC5B,YAAI,CAAC,KAAM;AACX,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cACE,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,WAAW,YACzB,OAAO,OAAO,YAAY,UAC1B;AACA,gBAAI,KAAK,MAA2B;AAAA,UACtC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,aAAO,IAAI,QAAQ;AAAA,IACrB,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,+BAAgE;AACpE,QAAI;AACF,YAAM,MAAM,MAAMA,UAAS,KAAK,2BAA2B,OAAO;AAClE,YAAM,MAA8B,CAAC;AACrC,YAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,iBAAW,QAAQ,OAAO;AACxB,cAAM,MAAM,KAAK,KAAK;AACtB,YAAI,CAAC,IAAK;AACV,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,cACE,OAAO,OAAO,YAAY,YAC1B,OAAO,OAAO,aAAa,YAC3B,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,UAAU,YACxB,OAAO,OAAO,gBAAgB,UAC9B;AACA,gBAAI,KAAK,MAA8B;AAAA,UACzC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,aAAO,0BAA0B,GAAG;AAAA,IACtC,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,0BAA0B,QAAgB,KAAsC;AACpF,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACjD,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAC/B,UAAM,SAAS,MAAM,KAAK,6BAA6B;AACvD,WAAO,OAAO,MAAM,CAAC,WAAW;AAAA,EAClC;AAAA,EAEA,MAAM,2BAA2B,SAAgC;AAC/D,UAAM,KAAK,kBAAkB;AAC7B,UAAME,WAAU,KAAK,2BAA2B,SAAS,OAAO;AAAA,EAClE;AAAA,EAEA,MAAM,4BAAoD;AACxD,QAAI;AACF,aAAO,MAAMF,UAAS,KAAK,2BAA2B,OAAO;AAAA,IAC/D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,+BAA+B,SAAgC;AACnE,UAAM,KAAK,kBAAkB;AAC7B,UAAME,WAAU,KAAK,+BAA+B,SAAS,OAAO;AAAA,EACtE;AAAA,EAEA,MAAM,gCAAwD;AAC5D,QAAI;AACF,aAAO,MAAMF,UAAS,KAAK,+BAA+B,OAAO;AAAA,IACnE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,wCACJ,OACe;AACf,UAAM,KAAK,kBAAkB;AAC7B,UAAME,WAAU,KAAK,+BAA+B,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM,OAAO;AAAA,EACpG;AAAA,EAEA,MAAM,oCACJ,OACe;AACf,UAAM,KAAK,kBAAkB;AAC7B,UAAMA,WAAU,KAAK,oCAAoC,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM,OAAO;AAAA,EACzG;AAAA,EAEA,MAAM,yCAA6F;AACjG,WAAO,KAAK,kCAAkC,KAAK,6BAA6B;AAAA,EAClF;AAAA,EAEA,MAAM,qCAAyF;AAC7F,WAAO,KAAK,kCAAkC,KAAK,kCAAkC;AAAA,EACvF;AAAA,EAEA,MAAM,kCAAkC,SAGnB;AACnB,UAAM,CAAC,cAAc,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,MACnD,KAAK,8BAA8B;AAAA,MACnC,KAAK,mCAAmC;AAAA,IAC1C,CAAC;AACD,QAAI,CAAC,gBAAgB,CAAC,WAAY,QAAO;AACzC,QACE,OAAO,SAAS,wBAAwB,YACxC,QAAQ,oBAAoB,SAAS,KACrC,WAAW,gBAAgB,QAAQ,qBACnC;AACA,aAAO;AAAA,IACT;AACA,QACE,OAAO,SAAS,6BAA6B,YAC7C,OAAO,SAAS,QAAQ,wBAAwB,KAChD,WAAW,qBAAqB,QAAQ,0BACxC;AACA,aAAO;AAAA,IACT;AACA,QAAI,WAAW,aAAa;AAC1B,YAAM,cAAc,WAAW,QAAQ,EAAE,OAAO,YAAY,EAAE,OAAO,KAAK;AAC1E,UAAI,gBAAgB,WAAW,YAAa,QAAO;AAAA,IACrD;AAEA,UAAM,KAAK,2BAA2B,YAAY;AAClD,UAAM,KAAK,wCAAwC;AAAA,MACjD,GAAG;AAAA,MACH,iBAAiB;AAAA,IACnB,CAAC;AACD,UAAM,QAAQ,IAAI;AAAA,MAChB,OAAO,KAAK,6BAA6B,EAAE,MAAM,MAAM,MAAS;AAAA,MAChE,OAAO,KAAK,kCAAkC,EAAE,MAAM,MAAM,MAAS;AAAA,IACvE,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,kCACZ,UACoD;AACpD,UAAM,6BAA6B,CAAC,UAClC,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,OAAO,UAAU,KAAK,KAAK,SAAS;AAC7F,UAAM,uBAAuB,CAC3B,UACwF;AACxF,UAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,YAAM,UAAU;AAChB,aACE,OAAO,QAAQ,WAAW,YAC1B,2BAA2B,QAAQ,KAAK,KACxC,QAAQ,aAAa,QACrB,OAAO,QAAQ,aAAa,YAC5B,2BAA2B,QAAQ,SAAS,OAAO,KACnD,2BAA2B,QAAQ,SAAS,OAAO,KACnD,2BAA2B,QAAQ,SAAS,MAAM,KAClD,QAAQ,YAAY,QACpB,OAAO,QAAQ,YAAY,YAC3B,2BAA2B,QAAQ,QAAQ,IAAI,KAC/C,2BAA2B,QAAQ,QAAQ,IAAI,KAC/C,2BAA2B,QAAQ,QAAQ,OAAO;AAAA,IAEtD;AACA,UAAM,oBAAoB,CACxB,UACoF;AACpF,UAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,YAAM,OAAO;AACb,aACE,OAAO,KAAK,WAAW,YACvB,OAAO,KAAK,UAAU,YACtB,OAAO,SAAS,KAAK,KAAK,MACzB,KAAK,cAAc,cAAc,KAAK,cAAc,cAAc,KAAK,cAAc,YACrF,KAAK,eAAe,SAAS,KAAK,eAAe,YAAY,KAAK,eAAe,WAClF,MAAM,QAAQ,KAAK,KAAK,KACxB,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ;AAAA,IAEvD;AAEA,QAAI;AACF,YAAM,MAAM,MAAMF,UAAS,UAAU,OAAO;AAC5C,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,YAAM,eAAe,QAAQ;AAC7B,YAAM,cAAc,QAAQ;AAC5B,YAAM,kBACJ,QAAQ,oBAAoB,WAAW,QAAQ,oBAAoB,WAC/D,OAAO,kBACP;AACN,YAAM,cACJ,OAAO,QAAQ,gBAAgB,YAAY,OAAO,YAAY,SAAS,IACnE,OAAO,cACP;AACN,YAAM,kBAAkB,MAAM,QAAQ,QAAQ,eAAe,IACzD,OAAO,gBAAgB,OAAO,oBAAoB,IAClD;AACJ,YAAM,cAAc,MAAM,QAAQ,QAAQ,WAAW,IACjD,OAAO,YAAY,OAAO,iBAAiB,IAC3C;AACJ,UACE,CAAC,2BAA2B,QAAQ,OAAO,KAC3C,OAAO,QAAQ,cAAc,YAC7B,OAAO,UAAU,WAAW,KAC5B,CAAC,gBACD,OAAO,aAAa,SAAS,YAC7B,aAAa,KAAK,WAAW,KAC7B,OAAO,aAAa,OAAO,YAC3B,aAAa,GAAG,WAAW,KAC3B,CAAC,eACD,CAAC,2BAA2B,YAAY,KAAK,KAC7C,CAAC,2BAA2B,YAAY,OAAO,KAC/C,CAAC,2BAA2B,YAAY,OAAO,KAC/C,CAAC,2BAA2B,YAAY,MAAM,KAC9C,CAAC,2BAA2B,QAAQ,gBAAgB,GACpD;AACA,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,SAAS,OAAO;AAAA,QAChB,WAAW,OAAO;AAAA,QAClB,cAAc;AAAA,UACZ,MAAM,aAAa;AAAA,UACnB,IAAI,aAAa;AAAA,QACnB;AAAA,QACA,aAAa;AAAA,UACX,OAAO,YAAY;AAAA,UACnB,SAAS,YAAY;AAAA,UACrB,SAAS,YAAY;AAAA,UACrB,QAAQ,YAAY;AAAA,QACtB;AAAA,QACA,kBAAkB,OAAO;AAAA,QACzB,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,QACrC,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,QAC7C,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,QAC7C,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,MACvC;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,SAAgC;AACxD,UAAM,KAAK,kBAAkB;AAC7B,UAAME,WAAU,KAAK,oBAAoB,SAAS,OAAO;AAAA,EAC3D;AAAA,EAEA,MAAM,qBAA6C;AACjD,QAAI;AACF,aAAO,MAAMF,UAAS,KAAK,oBAAoB,OAAO;AAAA,IACxD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,yBAAyB,OAAuE;AACpG,UAAM,KAAK,kBAAkB;AAC7B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,OAAO,OAAO,MAAM,GAAG,EAAE;AAC/B,UAAM,KAAK,KAAK,WAAW,UAAU;AACrC,UAAM,WAAW,+BAA+B,IAAI,OAAO,MAAM;AACjE,UAAM,WAAWD,MAAK,KAAK,KAAK,sBAAsB,GAAG,IAAI,IAAI,EAAE,KAAK;AACxE,UAAMG,WAAU,UAAU,4BAA4B,QAAQ,GAAG,OAAO;AACxE,WAAO,EAAE,GAAG,UAAU,SAAS;AAAA,EACjC;AAAA,EAEA,MAAM,wBACJ,QAAgB,KAChB,QAAmC,OACE;AACrC,UAAM,kBAAkB,OAAO,SAAS,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI;AACrE,UAAM,cAAc,KAAK,IAAI,GAAG,eAAe;AAC/C,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAE/B,QAAI;AACF,YAAM,aAAa,MAAM,KAAK,gCAAgC;AAC9D,YAAM,YAAwC,CAAC;AAE/C,iBAAW,QAAQ,YAAY;AAC7B,YAAI,UAAU,UAAU,YAAa;AACrC,cAAM,WAAWH,MAAK,KAAK,KAAK,sBAAsB,IAAI;AAC1D,YAAI;AACF,gBAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,gBAAM,SAAS,wBAAwB,GAAG;AAC1C,cAAI,CAAC,OAAQ;AACb,cAAI,UAAU,SAAS,OAAO,UAAU,MAAO;AAC/C,oBAAU,KAAK,EAAE,GAAG,QAAQ,SAAS,CAAC;AAAA,QACxC,QAAQ;AAAA,QAER;AAAA,MACF;AACA,aAAO;AAAA,IACT,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,wBACJ,IACA,SAC0C;AAC1C,UAAM,iBAAiB,MAAM,KAAK,mCAAmC,EAAE;AACvE,UAAM,SAAS,iBAAiB,MAAM,KAAK,2BAA2B,cAAc,IAAI;AACxF,QAAI,CAAC,UAAU,CAAC,eAAgB,QAAO;AACvC,QAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,UAAM,SAAS,8BAA8B,QAAQ,UAAS,oBAAI,KAAK,GAAE,YAAY,CAAC;AACtF,UAAME,WAAU,gBAAgB,4BAA4B,MAAM,GAAG,OAAO;AAC5E,WAAO,EAAE,GAAG,QAAQ,UAAU,eAAe;AAAA,EAC/C;AAAA,EAEA,MAAM,mBAAmB,QAA8B,KAAa,SAAkC;AACpG,UAAM,KAAK,kBAAkB;AAC7B,UAAM,UAAU,KAAK,yBAAyB,GAAG;AACjD,UAAM,MAAM,WAAW,WAAW,KAAK,0BAA0B,KAAK;AACtE,UAAM,WAAWH,MAAK,KAAK,KAAK,GAAG,OAAO,KAAK;AAC/C,UAAMG,WAAU,UAAU,SAAS,OAAO;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,QAA8B,KAAqC;AACzF,QAAI;AACF,YAAM,UAAU,KAAK,yBAAyB,GAAG;AACjD,YAAM,MAAM,WAAW,WAAW,KAAK,0BAA0B,KAAK;AACtE,aAAO,MAAMF,UAASD,MAAK,KAAK,KAAK,GAAG,OAAO,KAAK,GAAG,OAAO;AAAA,IAChE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,8BAA8B,SAAgC;AAClE,UAAM,KAAK,kBAAkB;AAC7B,UAAMG,WAAU,KAAK,8BAA8B,SAAS,OAAO;AAAA,EACrE;AAAA,EAEA,MAAM,+BAAuD;AAC3D,QAAI;AACF,aAAO,MAAMF,UAAS,KAAK,8BAA8B,OAAO;AAAA,IAClE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,sCAA4E;AAChF,UAAM,MAAM,MAAM,KAAK,6BAA6B;AACpD,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,WAAO,gCAAgC,GAAG;AAAA,EAC5C;AAAA,EAEA,MAAM,8BAA8B,OAAsE;AACxG,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,UAAM,MAAM,MAAM,KAAK,6BAA6B;AACpD,UAAM,EAAE,UAAU,KAAK,IAAI,+BAA+B,KAAK,OAAO,MAAM;AAC5E,UAAM,KAAK,8BAA8B,QAAQ;AACjD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,8BACJ,IACA,OAC2C;AAC3C,UAAM,MAAM,MAAM,KAAK,6BAA6B;AACpD,UAAM,EAAE,UAAU,KAAK,IAAI,+BAA+B,KAAK,IAAI,QAAO,oBAAI,KAAK,GAAE,YAAY,CAAC;AAClG,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,KAAK,8BAA8B,QAAQ;AACjD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMQ,WAAW,SAAiB,KAAa;AAC/C,UAAM,KAAK,KAAK,IAAI,EAAE,SAAS,EAAE;AACjC,UAAM,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC;AAClD,WAAO,GAAG,MAAM,IAAI,EAAE,IAAI,IAAI;AAAA,EAChC;AAAA,EAEA,MAAc,kCAAqD;AACjE,UAAM,QAAQ,MAAM,QAAQ,KAAK,oBAAoB;AACrD,WAAO,MACJ,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK,CAAC,EACrC,KAAK,EACL,QAAQ;AAAA,EACb;AAAA,EAEA,MAAc,2BAA2B,UAA4D;AACnG,QAAI;AACF,YAAM,MAAM,MAAMA,UAAS,UAAU,OAAO;AAC5C,YAAM,SAAS,wBAAwB,GAAG;AAC1C,aAAO,SAAS,EAAE,GAAG,QAAQ,SAAS,IAAI;AAAA,IAC5C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,mCAAmC,IAAoC;AACnF,UAAM,YAAY,MAAM,KAAK,gCAAgC;AAC7D,UAAM,cAAc,UAAU,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,KAAK,CAAC;AACvE,QAAI,aAAa;AACf,YAAM,aAAaD,MAAK,KAAK,KAAK,sBAAsB,WAAW;AACnE,YAAM,SAAS,MAAM,KAAK,2BAA2B,UAAU;AAC/D,UAAI,QAAQ,OAAO,GAAI,QAAO;AAAA,IAChC;AAEA,eAAW,YAAY,WAAW;AAChC,YAAM,WAAWA,MAAK,KAAK,KAAK,sBAAsB,QAAQ;AAC9D,YAAM,SAAS,MAAM,KAAK,2BAA2B,QAAQ;AAC7D,UAAI,QAAQ,OAAO,GAAI,QAAO;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,yBAAyB,KAAqB;AACpD,UAAM,UAAU,IAAI,KAAK;AACzB,QAAI,CAAC,+BAA+B,KAAK,OAAO,KAAK,QAAQ,SAAS,IAAI,GAAG;AAC3E,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cACJ,UACA,SACA,UACiB;AACjB,UAAME,OAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAElD,UAAM,KAAK,KAAK,WAAW,GAAG;AAC9B,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,MAChC;AAAA,MACA,UAAU;AAAA,IACZ;AAEA,UAAM,UAAU;AAAA,EAAQ,OAAO,QAAQ,WAAW,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,EAAY,QAAQ;AAAA;AAAA,eAAoB,OAAO;AAAA;AAE3J,UAAM,WAAWF,MAAK,KAAK,KAAK,cAAc,GAAG,EAAE,KAAK;AACxD,UAAMG,WAAU,UAAU,SAAS,OAAO;AAE1C,QAAI,MAAM,kBAAkB,EAAE,OAAO,QAAQ,EAAE;AAC/C,SAAK,yBAAyB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cACJ,MAWA;AACA,UAAM,WAAW,KAAK;AACtB,UAAM,SAAS,gBAAe,eAAe,IAAI,QAAQ;AACzD,QAAI,UAAU,KAAK,IAAI,IAAI,OAAO,WAAW,gBAAe,wBAAwB;AAGlF,UAAI;AACF,cAAM,UAAU,MAAMC,MAAK,KAAK,YAAY;AAC5C,YAAI,QAAQ,WAAW,OAAO,UAAU;AACtC,gBAAM,MAAM,OAAO;AACnB,iBAAO,MAAM,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,IAAI;AAAA,QACjE;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAQ,MAAM,QAAQ,KAAK,YAAY;AAC7C,YAAM,YAAY,CAAC;AACnB,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,SAAS,KAAK,EAAG;AAC3B,cAAM,WAAWJ,MAAK,KAAK,KAAK,cAAc,IAAI;AAClD,cAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,cAAM,SAAS,KAAK,kBAAkB,KAAK,QAAQ;AACnD,YAAI,QAAQ;AACV,oBAAU,KAAK,MAAM;AAAA,QACvB;AAAA,MACF;AACA,YAAM,SAAS,UAAU,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAC/D,sBAAe,eAAe,IAAI,UAAU,EAAE,WAAW,QAAQ,UAAU,KAAK,IAAI,EAAE,CAAC;AACvF,aAAO,MAAM,iBAAiB,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,IAAI;AAAA,IACpE,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA,EAGA,2BAAiC;AAC/B,oBAAe,eAAe,OAAO,KAAK,YAAY;AAAA,EACxD;AAAA,EAEQ,kBACN,KACA,UASO;AACP,UAAM,QAAQ,IAAI,MAAM,qCAAqC;AAC7D,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,iBAAiB,MAAM,CAAC;AAC9B,UAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAG3B,UAAM,KACJ,KAAK,wBAAwB,gBAAgB,IAAI,KACjDD,MAAK,SAAS,UAAU,KAAK;AAC/B,UAAM,UACJ,KAAK,wBAAwB,gBAAgB,SAAS,KAAK;AAC7D,UAAM,WAAW;AAAA,MACf,KAAK,wBAAwB,gBAAgB,UAAU,KAAK;AAAA,IAC9D;AACA,UAAM,WACJ,KAAK,wBAAwB,gBAAgB,UAAU,MAAM;AAG/D,UAAM,eAAe,KAAK,MAAM,yBAAyB;AACzD,UAAM,WAAW,eACb,KAAK,MAAM,GAAG,aAAa,KAAK,EAAE,KAAK,IACvC;AACJ,UAAM,UAAU,eAAe,aAAa,CAAC,EAAE,KAAK,IAAI;AAExD,WAAO,EAAE,IAAI,UAAU,SAAS,UAAU,UAAU,SAAS,SAAS;AAAA,EACxE;AAAA,EAEQ,wBACN,aACA,KACe;AACf,UAAM,QAAQ,YAAY;AAAA,MACxB,IAAI,OAAO,IAAI,GAAG,uBAAuB,GAAG;AAAA,IAC9C;AACA,WAAO,QAAQ,MAAM,CAAC,IAAI;AAAA,EAC5B;AAAA,EAEA,MAAM,gBAAgB,IAA8B;AAClD,UAAM,YAAY,MAAM,KAAK,cAAc;AAC3C,UAAM,IAAI,UAAU,KAAK,CAACK,OAAMA,GAAE,OAAO,EAAE;AAC3C,QAAI,CAAC,EAAG,QAAO;AAEf,QAAI,MAAM,MAAMJ,UAAS,EAAE,UAAU,OAAO;AAC5C,UAAM,IAAI,QAAQ,mBAAmB,gBAAgB;AACrD,UAAM,IAAI;AAAA,MACR;AAAA,MACA,iBAAgB,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA,IAC1C;AACA,UAAME,WAAU,EAAE,UAAU,KAAK,OAAO;AACxC,QAAI,MAAM,qBAAqB,EAAE,EAAE;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,cAAsB,WAAqC;AAC5E,UAAM,eAAe,KAAK,iBAAiB,cAAc,SAAS;AAClE,QAAI;AACF,aAAO,MAAMF,UAAS,cAAc,OAAO;AAAA,IAC7C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,cAAsB,SAAiB,WAAmC;AAC5F,UAAM,eAAe,KAAK,iBAAiB,cAAc,SAAS;AAClE,UAAME,WAAU,cAAc,SAAS,OAAO;AAC9C,QAAI,MAAM,mCAAmC,QAAQ,MAAM,SAAS;AAAA,EACtE;AAAA;AAAA,EAGA,OAAwB,qBAAqB;AAAA;AAAA,EAE7C,OAAwB,yBAAyB,KAAK,KAAK;AAAA,EAE3D,MAAM,iBACJ,cACA,YACA,MACe;AACf,UAAM,eAAe,KAAK,iBAAiB,cAAc,MAAM,SAAS;AAExE,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAMF,UAAS,cAAc,OAAO;AAAA,IACjD,QAAQ;AAAA,IAER;AAEA,UAAM,UAAU,MAAM;AACtB,UAAM,gBACJ,SAAS,YAAY,QACrB,QAAQ,kBAAkB,QAC1B,MAAM,QAAQ,QAAQ,WAAW,KACjC,QAAQ,YAAY,SAASD,MAAK,SAAS,YAAY,CAAC;AAG1D,QAAI,eAAe;AACjB,YAAM,WAAW,QAAQ;AACzB,UAAI,SAAS,SAAS,UAAU;AAC9B,cAAM,aAAaA,MAAK,KAAK,cAAc,QAAQ,UAAU;AAC7D,cAAM,EAAE,WAAW,IAAI,MAAM,4BAA4B;AAAA,UACvD,UAAU;AAAA,UACV;AAAA,UACA,eAAe;AAAA,UACf,eAAe,QAAQ;AAAA,QACzB,CAAC;AACD,cAAMG,WAAU,cAAc,YAAY,OAAO;AACjD,mBAAW;AACX,YAAI;AAAA,UACF,wCAAwC,SAAS,MAAM,oBAAoB,QAAQ;AAAA,QACrF;AAAA,MACF;AAAA,IACF,OAAO;AAEL,UAAI,SAAS,SAAS,gBAAe,oBAAoB;AACvD,YAAI,MAAM,kBAAkB,SAAS,MAAM,iBAAiB,gBAAe,kBAAkB,wBAAwB;AACrH;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,SAAS,MAAM,4BAA4B;AAC7D,QAAI,WAAW;AAEb,YAAM,aAAa,CAAC,GAAG,SAAS,SAAS,wBAAwB,CAAC;AAClE,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,gBAAgB,WAAW,WAAW,SAAS,CAAC,EAAE,CAAC;AACzD,cAAM,UAAU,KAAK,IAAI,IAAI,IAAI,KAAK,aAAa,EAAE,QAAQ;AAC7D,YAAI,UAAU,gBAAe,wBAAwB;AACnD,cAAI,MAAM,wBAAwB,KAAK,MAAM,UAAU,GAAI,CAAC,sBAAsB,gBAAe,yBAAyB,GAAI,IAAI;AAClI;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,UAAU;AAAA;AAAA,uBAAuB,SAAS;AAAA;AAAA,EAAO,UAAU;AAAA;AAEjE,UAAMA,WAAU,cAAc,WAAW,SAAS,OAAO;AACzD,QAAI,MAAM,0BAA0B,YAAY,EAAE;AAAA,EACpD;AAAA,EAEA,MAAM,0BAAkD;AACtD,QAAI;AACF,aAAO,MAAMF,UAAS,KAAK,yBAAyB,OAAO;AAAA,IAC7D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,yBAAyB,SAAgC;AAC7D,UAAMC,OAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAMC,WAAU,KAAK,yBAAyB,SAAS,OAAO;AAAA,EAChE;AAAA,EAEA,MAAM,yBAAyB,YAAmC;AAChE,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAMF,UAAS,KAAK,yBAAyB,OAAO;AAAA,IACjE,QAAQ;AAAA,IAER;AAEA,QAAI,SAAS,SAAS,gBAAe,oBAAoB;AACvD,UAAI;AAAA,QACF,8BAA8B,SAAS,MAAM,iBAAiB,gBAAe,kBAAkB;AAAA,MACjG;AACA;AAAA,IACF;AAEA,UAAM,aAAa,CAAC,GAAG,SAAS,SAAS,wBAAwB,CAAC;AAClE,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,gBAAgB,WAAW,WAAW,SAAS,CAAC,EAAE,CAAC;AACzD,YAAM,UAAU,KAAK,IAAI,IAAI,IAAI,KAAK,aAAa,EAAE,QAAQ;AAC7D,UAAI,UAAU,gBAAe,wBAAwB;AACnD,YAAI;AAAA,UACF,wBAAwB,KAAK,MAAM,UAAU,GAAI,CAAC,sBAAsB,gBAAe,yBAAyB,GAAI;AAAA,QACtH;AACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,UAAU,GAAG,SAAS,QAAQ,EAAE,SAAS,IAAI,SAAS,EAAE,wBAAmB,SAAS;AAAA;AAAA,EAAO,UAAU;AAAA;AAC3G,UAAMC,OAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAMC,WAAU,KAAK,yBAAyB,GAAG,SAAS,QAAQ,CAAC,GAAG,OAAO,IAAI,OAAO;AACxF,QAAI,MAAM,0CAA0C,KAAK,uBAAuB,EAAE;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,sBAAsB,MAAc,KAAwC;AAChF,UAAM,WAAWH,MAAK,KAAK,KAAK,aAAa,GAAG,IAAI,KAAK;AACzD,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,MAAMC,UAAS,UAAU,OAAO;AAChD,eAAS,gBAAgB,OAAO;AAAA,IAClC,QAAQ;AACN,UAAI,MAAM,sCAAsC,IAAI,eAAe;AACnE;AAAA,IACF;AAGA,UAAM,SAAS,OAAO,cAAc;AAAA,MAClC,CAAC,MAAM,EAAE,WAAW,IAAI,UAAU,EAAE,UAAU,IAAI;AAAA,IACpD;AACA,QAAI,OAAQ;AAEZ,WAAO,cAAc,KAAK,GAAG;AAC7B,WAAO,WAAU,oBAAI,KAAK,GAAE,YAAY;AACxC,UAAME,WAAU,UAAU,oBAAoB,MAAM,GAAG,OAAO;AAC9D,SAAK,8BAA8B;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBACJ,MACA,OACA,YACe;AACf,UAAM,WAAWH,MAAK,KAAK,KAAK,aAAa,GAAG,IAAI,KAAK;AACzD,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,MAAMC,UAAS,UAAU,OAAO;AAChD,eAAS,gBAAgB,OAAO;AAAA,IAClC,QAAQ;AACN,UAAI,MAAM,kCAAkC,IAAI,eAAe;AAC/D;AAAA,IACF;AAEA,WAAO,SAAS,QAAQ,KAAK;AAC7B,QAAI,OAAO,SAAS,SAAS,YAAY;AACvC,aAAO,WAAW,OAAO,SAAS,MAAM,GAAG,UAAU;AAAA,IACvD;AACA,WAAO,WAAU,oBAAI,KAAK,GAAE,YAAY;AACxC,UAAME,WAAU,UAAU,oBAAoB,MAAM,GAAG,OAAO;AAC9D,SAAK,8BAA8B;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,MAAc,OAA8B;AAC/D,UAAM,WAAWH,MAAK,KAAK,KAAK,aAAa,GAAG,IAAI,KAAK;AACzD,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,MAAMC,UAAS,UAAU,OAAO;AAChD,eAAS,gBAAgB,OAAO;AAAA,IAClC,QAAQ;AACN,UAAI,MAAM,+BAA+B,IAAI,eAAe;AAC5D;AAAA,IACF;AAEA,QAAI,OAAO,QAAQ,SAAS,KAAK,EAAG;AACpC,WAAO,QAAQ,KAAK,KAAK;AACzB,WAAO,WAAU,oBAAI,KAAK,GAAE,YAAY;AACxC,UAAME,WAAU,UAAU,oBAAoB,MAAM,GAAG,OAAO;AAC9D,SAAK,8BAA8B;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,MAAc,SAAgC;AACtE,UAAM,WAAWH,MAAK,KAAK,KAAK,aAAa,GAAG,IAAI,KAAK;AACzD,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,MAAMC,UAAS,UAAU,OAAO;AAChD,eAAS,gBAAgB,OAAO;AAAA,IAClC,QAAQ;AACN,UAAI,MAAM,oCAAoC,IAAI,eAAe;AACjE;AAAA,IACF;AAEA,WAAO,UAAU;AACjB,WAAO,WAAU,oBAAI,KAAK,GAAE,YAAY;AACxC,UAAME,WAAU,UAAU,oBAAoB,MAAM,GAAG,OAAO;AAC9D,SAAK,8BAA8B;AACnC,SAAK,wBAAwB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,qBAA4C;AAChD,UAAM,iBAAiB,KAAK,uBAAuB;AACnD,UAAM,SAAS,kBAAkB,KAAK,SAAS,cAAc;AAC7D,QAAI,OAAQ,QAAO;AAEnB,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK,WAAW;AAC9C,YAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC;AACvD,UAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAKlC,YAAM,aAAa;AACnB,YAAM,WAAyB,CAAC;AAChC,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,YAAY;AACnD,cAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI,UAAU;AAC7C,cAAM,UAAU,MAAM,QAAQ;AAAA,UAC5B,MAAM;AAAA,YAAI,CAAC,UACTF,UAASD,MAAK,KAAK,KAAK,aAAa,KAAK,GAAG,OAAO,EAAE,MAAM,MAAM,IAAI;AAAA,UACxE;AAAA,QACF;AACA,mBAAW,WAAW,SAAS;AAC7B,cAAI,YAAY,KAAM,UAAS,KAAK,gBAAgB,OAAO,CAAC;AAAA,QAC9D;AAAA,MACF;AAEA,wBAAkB,KAAK,SAAS,UAAU,cAAc;AACxD,aAAO;AAAA,IACT,QAAQ;AAEN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,YAAY,QAAoB,KAAmB;AAExD,UAAM,UAAU,OAAO,UAAU,IAAI,KAAK,OAAO,OAAO,EAAE,QAAQ,IAAI;AACtE,UAAM,YAAY,KAAK,IAAI,IAAI,IAAI,QAAQ,IAAI,YAAY,MAAO,KAAK,KAAK,GAAG;AAC/E,UAAM,UAAU,KAAK,IAAI,YAAY;AAGrC,UAAM,YAAY,KAAK,IAAI,OAAO,MAAM,SAAS,IAAI,CAAG;AAGxD,UAAM,gBAAgB,KAAK,IAAI,OAAO,SAAS,SAAS,IAAI,CAAG;AAG/D,UAAM,gBAAwC;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,UAAM,eAAe,cAAc,OAAO,KAAK,YAAY,CAAC,KAAK;AAGjE,UAAM,aAAa,KAAK,IAAI,OAAO,cAAc,SAAS,GAAG,CAAG;AAEhE,WACE,UAAU,MACV,YAAY,OACZ,gBAAgB,OAChB,eAAe,MACf,aAAa;AAAA,EAEjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBACJ,QACA,WAC8C;AAC9C,UAAM,mBACJ,WAAW,gBAAgB,UAC3B,WAAW,aAAa;AAE1B,QACE,oBACA,KAAK,uBACL,KAAK,IAAI,IAAI,KAAK,oBAAoB,UAAU,gBAAe,8BAC/D;AACA,aAAO,EAAE,QAAQ,KAAK,oBAAoB,QAAQ,QAAQ,KAAK;AAAA,IACjE;AAEA,UAAM,WAAW,MAAM,KAAK,mBAAmB;AAC/C,QAAI,SAAS,WAAW,GAAG;AACzB,UAAI,iBAAkB,MAAK,sBAAsB,EAAE,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE;AACnF,aAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACrC;AAEA,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,SAAyB,SAAS,IAAI,CAAC,OAAO;AAAA,MAClD,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,OAAO,gBAAe,YAAY,GAAG,GAAG;AAAA,MACxC,WAAW,EAAE,MAAM;AAAA,MACnB,SAAS,EAAE;AAAA,MACX,kBAAkB,EAAE,cAAc,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,IACnE,EAAE;AAGF,WAAO,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACvC,UAAM,cAAc,OAAO,WAAW,gBAAgB,WAClD,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,WAAW,CAAC,IAC7C,OAAO;AACX,UAAM,OAAO,OAAO,MAAM,GAAG,WAAW;AAExC,QAAI,KAAK,WAAW,GAAG;AACrB,UAAI,iBAAkB,MAAK,sBAAsB,EAAE,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE;AACnF,aAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACrC;AAGA,UAAM,SAAS;AACf,UAAM,OAAiB,CAAC;AACxB,QAAI,aAAa,OAAO;AACxB,UAAM,WAAW,OAAO,WAAW,aAAa,WAC5C,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,QAAQ,CAAC,IAC1C,OAAO;AAEX,eAAW,UAAU,MAAM;AACzB,YAAM,UAAU,OAAO,WAAW,GAAG,OAAO,SAAS;AACrD,YAAM,YAAY,OAAO,iBAAiB,SAAS,IAC/C,OAAO,iBAAiB,KAAK,IAAI,IACjC;AACJ,YAAM,MAAM,KAAK,OAAO,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO,MAAM,SAAS;AAEzE,UAAI,aAAa,IAAI,SAAS,IAAI,SAAU;AAC5C,WAAK,KAAK,GAAG;AACb,oBAAc,IAAI,SAAS;AAAA,IAC7B;AAEA,UAAM,SAAS,KAAK,WAAW,IAAI,KAAK,GAAG,MAAM;AAAA,EAAK,KAAK,KAAK,IAAI,CAAC;AAAA;AACrE,QAAI,iBAAkB,MAAK,sBAAsB,EAAE,QAAQ,SAAS,KAAK,IAAI,EAAE;AAC/E,WAAO,EAAE,QAAQ,QAAQ,MAAM;AAAA,EACjC;AAAA;AAAA,EAGA,gCAAsC;AACpC,SAAK,sBAAsB;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAwB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5C,MAAM,0BAA2C;AAC/C,QAAI,SAAS;AACb,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK,WAAW;AAC9C,YAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC;AAGvD,YAAM,SAAS,oBAAI,IAAsB;AACzC,iBAAW,QAAQ,SAAS;AAC1B,cAAM,WAAW,KAAK,QAAQ,OAAO,EAAE;AAEvC,cAAM,UAAU,SAAS,QAAQ,GAAG;AACpC,YAAI,YAAY,GAAI;AACpB,cAAM,OAAO,SAAS,MAAM,GAAG,OAAO;AACtC,cAAM,aAAa,SAAS,MAAM,UAAU,CAAC;AAC7C,cAAM,YAAY,oBAAoB,YAAY,IAAI;AAEtD,YAAI,CAAC,OAAO,IAAI,SAAS,EAAG,QAAO,IAAI,WAAW,CAAC,CAAC;AACpD,eAAO,IAAI,SAAS,EAAG,KAAK,IAAI;AAAA,MAClC;AAGA,iBAAW,CAAC,WAAW,KAAK,KAAK,QAAQ;AACvC,YAAI,MAAM,UAAU,EAAG;AAGvB,cAAM,eAA2B;AAAA,UAC/B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO,CAAC;AAAA,UACR,SAAS;AAAA,UACT,eAAe,CAAC;AAAA,UAChB,UAAU,CAAC;AAAA,UACX,SAAS,CAAC;AAAA,QACZ;AAEA,mBAAW,QAAQ,OAAO;AACxB,gBAAM,WAAWA,MAAK,KAAK,KAAK,aAAa,IAAI;AACjD,cAAI;AACF,kBAAM,UAAU,MAAMC,UAAS,UAAU,OAAO;AAChD,kBAAM,SAAS,gBAAgB,OAAO;AAGtC,gBAAI,CAAC,aAAa,QAAQ,aAAa,SAAS,SAAS;AACvD,2BAAa,OAAO,OAAO;AAAA,YAC7B;AAGA,gBAAI,CAAC,aAAa,WAAW,OAAO,UAAU,aAAa,SAAS;AAClE,2BAAa,UAAU,OAAO;AAAA,YAChC;AAGA,gBAAI,OAAO,KAAK,SAAS,aAAa,KAAK,QAAQ;AACjD,2BAAa,OAAO,OAAO;AAAA,YAC7B;AAGA,gBAAI,CAAC,aAAa,WAAW,OAAO,SAAS;AAC3C,2BAAa,UAAU,OAAO;AAAA,YAChC;AAGA,yBAAa,MAAM,KAAK,GAAG,OAAO,KAAK;AAGvC,yBAAa,cAAc,KAAK,GAAG,OAAO,aAAa;AAGvD,yBAAa,SAAS,KAAK,GAAG,OAAO,QAAQ;AAG7C,yBAAa,QAAQ,KAAK,GAAG,OAAO,OAAO;AAAA,UAC7C,QAAQ;AAAA,UAER;AAAA,QACF;AAGA,qBAAa,QAAQ,CAAC,GAAG,IAAI,IAAI,aAAa,KAAK,CAAC;AAGpD,cAAM,UAAU,oBAAI,IAAY;AAChC,qBAAa,gBAAgB,aAAa,cAAc,OAAO,CAAC,MAAM;AACpE,gBAAM,MAAM,GAAG,EAAE,MAAM,KAAK,EAAE,KAAK;AACnC,cAAI,QAAQ,IAAI,GAAG,EAAG,QAAO;AAC7B,kBAAQ,IAAI,GAAG;AACf,iBAAO;AAAA,QACT,CAAC;AAGD,cAAM,UAAU,oBAAI,IAAY;AAChC,qBAAa,WAAW,aAAa,SAClC,OAAO,CAAC,MAAM;AACb,gBAAM,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI;AAChC,cAAI,QAAQ,IAAI,GAAG,EAAG,QAAO;AAC7B,kBAAQ,IAAI,GAAG;AACf,iBAAO;AAAA,QACT,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAG9C,qBAAa,UAAU,CAAC,GAAG,IAAI,IAAI,aAAa,OAAO,CAAC;AAGxD,YAAI,CAAC,aAAa,MAAM;AACtB,gBAAM,UAAU,UAAU,QAAQ,GAAG;AACrC,uBAAa,OAAO,YAAY,KAAK,UAAU,MAAM,UAAU,CAAC,IAAI;AAAA,QACtE;AAEA,qBAAa,UAAU,aAAa,YAAW,oBAAI,KAAK,GAAE,YAAY;AAEtE,cAAM,gBAAgBD,MAAK,KAAK,KAAK,aAAa,GAAG,SAAS,KAAK;AACnE,cAAMG,WAAU,eAAe,oBAAoB,YAAY,GAAG,OAAO;AAGzE,mBAAW,QAAQ,OAAO;AACxB,gBAAM,WAAWH,MAAK,KAAK,KAAK,aAAa,IAAI;AACjD,cAAI,aAAa,eAAe;AAC9B,gBAAI;AACF,oBAAM,OAAO,QAAQ;AACrB;AACA,kBAAI,MAAM,iBAAiB,IAAI,WAAM,SAAS,KAAK;AAAA,YACrD,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,wBAAwB,WAA0C;AACtE,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,KAAK,IAAI,IAAI,YAAY,KAAK,KAAK,KAAK;AACvD,UAAM,UAAwB,CAAC;AAE/B,eAAW,KAAK,UAAU;AACxB,UAAI,EAAE,YAAY,aAAa,aAAc;AAG7C,YAAM,aAAa,EAAE,YAAY,KAAK;AAAA,QACpC,CAAC,MAAM,MAAM,eAAe,MAAM;AAAA,MACpC;AACA,UAAI,CAAC,WAAY;AAEjB,YAAM,YAAY,IAAI,KAAK,EAAE,YAAY,OAAO,EAAE,QAAQ;AAC1D,UAAI,YAAY,QAAQ;AAEtB,YAAI;AACF,gBAAM,OAAO,EAAE,IAAI;AACnB,kBAAQ,KAAK,CAAC;AACd,cAAI,MAAM,8BAA8B,EAAE,YAAY,EAAE,EAAE;AAAA,QAC5D,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,GAAG;AACtB,WAAK,wBAAwB;AAAA,IAC/B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAoB,SAAiD;AACzE,QAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,YAAY,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC;AACpE,QAAI,UAAU;AAEd,eAAW,SAAS,SAAS;AAC3B,YAAM,SAAS,UAAU,IAAI,MAAM,QAAQ;AAC3C,UAAI,CAAC,OAAQ;AAEb,YAAM,QAA2B;AAAA,QAC/B,GAAG,OAAO;AAAA,QACV,aAAa,MAAM;AAAA,QACnB,cAAc,MAAM;AAAA,MACtB;AAEA,YAAM,cAAc,GAAG,qBAAqB,KAAK,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AACvE,UAAI;AACF,cAAMG,WAAU,OAAO,MAAM,aAAa,OAAO;AACjD;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,MAAM,wCAAwC,MAAM,QAAQ,KAAK,GAAG,EAAE;AAAA,MAC5E;AAAA,IACF;AAEA,QAAI,UAAU,GAAG;AACf,UAAI,MAAM,+BAA+B,OAAO,WAAW;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,IAAwC;AAC1D,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,WAAO,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,EAAE,KAAK;AAAA,EAC1D;AAAA,EAEA,MAAM,wBAAwB,IAA0D;AACtF,UAAM,YAAY,yBAAyB,KAAK,SAAS,EAAE;AAC3D,QAAI,UAAW,QAAO;AAEtB,UAAM,SAAS,MAAM,KAAK,cAAc,EAAE;AAC1C,QAAI,OAAQ,QAAO,KAAK,wBAAwB,QAAQ,QAAQ;AAEhE,UAAM,YAAY,MAAM,KAAK,qBAAqB,GAAG,KAAK,CAAC,WAAW,OAAO,YAAY,OAAO,EAAE;AAClG,QAAI,CAAC,SAAU,QAAO;AAEtB,WAAO,KAAK,wBAAwB,UAAU,UAAU;AAAA,EAC1D;AAAA,EAEA,MAAM,wBACJ,SAC2C;AAC3C,WAAO,0BAA0B,KAAK,SAAS,OAAO;AAAA,EACxD;AAAA,EAEA,MAAM,+BAA0F;AAC9F,WAAO,8BAA8B,KAAK,OAAO;AAAA,EACnD;AAAA,EAEQ,wBACN,QACA,gBAC8B;AAC9B,UAAM,UAAU,gBAAgB,KAAK,SAAS,OAAO,IAAI;AACzD,WAAO;AAAA,MACL,UAAU,OAAO,YAAY;AAAA,MAC7B,UAAU,OAAO,YAAY;AAAA,MAC7B,QAAQ,wBAAwB,OAAO,aAAa,SAAS,cAAc;AAAA,MAC3E,gBAAgB,OAAO,YAAY;AAAA,MACnC,MAAM,OAAO;AAAA,MACb;AAAA,MACA,SAAS,OAAO,YAAY;AAAA,MAC5B,SAAS,OAAO,YAAY;AAAA,MAC5B,YAAY,OAAO,YAAY;AAAA,MAC/B,cAAc,OAAO,YAAY;AAAA,MACjC,WAAW,OAAO,YAAY;AAAA,MAC9B,QAAQ,OAAO,YAAY;AAAA,MAC3B,YAAY,OAAO,YAAY;AAAA,MAC/B,gBAAgB,OAAO,YAAY;AAAA,MACnC,YAAY,OAAO,YAAY;AAAA,MAC/B,aAAa,OAAO,YAAY;AAAA,MAChC,cAAc,OAAO,YAAY;AAAA,MACjC,MAAM,wBAAwB,OAAO,YAAY,IAAI;AAAA,MACrD,SAAS,2BAA2B,OAAO,OAAO;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,UAAkB,QAAgB,KAAsC;AAC9F,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACjD,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAE/B,UAAM,YAAY,4BAA4B,KAAK,SAAS,UAAU,WAAW;AACjF,QAAI,aAAa,UAAU,SAAS,EAAG,QAAO;AAE9C,UAAM,SAAS,MAAM,KAAK,6BAA6B;AACvD,WAAO,OAAO,OAAO,CAAC,UAAU,MAAM,aAAa,QAAQ,EAAE,MAAM,CAAC,WAAW;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WACJ,UACA,YACA,YACA,UACA,SACA,UAUI,CAAC,GACY;AACjB,UAAM,KAAK,kBAAkB;AAC7B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AAC3C,UAAM,KAAK,GAAG,QAAQ,UAAU,UAAU;AAC1C,UAAM,OAAO,QAAQ,cAAc;AACnC,UAAM,OAAO,eAAe,IAAI;AAEhC,UAAM,KAAwB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,SAAS,IAAI,YAAY;AAAA,MACzB,SAAS,IAAI,YAAY;AAAA,MACzB,QAAQ,QAAQ,UAAU;AAAA,MAC1B,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,WAAW,QAAQ;AAAA,MACnB,YAAY,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,QAAQ;AAAA,MACpB,kBAAkB,QAAQ;AAAA,MAC1B,mBAAmB,QAAQ;AAAA,MAC3B,YAAY,QAAQ;AAAA,IACtB;AAEA,UAAM,YAAY,sBAAsB,OAAO;AAC/C,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,+BAA+B,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,IAC7F;AACA,UAAM,cAAc,GAAG,qBAAqB,EAAE,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA;AAEpE,QAAI;AACJ,QAAI,aAAa,cAAc;AAC7B,iBAAWH,MAAK,KAAK,KAAK,gBAAgB,GAAG,EAAE,KAAK;AAAA,IACtD,OAAO;AACL,iBAAWA,MAAK,KAAK,KAAK,UAAU,OAAO,GAAG,EAAE,KAAK;AAAA,IACvD;AAEA,UAAMG,WAAU,UAAU,aAAa,OAAO;AAC9C,QAAI,MAAM,eAAe,EAAE,KAAK,aAAa,CAAC,IAAI,UAAU,QAAQ,QAAQ,EAAE;AAC9E,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBAAmB,UAAyC;AAChE,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,WAAO,SACJ,OAAO,CAAC,MAAM,EAAE,YAAY,aAAa,QAAQ,EACjD,KAAK,CAAC,GAAG,OAAO,EAAE,YAAY,cAAc,MAAM,EAAE,YAAY,cAAc,EAAE;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBACJ,aACA,aACA,QACkB;AAClB,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,YAAY,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,WAAW;AACvE,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,YAA+B;AAAA,MACnC,GAAG,UAAU;AAAA,MACb,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,cAAc;AAAA,MACd,SAAS;AAAA,IACX;AAEA,UAAM,cAAc,GAAG,qBAAqB,SAAS,CAAC;AAAA;AAAA,EAAO,UAAU,OAAO;AAAA;AAE9E,QAAI;AACF,YAAMA,WAAU,UAAU,MAAM,aAAa,OAAO;AACpD,YAAM,KAAK,4CAA4C,2BAA2B;AAAA,QAChF,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,QACX,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,QAAQ,KAAK,wBAAwB,UAAU,aAAa,UAAU,IAAI;AAAA,QAC1E,OAAO,KAAK,wBAAwB,WAAW,UAAU,IAAI;AAAA,QAC7D,kBAAkB,CAAC,WAAW;AAAA,MAChC,CAAC;AACD,WAAK,wBAAwB;AAC7B,UAAI,MAAM,qBAAqB,WAAW,OAAO,WAAW,KAAK,MAAM,EAAE;AAGzE,YAAM,KAAK,YAAY,cAAc,eAAe,UAAU,OAAO;AAAA;AAAA,UAAe,MAAM,IAAI;AAAA,QAC5F,YAAY;AAAA,QACZ,MAAM,CAAC,gBAAgB,eAAe;AAAA,QACtC,QAAQ;AAAA,QACR,SAAS,CAAC,aAAa,WAAW;AAAA,MACpC,CAAC;AAED,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,MAAM,8BAA8B,WAAW,KAAK,GAAG;AAC3D,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,IAAY,eAAuB;AACjC,WAAOH,MAAK,KAAK,KAAK,SAAS,WAAW;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,SAAuC;AACxD,UAAME,OAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAClD,UAAM,WAAWF,MAAK,KAAK,KAAK,cAAc,GAAG,QAAQ,EAAE,OAAO;AAClE,UAAMG,WAAU,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,OAAO;AACnE,QAAI,MAAM,iBAAiB,QAAQ,EAAE,EAAE;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAA0C;AAC9C,QAAI;AACF,YAAM,QAAQ,MAAM,QAAQ,KAAK,YAAY;AAC7C,YAAM,YAA6B,CAAC;AAEpC,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,SAAS,OAAO,EAAG;AAC7B,cAAM,WAAWH,MAAK,KAAK,KAAK,cAAc,IAAI;AAClD,cAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,kBAAU,KAAK,KAAK,MAAM,GAAG,CAAkB;AAAA,MACjD;AAEA,aAAO;AAAA,IACT,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,WAAqB,WAAoC;AAC7E,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,YAAY,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC;AACpE,QAAI,WAAW;AAEf,eAAW,MAAM,WAAW;AAC1B,YAAM,SAAS,UAAU,IAAI,EAAE;AAC/B,UAAI,CAAC,OAAQ;AAEb,YAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,YAAM,YAA+B;AAAA,QACnC,GAAG,OAAO;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,SAAS;AAAA,MACX;AAEA,YAAM,cAAc,GAAG,qBAAqB,SAAS,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AAE3E,UAAI;AACF,cAAME,WAAU,OAAO,MAAM,aAAa,OAAO;AACjD,cAAM,KAAK,4CAA4C,2BAA2B;AAAA,UAChF,UAAU;AAAA,UACV,WAAW;AAAA,UACX,WAAW,UAAU,cAAc,UAAU;AAAA,UAC7C,OAAO;AAAA,UACP,YAAY,WAAW,SAAS;AAAA,UAChC,QAAQ,KAAK,wBAAwB,OAAO,aAAa,OAAO,IAAI;AAAA,UACpE,OAAO,KAAK,wBAAwB,WAAW,OAAO,IAAI;AAAA,UAC1D,kBAAkB,CAAC,SAAS;AAAA,QAC9B,CAAC;AACD;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI,WAAW,GAAG;AAChB,WAAK,wBAAwB;AAC7B,UAAI,MAAM,YAAY,QAAQ,yBAAyB,SAAS,EAAE;AAAA,IACpE;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAW,QAAqC;AACpD,UAAM,WAAWH,MAAK,KAAK,KAAK,UAAU,aAAa;AACvD,UAAME,OAAM,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAMC,WAAU,UAAU,KAAK,UAAU,EAAE,QAAQ,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,GAAG,MAAM,CAAC,GAAG,OAAO;AAC3G,QAAI,MAAM,SAAS,OAAO,MAAM,eAAe;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA0E;AAC9E,UAAM,WAAWH,MAAK,KAAK,KAAK,UAAU,aAAa;AACvD,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,UAAU,OAAO;AAC5C,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,QAAQ;AACN,aAAO,EAAE,QAAQ,CAAC,GAAG,WAAW,KAAK;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBACJ,UACA,OACA,WACkB;AAClB,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,QAAQ;AACjE,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,gBAAgB,OAAO,YAAY,SAAS,CAAC;AACnD,UAAM,cAAc,CAAC,GAAG,aAAa;AAGrC,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,YAAY,KAAK,CAAC,MAAM,EAAE,aAAa,KAAK,YAAY,EAAE,aAAa,KAAK,QAAQ,GAAG;AAC1F,oBAAY,KAAK,IAAI;AAAA,MACvB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC;AAAA,QACA;AAAA,MACF;AACA,UAAI,MAAM,SAAS,MAAM,MAAM,oBAAoB,QAAQ,EAAE;AAC7D,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,MAAM,iCAAiC,QAAQ,KAAK,GAAG;AAC3D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,wBACN,aACA,UAC6B;AAC7B,WAAO;AAAA,MACL,UAAU,YAAY;AAAA,MACtB,MAAM;AAAA,MACN,QAAQ,YAAY,UAAU;AAAA,MAC9B,gBAAgB,YAAY;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,0BACN,QACA,OAC0B;AAC1B,UAAM,eAAe,OAAO,UAAU;AACtC,UAAM,cAAc,MAAM,UAAU;AACpC,QAAI,iBAAiB,cAAc,gBAAgB,WAAY,QAAO;AACtE,QAAI,iBAAiB,gBAAgB,gBAAgB,aAAc,QAAO;AAC1E,QAAI,iBAAiB,cAAc,gBAAgB,WAAY,QAAO;AACtE,QAAI,iBAAiB,YAAY,gBAAgB,UAAU;AACzD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,oCACZ,OACA,cAAc,8BACC;AACf,UAAM,KAAK,4BAA4B;AAAA,MACrC;AAAA,QACE,GAAG;AAAA,QACH,SAAS,KAAK,WAAW,KAAK;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,4CACZ,WACA,OACA,aACe;AACf,QAAI;AACF,YAAM,KAAK,oCAAoC,OAAO,WAAW;AAAA,IACnE,SAAS,WAAW;AAClB,UAAI,KAAK,GAAG,SAAS,oDAAoD,SAAS,EAAE;AAAA,IACtF;AAAA,EACF;AACF;","names":["readFile","stat","writeFile","mkdir","path","path","path","parseFrontmatter","match","path","readFile","mkdir","writeFile","stat","q"]}