@hiveai/core 0.10.9 → 0.12.0

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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema.ts","../src/parser.ts","../src/paths.ts","../src/loader.ts","../src/search.ts","../src/verifier.ts","../src/relevance.ts","../src/usage.ts","../src/confidence.ts","../src/specificity.ts","../src/token-budget.ts","../src/code-map.ts","../src/config.ts","../src/cross-repo.ts","../src/dep-tracker.ts","../src/contract-watcher.ts","../src/usage-log.ts","../src/briefing-preset.ts","../src/briefing-body.ts","../src/resolve-project.ts","../src/topic-suggest.ts","../src/lexical-rank.ts","../src/memory-timeline.ts","../src/conflict-candidates.ts","../src/runtime-journal.ts","../src/enforcement.ts","../src/memory-lifecycle.ts","../src/sensors.ts","../src/sensor-suggest.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const MemoryScopeSchema = z.enum([\"personal\", \"team\", \"module\", \"shared\"]);\n\nexport const MemoryStatusSchema = z.enum([\n \"draft\",\n \"proposed\",\n \"validated\",\n \"deprecated\",\n \"stale\",\n \"rejected\",\n]);\n\nexport const MemoryTypeSchema = z.enum([\n \"convention\",\n \"decision\",\n \"gotcha\",\n \"architecture\",\n \"glossary\",\n \"skill\", // reusable procedure/playbook for a recurring task (feedforward harness guide)\n \"attempt\", // failed approach — \"tried X, failed because Y, use Z instead\"\n \"session_recap\", // end-of-session summary: goal / accomplished / discoveries / next steps\n]);\n\nexport const AnchorSchema = z.object({\n commit: z.string().optional(),\n paths: z.array(z.string()).default([]),\n symbols: z.array(z.string()).default([]),\n});\n\n/**\n * An executable check derived from a memory — the \"feedback computational\" layer.\n *\n * A `gotcha`/`attempt` is normally feedforward (text the agent reads). A sensor turns\n * that lesson into a deterministic check: when a touched file matches `pattern`, the\n * memory's warning fires regardless of semantic ranking. This closes the harness loop —\n * a documented mistake becomes a permanent guardrail.\n *\n * Phase 1 implements `kind: \"regex\"` only. `shell`/`test` are reserved for a later phase\n * (they require I/O and must run from the CLI, not core).\n */\nexport const SensorSchema = z.object({\n kind: z.enum([\"regex\", \"shell\", \"test\"]).default(\"regex\"),\n /** Regex source (for kind=regex), matched against added diff lines / file content. */\n pattern: z.string().optional(),\n /** Regex flags (e.g. \"i\", \"m\"). Ignored for non-regex kinds. */\n flags: z.string().optional(),\n /** Shell/test command to run (for kind=shell|test). Executed by the CLI, never by core. */\n command: z.string().optional(),\n /** Glob-ish path prefixes the sensor applies to. Falls back to the memory's anchor paths when empty. */\n paths: z.array(z.string()).default([]),\n /** LLM-facing self-correction message: what was done wrong and what to do instead. */\n message: z.string().min(1),\n /** `warn` surfaces in review; `block` can hard-block the commit (only when the gate opts in). */\n severity: z.enum([\"warn\", \"block\"]).default(\"warn\"),\n /** True when hAIve generated this sensor automatically (vs. hand-authored). */\n autogen: z.boolean().default(false),\n /** ISO timestamp of the last time this sensor matched a diff. */\n last_fired: z.string().nullable().default(null),\n});\n\nconst IsoDateString = z\n .union([z.string(), z.date()])\n .transform((v) => (v instanceof Date ? v.toISOString() : v))\n .pipe(z.string().datetime());\n\nexport const MemoryFrontmatterSchema = z\n .object({\n id: z.string().min(1),\n scope: MemoryScopeSchema.default(\"personal\"),\n module: z.string().optional(),\n type: MemoryTypeSchema,\n status: MemoryStatusSchema.default(\"draft\"),\n anchor: AnchorSchema.default({ paths: [], symbols: [] }),\n /** Optional executable check derived from this memory (feedback computational layer). */\n sensor: SensorSchema.optional(),\n tags: z.array(z.string()).default([]),\n domain: z.string().optional(),\n author: z.string().optional(),\n created_at: IsoDateString,\n expires_when: z.string().nullable().default(null),\n verified_at: z.string().nullable().default(null),\n stale_reason: z.string().nullable().default(null),\n related_ids: z.array(z.string()).default([]),\n last_read_at: z.string().nullable().default(null),\n topic: z.string().optional(), // stable key for upsert — same topic in same scope → update instead of create\n revision_count: z.number().int().min(0).default(0), // incremented each time a topic upsert occurs\n /**\n * When true, the AI MUST NOT act on this memory autonomously.\n * It must surface the information to the human developer and wait\n * for explicit confirmation before modifying any code.\n * Used for cross-repo breaking changes, dependency bumps, contract diffs.\n */\n requires_human_approval: z.boolean().default(false),\n })\n .refine(\n (data) => data.scope !== \"module\" || !!data.module,\n { message: \"module name is required when scope is 'module'\", path: [\"module\"] },\n );\n\n// Additional fields for cross-repo provenance (stored in frontmatter of imported memories)\nexport const CrossRepoProvenanceSchema = z.object({\n source_name: z.string(), // the crossRepoSources name from haive.config.json\n source_path: z.string(), // original file path in the source repo\n source_id: z.string(), // original memory id\n imported_at: z.string(), // ISO timestamp of import\n}).optional();\n","import matter from \"gray-matter\";\nimport { MemoryFrontmatterSchema } from \"./schema.js\";\nimport type { Memory, MemoryFrontmatter, Sensor } from \"./types.js\";\n\nconst PRIVATE_BLOCK_RE = /<private>[\\s\\S]*?<\\/private>/g;\n\nexport function stripPrivate(body: string): string {\n return body.replace(PRIVATE_BLOCK_RE, \"\").trimEnd();\n}\n\nexport function parseMemory(raw: string): Memory {\n const parsed = matter(raw);\n const frontmatter = MemoryFrontmatterSchema.parse(parsed.data);\n return {\n frontmatter,\n body: stripPrivate(parsed.content.trim()),\n };\n}\n\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((v) => stripUndefined(v)) as unknown as T;\n }\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = stripUndefined(v);\n }\n return out as T;\n }\n return value;\n}\n\nexport function serializeMemory(memory: Memory): string {\n const clean = stripUndefined(memory.frontmatter) as Record<string, unknown>;\n return matter.stringify(memory.body, clean);\n}\n\nexport function newMemoryId(type: string, slug: string, date = new Date()): string {\n const isoDate = date.toISOString().slice(0, 10);\n const safeSlug = slug\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n return `${isoDate}-${type}-${safeSlug}`;\n}\n\nexport function buildFrontmatter(input: {\n type: MemoryFrontmatter[\"type\"];\n slug: string;\n scope?: MemoryFrontmatter[\"scope\"];\n module?: string;\n tags?: string[];\n domain?: string;\n author?: string;\n paths?: string[];\n symbols?: string[];\n commit?: string;\n topic?: string;\n status?: MemoryFrontmatter[\"status\"];\n relatedIds?: string[];\n sensor?: Sensor;\n}): MemoryFrontmatter {\n const now = new Date();\n const id = newMemoryId(input.type, input.slug, now);\n return MemoryFrontmatterSchema.parse({\n id,\n scope: input.scope ?? \"personal\",\n module: input.module,\n type: input.type,\n status: input.status ?? \"draft\",\n anchor: {\n commit: input.commit,\n paths: input.paths ?? [],\n symbols: input.symbols ?? [],\n },\n tags: input.tags ?? [],\n domain: input.domain,\n author: input.author,\n created_at: now.toISOString(),\n expires_when: null,\n topic: input.topic,\n sensor: input.sensor,\n revision_count: 0,\n related_ids: input.relatedIds ?? [],\n });\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport const HAIVE_DIR = \".ai\";\n\nconst ROOT_MARKERS = [\".ai\", \".git\", \"package.json\"];\n\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n let current = path.resolve(startDir);\n const fsRoot = path.parse(current).root;\n while (current !== fsRoot) {\n for (const marker of ROOT_MARKERS) {\n if (existsSync(path.join(current, marker))) return current;\n }\n current = path.dirname(current);\n }\n return path.resolve(startDir);\n}\n\nexport const PROJECT_CONTEXT_FILE = \"project-context.md\";\nexport const MEMORIES_DIR = \"memories\";\n\nexport interface HaivePaths {\n root: string;\n haiveDir: string;\n /** Disposable local layer (session journal, caches). Not team truth — see `.ai/.runtime/` layout. */\n runtimeDir: string;\n projectContext: string;\n memoriesDir: string;\n personalDir: string;\n teamDir: string;\n sharedDir: string;\n moduleDir: string;\n modulesContextDir: string;\n}\n\nexport function resolveHaivePaths(projectRoot: string): HaivePaths {\n const haiveDir = path.join(projectRoot, HAIVE_DIR);\n const memoriesDir = path.join(haiveDir, MEMORIES_DIR);\n return {\n root: projectRoot,\n haiveDir,\n runtimeDir: path.join(haiveDir, \".runtime\"),\n projectContext: path.join(haiveDir, PROJECT_CONTEXT_FILE),\n memoriesDir,\n personalDir: path.join(memoriesDir, \"personal\"),\n teamDir: path.join(memoriesDir, \"team\"),\n sharedDir: path.join(memoriesDir, \"shared\"),\n moduleDir: path.join(memoriesDir, \"module\"),\n modulesContextDir: path.join(haiveDir, \"modules\"),\n };\n}\n\nexport function memoryFilePath(\n paths: HaivePaths,\n scope: \"personal\" | \"team\" | \"module\" | \"shared\",\n id: string,\n module?: string,\n): string {\n const base =\n scope === \"personal\"\n ? paths.personalDir\n : scope === \"team\"\n ? paths.teamDir\n : scope === \"shared\"\n ? paths.sharedDir\n : path.join(paths.moduleDir, module ?? \"_unscoped\");\n return path.join(base, `${id}.md`);\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parseMemory } from \"./parser.js\";\nimport type { Memory } from \"./types.js\";\n\nexport interface LoadedMemory {\n memory: Memory;\n filePath: string;\n}\n\nexport async function listMarkdownFilesRecursive(dir: string): Promise<string[]> {\n const out: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return out;\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await listMarkdownFilesRecursive(full)));\n } else if (entry.isFile() && entry.name.endsWith(\".md\")) {\n out.push(full);\n }\n }\n return out;\n}\n\nexport async function loadMemory(filePath: string): Promise<LoadedMemory> {\n const raw = await readFile(filePath, \"utf8\");\n return { memory: parseMemory(raw), filePath };\n}\n\nexport async function loadMemoriesFromDir(dir: string): Promise<LoadedMemory[]> {\n const files = await listMarkdownFilesRecursive(dir);\n const out: LoadedMemory[] = [];\n for (const file of files) {\n try {\n out.push(await loadMemory(file));\n } catch {\n // Skip unparseable files in v0.1; future: surface a warning channel.\n }\n }\n return out;\n}\n","import type { Memory } from \"./types.js\";\n\nexport function tokenizeQuery(query: string): string[] {\n return query\n .toLowerCase()\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\nexport function literalMatchesAllTokens(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return true;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.every((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nfunction collectAnchorPathTokens(paths: readonly string[]): string[] {\n const out = new Set<string>();\n for (const p of paths) {\n const lower = p.toLowerCase();\n out.add(lower);\n // basename without extension\n const base = lower.split(\"/\").pop() ?? lower;\n const noExt = base.replace(/\\.[a-z0-9]+$/, \"\");\n if (noExt) out.add(noExt);\n // each path segment (helps \"verifier\" match \"src/verifier.ts\")\n for (const segment of lower.split(\"/\")) {\n const seg = segment.replace(/\\.[a-z0-9]+$/, \"\");\n if (seg) out.add(seg);\n }\n }\n return [...out];\n}\n\n/**\n * OR-based fallback: returns true if the memory matches at least one token.\n * Used when all-tokens (AND) search returns 0 results.\n */\nexport function literalMatchesAnyToken(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return false;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.some((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nexport function pickSnippetNeedle(query: string): string {\n const tokens = tokenizeQuery(query);\n if (tokens.length === 0) return query.toLowerCase();\n return [...tokens].sort((a, b) => b.length - a.length)[0]!;\n}\n\nexport function extractSnippet(body: string, needle: string, radius = 40): string {\n const lower = body.toLowerCase();\n const idx = needle ? lower.indexOf(needle) : -1;\n if (idx < 0) {\n return body.slice(0, radius * 3).replace(/\\s+/g, \" \").trim();\n }\n const start = Math.max(0, idx - radius);\n const end = Math.min(body.length, idx + needle.length + radius);\n const snippet = body.slice(start, end).replace(/\\s+/g, \" \").trim();\n return (start > 0 ? \"…\" : \"\") + snippet + (end < body.length ? \"…\" : \"\");\n}\n","import { readFile, readdir, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { globToRegExp, isGlobPath } from \"./relevance.js\";\nimport type { Memory } from \"./types.js\";\n\nexport interface VerifyResult {\n stale: boolean;\n reason: string | null;\n checkedPaths: string[];\n checkedSymbols: string[];\n possibleRenames: string[];\n}\n\nexport interface VerifyOptions {\n /** Project root used to resolve relative anchor paths. */\n projectRoot: string;\n}\n\n/**\n * Verify that a memory's anchor still matches the current code.\n * - Every anchor.paths entry must exist on disk\n * - Every anchor.symbols entry must appear at least once across the anchor.paths\n * files (or any tracked file if no paths are recorded)\n *\n * Anchorless memories (no paths and no symbols) are always considered fresh —\n * staleness only applies to memories that opted into anchoring.\n */\nexport async function verifyAnchor(\n memory: Memory,\n options: VerifyOptions,\n): Promise<VerifyResult> {\n const anchor = memory.frontmatter.anchor;\n const checkedPaths = anchor.paths;\n const checkedSymbols = anchor.symbols;\n\n if (checkedPaths.length === 0 && checkedSymbols.length === 0) {\n return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };\n }\n\n const missingPaths: string[] = [];\n const existingAbsPaths: string[] = [];\n for (const rel of checkedPaths) {\n if (isGlobPath(rel)) {\n const matches = await findGlobMatches(rel, options.projectRoot);\n if (matches.length > 0) {\n existingAbsPaths.push(...matches.map((m) => path.join(options.projectRoot, m)));\n } else {\n missingPaths.push(rel);\n }\n continue;\n }\n const abs = path.isAbsolute(rel) ? rel : path.join(options.projectRoot, rel);\n if (existsSync(abs)) {\n existingAbsPaths.push(...await readableFilesForAnchor(abs));\n } else {\n missingPaths.push(rel);\n }\n }\n\n if (missingPaths.length > 0) {\n const possibleRenames = await findPossibleRenames(missingPaths, options.projectRoot);\n return {\n stale: true,\n reason: `anchor path(s) no longer exist: ${missingPaths.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n possibleRenames,\n };\n }\n\n if (checkedSymbols.length > 0) {\n if (existingAbsPaths.length === 0) {\n return {\n stale: true,\n reason: `cannot verify symbols (${checkedSymbols.join(\", \")}): no anchor paths recorded`,\n checkedPaths,\n checkedSymbols,\n possibleRenames: [],\n };\n }\n const missingSymbols: string[] = [];\n for (const sym of checkedSymbols) {\n let found = false;\n for (const file of existingAbsPaths) {\n try {\n const contents = await readFile(file, \"utf8\");\n if (contents.includes(sym)) {\n found = true;\n break;\n }\n } catch {\n // unreadable file; treat as not finding the symbol here\n }\n }\n if (!found) missingSymbols.push(sym);\n }\n if (missingSymbols.length > 0) {\n return {\n stale: true,\n reason: `anchor symbol(s) not found in any anchor path: ${missingSymbols.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n possibleRenames: [],\n };\n }\n }\n\n return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };\n}\n\nasync function findPossibleRenames(\n missingPaths: string[],\n projectRoot: string,\n): Promise<string[]> {\n const basenames = new Set(missingPaths.map((p) => path.basename(p)));\n const found: string[] = [];\n try {\n await walkDir(projectRoot, projectRoot, basenames, found, 0);\n } catch {\n // best-effort\n }\n return found;\n}\n\nasync function findGlobMatches(pattern: string, projectRoot: string): Promise<string[]> {\n const re = globToRegExp(pattern);\n const found: string[] = [];\n try {\n await walkAllFiles(projectRoot, projectRoot, found, 0, re);\n } catch {\n // best-effort\n }\n return found;\n}\n\nasync function readableFilesForAnchor(abs: string): Promise<string[]> {\n try {\n const s = await stat(abs);\n if (s.isDirectory()) {\n const out: string[] = [];\n await walkReadableFiles(abs, out, 0);\n return out;\n }\n if (s.isFile()) return [abs];\n } catch {\n return [abs];\n }\n return [abs];\n}\n\nasync function walkReadableFiles(dir: string, found: string[], depth: number): Promise<void> {\n if (depth > 6) return;\n let entries: string[];\n try {\n entries = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const name of entries) {\n if (name.startsWith(\".\") || name === \"node_modules\") continue;\n const abs = path.join(dir, name);\n try {\n const s = await stat(abs);\n if (s.isDirectory()) await walkReadableFiles(abs, found, depth + 1);\n else if (s.isFile()) found.push(abs);\n } catch {\n continue;\n }\n }\n}\n\nasync function walkAllFiles(\n dir: string,\n root: string,\n found: string[],\n depth: number,\n match: RegExp,\n): Promise<void> {\n if (depth > 12) return;\n let entries: string[];\n try {\n entries = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const name of entries) {\n if (name === \"node_modules\" || name === \".git\" || name === \".ai\") continue;\n const abs = path.join(dir, name);\n try {\n const s = await stat(abs);\n if (s.isDirectory()) {\n await walkAllFiles(abs, root, found, depth + 1, match);\n } else if (s.isFile()) {\n const rel = path.relative(root, abs).replace(/\\\\/g, \"/\");\n if (match.test(rel)) found.push(rel);\n }\n } catch {\n continue;\n }\n }\n}\n\nasync function walkDir(\n dir: string,\n root: string,\n targets: Set<string>,\n found: string[],\n depth: number,\n): Promise<void> {\n if (depth > 6) return;\n let entries: string[];\n try {\n entries = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const name of entries) {\n if (name.startsWith(\".\") || name === \"node_modules\") continue;\n const abs = path.join(dir, name);\n let isDir = false;\n try {\n isDir = (await stat(abs)).isDirectory();\n } catch {\n continue;\n }\n if (isDir) {\n await walkDir(abs, root, targets, found, depth + 1);\n } else if (targets.has(name)) {\n found.push(path.relative(root, abs));\n }\n }\n}\n","import path from \"node:path\";\nimport type { LoadedMemory } from \"./loader.js\";\n\n/**\n * Tag stamped on memories that were pre-seeded from a stack pack at `haive init`\n * (generic framework knowledge the model already largely knows, not repo-specific\n * institutional knowledge). Briefing ranking caps these at `background` priority so\n * a generic seed never displaces a repo-specific memory — unless the seed has been\n * anchored to a file the agent is actually editing.\n */\nexport const STACK_PACK_TAG = \"stack-pack\";\n\n/** True when a memory was pre-seeded from a stack pack (carries {@link STACK_PACK_TAG}). */\nexport function isStackPackSeed(fm: { tags?: string[] } | null | undefined): boolean {\n return Boolean(fm?.tags?.includes(STACK_PACK_TAG));\n}\n\nconst MODULE_PATTERNS = [\n /^packages\\/([^/]+)\\//,\n /^apps\\/([^/]+)\\//,\n /^modules\\/([^/]+)\\//,\n /^src\\/([^/]+)\\//,\n /^libs\\/([^/]+)\\//,\n /^services\\/([^/]+)\\//,\n /^internal\\/([^/]+)\\//,\n /^projects\\/([^/]+)\\//, // Nx layout\n /^cmd\\/([^/]+)\\//, // Go-style\n];\n\n/**\n * Best-effort inference: given a list of file paths, infer module names from\n * conventional layouts (packages/X/, apps/X/, modules/X/, src/X/).\n */\nexport function inferModulesFromPaths(filePaths: string[]): string[] {\n const out = new Set<string>();\n for (const p of filePaths) {\n const norm = normalize(p);\n for (const re of MODULE_PATTERNS) {\n const m = norm.match(re);\n if (m && m[1]) out.add(m[1]);\n }\n }\n return [...out].sort();\n}\n\n/**\n * Path overlap: returns true if `a` and `b` refer to the same path or one is a\n * parent of the other. Both inputs are treated as POSIX-style relative paths.\n */\nexport function pathsOverlap(a: string, b: string): boolean {\n const na = normalize(a);\n const nb = normalize(b);\n if (isGlobPath(na)) return globOverlapsPath(na, nb);\n if (isGlobPath(nb)) return globOverlapsPath(nb, na);\n if (na === nb) return true;\n return na.startsWith(nb + \"/\") || nb.startsWith(na + \"/\");\n}\n\nexport function memoryMatchesAnchorPaths(\n memory: LoadedMemory[\"memory\"],\n inputPaths: string[],\n): boolean {\n const anchorPaths = memory.frontmatter.anchor.paths;\n if (anchorPaths.length === 0) return false;\n for (const ap of anchorPaths) {\n for (const ip of inputPaths) {\n if (pathsOverlap(ap, ip)) return true;\n }\n }\n return false;\n}\n\nfunction normalize(p: string): string {\n // Strip leading \"./\" and trailing \"/\", normalize separators.\n return p.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function isGlobPath(p: string): boolean {\n return /[*?\\[]/.test(p);\n}\n\nexport function globToRegExp(pattern: string): RegExp {\n const norm = normalize(pattern);\n let out = \"^\";\n for (let i = 0; i < norm.length; i++) {\n const ch = norm[i]!;\n const next = norm[i + 1];\n const afterNext = norm[i + 2];\n if (ch === \"*\" && next === \"*\" && afterNext === \"/\") {\n out += \"(?:.*/)?\";\n i += 2;\n } else if (ch === \"*\" && next === \"*\") {\n out += \".*\";\n i++;\n } else if (ch === \"*\") {\n out += \"[^/]*\";\n } else if (ch === \"?\") {\n out += \"[^/]\";\n } else {\n out += ch.replace(/[|\\\\{}()[\\]^$+?.]/g, \"\\\\$&\");\n }\n }\n out += \"$\";\n return new RegExp(out);\n}\n\nfunction globOverlapsPath(globPattern: string, candidate: string): boolean {\n const normalizedCandidate = normalize(candidate);\n if (globToRegExp(globPattern).test(normalizedCandidate)) return true;\n const prefix = globLiteralPrefix(globPattern);\n if (!prefix || prefix.split(\"/\").length < 2) return false;\n return normalizedCandidate === prefix ||\n normalizedCandidate.startsWith(prefix + \"/\") ||\n prefix.startsWith(normalizedCandidate + \"/\");\n}\n\nfunction globLiteralPrefix(pattern: string): string {\n const norm = normalize(pattern);\n const firstGlob = norm.search(/[*?\\[]/);\n if (firstGlob < 0) return norm;\n const slash = norm.slice(0, firstGlob).lastIndexOf(\"/\");\n return slash < 0 ? \"\" : norm.slice(0, slash);\n}\n\nexport function relPathFrom(root: string, abs: string): string {\n return path.relative(root, abs).replace(/\\\\/g, \"/\");\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport interface MemoryUsage {\n read_count: number;\n last_read_at: string | null;\n rejected_count: number;\n last_rejected_at: string | null;\n rejection_reason: string | null;\n}\n\nexport interface UsageIndex {\n version: 1;\n updated_at: string;\n by_id: Record<string, MemoryUsage>;\n}\n\nexport const USAGE_FILE = \"usage.json\";\n\nexport function emptyUsage(): MemoryUsage {\n return {\n read_count: 0,\n last_read_at: null,\n rejected_count: 0,\n last_rejected_at: null,\n rejection_reason: null,\n };\n}\n\nexport function emptyUsageIndex(): UsageIndex {\n return {\n version: 1,\n updated_at: new Date().toISOString(),\n by_id: {},\n };\n}\n\nexport function usagePath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, \".cache\", USAGE_FILE);\n}\n\nexport async function loadUsageIndex(paths: HaivePaths): Promise<UsageIndex> {\n const file = usagePath(paths);\n if (!existsSync(file)) return emptyUsageIndex();\n const raw = await readFile(file, \"utf8\");\n try {\n const parsed = JSON.parse(raw) as UsageIndex;\n if (parsed.version !== 1) return emptyUsageIndex();\n return parsed;\n } catch {\n return emptyUsageIndex();\n }\n}\n\nexport async function saveUsageIndex(paths: HaivePaths, index: UsageIndex): Promise<void> {\n const file = usagePath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n index.updated_at = new Date().toISOString();\n await writeFile(file, JSON.stringify(index, null, 2), \"utf8\");\n}\n\nexport function getUsage(index: UsageIndex, id: string): MemoryUsage {\n return index.by_id[id] ?? emptyUsage();\n}\n\nexport function bumpRead(index: UsageIndex, ids: string[]): UsageIndex {\n if (ids.length === 0) return index;\n const now = new Date().toISOString();\n for (const id of ids) {\n const current = index.by_id[id] ?? emptyUsage();\n index.by_id[id] = {\n ...current,\n read_count: current.read_count + 1,\n last_read_at: now,\n };\n }\n return index;\n}\n\nexport function recordRejection(\n index: UsageIndex,\n id: string,\n reason: string | null,\n): UsageIndex {\n const current = index.by_id[id] ?? emptyUsage();\n const now = new Date().toISOString();\n index.by_id[id] = {\n ...current,\n rejected_count: current.rejected_count + 1,\n last_rejected_at: now,\n rejection_reason: reason,\n };\n return index;\n}\n\nexport const DECAY_DAYS = 90;\n\nexport function isDecaying(usage: MemoryUsage, createdAt: string): boolean {\n const threshold = Date.now() - DECAY_DAYS * 24 * 60 * 60 * 1000;\n const anchor = usage.last_read_at ?? createdAt;\n return new Date(anchor).getTime() < threshold;\n}\n\nexport async function trackReads(\n paths: HaivePaths,\n ids: string[],\n): Promise<UsageIndex> {\n if (ids.length === 0) {\n return await loadUsageIndex(paths);\n }\n const index = await loadUsageIndex(paths);\n bumpRead(index, ids);\n await saveUsageIndex(paths, index);\n return index;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\nimport type { MemoryUsage } from \"./usage.js\";\n\nexport type ConfidenceLevel =\n | \"unverified\"\n | \"low\"\n | \"trusted\"\n | \"authoritative\"\n | \"stale\";\n\nexport interface ConfidenceThresholds {\n trustedReads: number;\n authoritativeReads: number;\n /** Days without a read after which confidence drops one tier (authoritative → trusted). */\n decayDays: number;\n /** Days without a read after which confidence drops two tiers (e.g. authoritative → low). */\n hardDecayDays: number;\n}\n\nexport const DEFAULT_CONFIDENCE_THRESHOLDS: ConfidenceThresholds = {\n trustedReads: 3,\n authoritativeReads: 10,\n decayDays: 180,\n hardDecayDays: 365,\n};\n\nconst MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/**\n * Compute the trust level of a memory.\n *\n * Base tier is derived from `status + read_count`:\n * - draft → unverified\n * - proposed (low reads) → low\n * - proposed (3+ reads) → trusted\n * - validated (low reads) → trusted\n * - validated (10+ reads) → authoritative\n * - stale / deprecated / rejected → stale\n *\n * On top of the base tier, a TIME DECAY is applied: a memory that has not been\n * read in `decayDays` (default 180) drops one tier, and one not read in\n * `hardDecayDays` (default 365) drops two tiers. The clock starts at\n * `last_read_at` if any, otherwise `created_at` from the frontmatter.\n *\n * The decay never crosses into `stale` (we keep that signal reserved for the\n * verifier). The intent is to surface \"this used to be authoritative but\n * nobody has touched it in a year — verify before quoting it\" without\n * pretending the memory is wrong.\n */\nexport function deriveConfidence(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n thresholds: ConfidenceThresholds = DEFAULT_CONFIDENCE_THRESHOLDS,\n now: Date = new Date(),\n): ConfidenceLevel {\n if (fm.status === \"stale\" || fm.status === \"deprecated\" || fm.status === \"rejected\") return \"stale\";\n\n const baseLevel = baseConfidence(fm, usage, thresholds);\n\n // Apply decay only to tiers worth lowering.\n if (baseLevel !== \"authoritative\" && baseLevel !== \"trusted\") return baseLevel;\n\n const anchor = usage.last_read_at ?? fm.created_at;\n const ageDays = (now.getTime() - new Date(anchor).getTime()) / MS_PER_DAY;\n if (Number.isNaN(ageDays) || ageDays <= 0) return baseLevel;\n\n if (ageDays >= thresholds.hardDecayDays) {\n // Two-tier drop. authoritative → low, trusted → low.\n return \"low\";\n }\n if (ageDays >= thresholds.decayDays) {\n if (baseLevel === \"authoritative\") return \"trusted\";\n if (baseLevel === \"trusted\") return \"low\";\n }\n return baseLevel;\n}\n\nfunction baseConfidence(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n thresholds: ConfidenceThresholds,\n): ConfidenceLevel {\n if (fm.status === \"validated\") {\n return usage.read_count >= thresholds.authoritativeReads\n ? \"authoritative\"\n : \"trusted\";\n }\n if (fm.status === \"proposed\") {\n return usage.read_count >= thresholds.trustedReads ? \"trusted\" : \"low\";\n }\n // draft\n return \"unverified\";\n}\n\nexport interface AutoPromoteRule {\n /** Minimum read_count to promote proposed → validated. */\n minReads: number;\n /** Maximum rejected_count tolerated (memories with more rejections never auto-promote). */\n maxRejections: number;\n}\n\nexport const DEFAULT_AUTO_PROMOTE_RULE: AutoPromoteRule = {\n minReads: 5,\n maxRejections: 0,\n};\n\nexport function isAutoPromoteEligible(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n rule: AutoPromoteRule = DEFAULT_AUTO_PROMOTE_RULE,\n): boolean {\n if (fm.status !== \"proposed\") return false;\n if (usage.rejected_count > rule.maxRejections) return false;\n return usage.read_count >= rule.minReads;\n}\n","/**\n * Specificity (\"surprise\") scoring for memories.\n *\n * hAIve's measured value is preventing agents from reinventing — wrongly — the team's\n * NON-OBVIOUS, arbitrary decisions (e.g. \"public ids are internal id + 100000 prefixed AC-\",\n * \"the status field must be 'OK'/'KO'\"). A capable model already knows generic best practice\n * (\"use Decimal for money\", \"validate input\"), so surfacing that is pure token overhead.\n *\n * `specificityScore` is a cheap, deterministic heuristic that estimates how *unguessable* a\n * memory is: high when it contains concrete, arbitrary signal (string literals, code\n * identifiers, magic numbers, paths, ALLCAPS constants), low when it is generic prose.\n *\n * It is intentionally a heuristic, not a model call — used to (1) bias briefing ranking toward\n * unguessable knowledge, (2) keep a near-empty briefing cheap when nothing team-specific\n * matches, (3) lint low-value memories, and (4) filter auto-capture candidates.\n */\n\n/** Generic best-practice phrases a capable model already knows — low marginal value to surface. */\nconst GENERIC_PHRASES: readonly string[] = [\n \"validate input\", \"sanitize\", \"prepared statement\", \"parameterized quer\",\n \"never commit secret\", \"use environment variable\", \"handle error\", \"write test\",\n \"avoid sql injection\", \"escape html\", \"hash password\", \"use https\", \"least privilege\",\n \"do not hardcode\", \"don't hardcode\", \"single responsibility\", \"keep it dry\",\n \"follow best practice\", \"use meaningful names\", \"add error handling\", \"check for null\",\n \"use try/catch\", \"use async/await\", \"avoid magic number\", \"write clean code\",\n];\n\nconst STRING_LITERAL = /[\"'`][^\"'`\\n]{1,48}[\"'`]/g;\nconst BACKTICK_SPAN = /`[^`\\n]+`/g;\nconst CAMEL_CASE = /\\b[a-zA-Z_][a-zA-Z0-9_]*[a-z][A-Z][a-zA-Z0-9_]*\\b/g;\nconst SNAKE_CASE = /\\b[a-z][a-z0-9]*_[a-z0-9_]+\\b/g;\nconst DOTTED = /\\b\\w+\\.\\w+(?:\\.\\w+)*\\b/g;\nconst MAGIC_NUMBER = /\\b\\d{2,}\\b|\\b\\d+\\.\\d+\\b/g;\nconst FILE_PATH = /\\b[\\w./-]+\\.[a-z]{1,5}\\b/g;\nconst ALLCAPS_CONST = /\\b[A-Z]{2,}(?:_[A-Z0-9]+)+\\b|\\b[A-Z]{3,}\\b/g;\n\nfunction countMatches(text: string, re: RegExp): number {\n const m = text.match(re);\n return m ? m.length : 0;\n}\n\n/**\n * Estimate how unguessable / team-specific a memory body is, in [0, 1].\n * ~0 = generic advice a model already follows by default.\n * ~1 = arbitrary, repo-specific knowledge no model can infer.\n */\nexport function specificityScore(body: string): number {\n const text = (body ?? \"\").trim();\n if (text.length === 0) return 0;\n const lower = text.toLowerCase();\n const words = lower.split(/\\s+/).filter(Boolean).length || 1;\n\n let hits = 0;\n hits += countMatches(text, STRING_LITERAL) * 2;\n hits += countMatches(text, BACKTICK_SPAN) * 2;\n hits += countMatches(text, CAMEL_CASE);\n hits += countMatches(text, SNAKE_CASE);\n hits += countMatches(text, DOTTED);\n hits += countMatches(text, MAGIC_NUMBER);\n hits += countMatches(text, FILE_PATH);\n hits += countMatches(text, ALLCAPS_CONST);\n\n // Density of concrete signal. The denominator scales with length so a long generic\n // paragraph isn't rescued by a single identifier, while a short, dense rule scores high.\n let score = Math.min(1, hits / Math.max(6, words * 0.35));\n\n // A memory that reads like generic advice and carries little concrete signal is capped low.\n const generic = GENERIC_PHRASES.some((p) => lower.includes(p));\n if (generic && hits < 4) score = Math.min(score, 0.22);\n\n return score;\n}\n\n/** Default threshold below which a memory is considered likely-guessable (low marginal value). */\nexport const GUESSABLE_THRESHOLD = 0.3;\n\n/** True when a memory body looks like generic knowledge a capable model already has. */\nexport function isLikelyGuessable(body: string, threshold: number = GUESSABLE_THRESHOLD): boolean {\n return specificityScore(body) < threshold;\n}\n","/**\n * Token budgeting helpers. We use the standard heuristic of ~4 chars per token,\n * which is conservative for English/code/markdown. Callers that need exact\n * counts should plug in a real tokenizer; this module only ever over-estimates,\n * so the user's hard limits are respected.\n */\n\nexport const CHARS_PER_TOKEN = 4;\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nexport interface TruncateOptions {\n /** Maximum tokens allowed in the result (inclusive). */\n maxTokens: number;\n /** Marker inserted where content was dropped. */\n marker?: string;\n /** Where to keep characters from when truncating. Default: head. */\n mode?: \"head\" | \"tail\" | \"middle\";\n}\n\nexport interface TruncateResult {\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n}\n\nconst DEFAULT_MARKER = \"\\n…[truncated]…\\n\";\n\nexport function truncateToTokens(\n input: string,\n options: TruncateOptions,\n): TruncateResult {\n const originalTokens = estimateTokens(input);\n const max = Math.max(0, options.maxTokens);\n if (originalTokens <= max) {\n return { text: input, truncated: false, estimatedTokens: originalTokens, originalTokens };\n }\n\n if (max === 0) {\n return { text: \"\", truncated: true, estimatedTokens: 0, originalTokens };\n }\n\n const marker = options.marker ?? DEFAULT_MARKER;\n const mode = options.mode ?? \"head\";\n const markerTokens = estimateTokens(marker);\n const budgetChars = Math.max(0, (max - markerTokens) * CHARS_PER_TOKEN);\n\n let result: string;\n if (budgetChars === 0) {\n result = \"\";\n } else if (mode === \"tail\") {\n result = marker + input.slice(input.length - budgetChars);\n } else if (mode === \"middle\") {\n const half = Math.floor(budgetChars / 2);\n result = input.slice(0, half) + marker + input.slice(input.length - half);\n } else {\n result = input.slice(0, budgetChars) + marker;\n }\n\n return {\n text: result,\n truncated: true,\n estimatedTokens: estimateTokens(result),\n originalTokens,\n };\n}\n\n/**\n * Allocate a global token budget across N parts with relative weights, then\n * truncate each part to its share. Returns parts in input order, paired with\n * truncate metadata.\n */\nexport interface BudgetPart {\n key: string;\n text: string;\n weight: number;\n mode?: TruncateOptions[\"mode\"];\n}\n\nexport interface BudgetSlice {\n key: string;\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n allocatedTokens: number;\n}\n\nexport function allocateBudget(\n parts: BudgetPart[],\n maxTokens: number,\n): BudgetSlice[] {\n if (parts.length === 0) return [];\n const totalWeight = parts.reduce((s, p) => s + Math.max(0, p.weight), 0);\n if (totalWeight === 0) {\n return parts.map((p) => ({\n key: p.key,\n text: \"\",\n truncated: estimateTokens(p.text) > 0,\n estimatedTokens: 0,\n originalTokens: estimateTokens(p.text),\n allocatedTokens: 0,\n }));\n }\n\n // First pass: allocate by weight, but if a part's content fits in less than\n // its share, redistribute the surplus to others proportionally.\n const allocations = new Map<string, number>();\n let remaining = maxTokens;\n let remainingWeight = totalWeight;\n\n // Sort parts by share fit ascending so small ones consume their share first.\n const sortedByFit = [...parts]\n .map((p) => ({\n key: p.key,\n tokens: estimateTokens(p.text),\n share: (p.weight / totalWeight) * maxTokens,\n part: p,\n }))\n .sort((a, b) => a.tokens - b.tokens);\n\n for (const item of sortedByFit) {\n const myShare = remainingWeight > 0\n ? (item.part.weight / remainingWeight) * remaining\n : 0;\n const grant = Math.min(item.tokens, Math.floor(myShare));\n allocations.set(item.key, grant);\n remaining -= grant;\n remainingWeight -= item.part.weight;\n }\n\n return parts.map((p) => {\n const allocated = allocations.get(p.key) ?? 0;\n const truncated = truncateToTokens(p.text, {\n maxTokens: allocated,\n mode: p.mode ?? \"head\",\n });\n return {\n key: p.key,\n text: truncated.text,\n truncated: truncated.truncated,\n estimatedTokens: truncated.estimatedTokens,\n originalTokens: truncated.originalTokens,\n allocatedTokens: allocated,\n };\n });\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { spawnSync } from \"node:child_process\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const CODE_MAP_FILE = \"code-map.json\";\n\nexport type CodeExportKind =\n | \"function\"\n | \"class\"\n | \"interface\"\n | \"type\"\n | \"const\"\n | \"enum\"\n | \"default\";\n\nexport interface CodeExport {\n name: string;\n kind: CodeExportKind;\n description?: string;\n line: number;\n}\n\nexport interface CodeFileEntry {\n summary?: string;\n exports: CodeExport[];\n loc: number;\n}\n\nexport interface CodeMap {\n version: 1;\n generated_at: string;\n root: string;\n files: Record<string, CodeFileEntry>;\n}\n\nexport interface BuildCodeMapOptions {\n includeExtensions?: string[];\n excludeDirs?: string[];\n /** Include untracked files that are not ignored by git. Default: false when the root is a git repo. */\n includeUntracked?: boolean;\n}\n\nconst DEFAULT_INCLUDE = [\n \".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\",\n \".java\", \".kt\",\n \".py\",\n \".go\",\n \".rb\",\n \".rs\",\n \".cs\",\n \".php\",\n];\nconst DEFAULT_EXCLUDE = [\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \".git\",\n \".next\",\n \".turbo\",\n \".vitest-cache\",\n \"coverage\",\n \"test\",\n \"tests\",\n \"__tests__\",\n \"__mocks__\",\n \"target\", // Maven/Gradle build output\n \".gradle\",\n \"__pycache__\",\n \".pytest_cache\",\n \"vendor\", // Go / PHP\n];\n\nconst TEST_FILE_RE = /\\.(test|spec)\\.[a-z]+$/i;\n\nexport function codeMapPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, CODE_MAP_FILE);\n}\n\nexport async function loadCodeMap(paths: HaivePaths): Promise<CodeMap | null> {\n const file = codeMapPath(paths);\n if (!existsSync(file)) return null;\n return JSON.parse(await readFile(file, \"utf8\")) as CodeMap;\n}\n\nexport async function saveCodeMap(paths: HaivePaths, map: CodeMap): Promise<void> {\n const file = codeMapPath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, JSON.stringify(map, null, 2), \"utf8\");\n}\n\nexport async function buildCodeMap(\n root: string,\n options: BuildCodeMapOptions = {},\n): Promise<CodeMap> {\n const include = new Set(options.includeExtensions ?? DEFAULT_INCLUDE);\n const exclude = new Set(options.excludeDirs ?? DEFAULT_EXCLUDE);\n const files: Record<string, CodeFileEntry> = {};\n\n for await (const abs of collectSourceFiles(root, include, exclude, options.includeUntracked)) {\n const rel = path.relative(root, abs).replace(/\\\\/g, \"/\");\n if (rel.startsWith(\".ai/\")) continue;\n const content = await readFile(abs, \"utf8\");\n const ext = path.extname(abs).toLowerCase();\n const entry = parseFile(content, ext);\n if (entry.exports.length > 0) files[rel] = entry;\n }\n\n return {\n version: 1,\n generated_at: new Date().toISOString(),\n root,\n files,\n };\n}\n\nasync function* collectSourceFiles(\n root: string,\n include: Set<string>,\n exclude: Set<string>,\n includeUntracked: boolean | undefined,\n): AsyncGenerator<string> {\n const gitFiles = gitSourceFiles(root, include, exclude, includeUntracked === true);\n if (gitFiles) {\n for (const rel of gitFiles) yield path.join(root, rel);\n return;\n }\n\n yield* walkSourceFiles(root, include, exclude);\n}\n\nfunction gitSourceFiles(\n root: string,\n include: Set<string>,\n exclude: Set<string>,\n includeUntracked: boolean,\n): string[] | null {\n const args = includeUntracked\n ? [\"ls-files\", \"--cached\", \"--others\", \"--exclude-standard\"]\n : [\"ls-files\", \"--cached\"];\n const result = spawnSync(\"git\", args, {\n cwd: root,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n if (result.status !== 0) return null;\n\n return result.stdout\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .filter((rel) => isIncludedSourcePath(rel, include, exclude))\n .sort();\n}\n\nasync function* walkSourceFiles(\n dir: string,\n include: Set<string>,\n exclude: Set<string>,\n): AsyncGenerator<string> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") && entry.name !== \".github\") {\n // Skip hidden dirs except .github (workflows can be useful)\n if (entry.isDirectory()) continue;\n }\n if (exclude.has(entry.name)) continue;\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkSourceFiles(full, include, exclude);\n } else if (entry.isFile()) {\n const ext = path.extname(entry.name).toLowerCase();\n if (include.has(ext) && !TEST_FILE_RE.test(entry.name)) yield full;\n }\n }\n}\n\nfunction isIncludedSourcePath(\n rel: string,\n include: Set<string>,\n exclude: Set<string>,\n): boolean {\n const normalized = rel.replace(/\\\\/g, \"/\");\n if (normalized.startsWith(\".ai/\")) return false;\n const parts = normalized.split(\"/\");\n if (parts.some((part) => exclude.has(part))) return false;\n const base = parts.at(-1) ?? \"\";\n const ext = path.extname(base).toLowerCase();\n return include.has(ext) && !TEST_FILE_RE.test(base);\n}\n\nconst EXPORT_RE =\n /^export\\s+(?:default\\s+)?(async\\s+)?(function|class|interface|type|const|let|var|enum)\\s+(\\*?)\\s*([A-Za-z_$][\\w$]*)/gm;\n\nconst NAMED_REEXPORT_RE = /^export\\s*\\{([^}]+)\\}/gm;\n\nconst FILE_HEADER_COMMENT_RE = /^\\/\\*\\*([\\s\\S]*?)\\*\\//;\n\n// Java / Kotlin: public/protected class, interface, enum, record, @interface, fun, @RestController etc.\nconst JAVA_DECL_RE =\n /^(?:[ \\t]*)(?:@\\w+\\s+)*(?:public|protected|private|internal)?\\s*(?:static\\s+|final\\s+|abstract\\s+|open\\s+|data\\s+|sealed\\s+)*(?:(class|interface|enum|record|@interface|object)\\s+([A-Z][A-Za-z0-9_$]*)|(fun|def|func|function)\\s+([a-z_][A-Za-z0-9_$]*))/gm;\n\n// Python: def / class at module level (not indented)\nconst PYTHON_DECL_RE = /^(def|class)\\s+([A-Za-z_][A-Za-z0-9_]*)/gm;\n\n// Go: func declarations\nconst GO_DECL_RE = /^func\\s+(?:\\(\\w+\\s+\\*?[A-Za-z_][\\w]*\\)\\s+)?([A-Za-z_][A-Za-z0-9_]*)/gm;\n\n// Rust: pub fn / pub struct / pub enum / pub trait\nconst RUST_DECL_RE =\n /^pub(?:\\([^)]*\\))?\\s+(fn|struct|enum|trait|type|const|impl|mod)\\s+([A-Za-z_][A-Za-z0-9_]*)/gm;\n\nfunction parseFile(source: string, ext: string): CodeFileEntry {\n if (ext === \".java\" || ext === \".kt\") return parseJvmFile(source);\n if (ext === \".py\") return parsePythonFile(source);\n if (ext === \".go\") return parseGoFile(source);\n if (ext === \".rs\") return parseRustFile(source);\n return parseJsFile(source);\n}\n\nfunction parseJsFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n\n let m: RegExpExecArray | null;\n EXPORT_RE.lastIndex = 0;\n while ((m = EXPORT_RE.exec(source))) {\n const kindRaw = m[2] ?? \"\";\n const name = m[4] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"function\" ? \"function\" :\n kindRaw === \"class\" ? \"class\" :\n kindRaw === \"interface\" ? \"interface\" :\n kindRaw === \"type\" ? \"type\" :\n kindRaw === \"enum\" ? \"enum\" : \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n\n NAMED_REEXPORT_RE.lastIndex = 0;\n while ((m = NAMED_REEXPORT_RE.exec(source))) {\n const inside = m[1] ?? \"\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n for (const part of inside.split(\",\")) {\n const cleaned = part.trim().split(/\\s+as\\s+/).pop()?.trim() ?? \"\";\n if (!cleaned || cleaned.startsWith(\"type \")) continue;\n if (exports.some((e) => e.name === cleaned)) continue;\n exports.push({ name: cleaned, kind: \"const\", line: lineIdx + 1 });\n }\n }\n\n const summary = extractFileSummary(source);\n return { ...(summary ? { summary } : {}), exports, loc: source.split(\"\\n\").length };\n}\n\nfunction parseJvmFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n JAVA_DECL_RE.lastIndex = 0;\n while ((m = JAVA_DECL_RE.exec(source))) {\n const kindRaw = m[1] ?? m[3] ?? \"\";\n const name = m[2] ?? m[4] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"class\" || kindRaw === \"record\" || kindRaw === \"object\" ? \"class\" :\n kindRaw === \"interface\" || kindRaw === \"@interface\" ? \"interface\" :\n kindRaw === \"enum\" ? \"enum\" :\n kindRaw === \"fun\" || kindRaw === \"def\" || kindRaw === \"func\" || kindRaw === \"function\" ? \"function\" :\n \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n const summary = extractJavaSummary(source);\n return { ...(summary ? { summary } : {}), exports, loc: lines.length };\n}\n\nfunction parsePythonFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n PYTHON_DECL_RE.lastIndex = 0;\n while ((m = PYTHON_DECL_RE.exec(source))) {\n const keyword = m[1] ?? \"\";\n const name = m[2] ?? \"\";\n if (!name || name.startsWith(\"_\")) continue;\n const kind: CodeExportKind = keyword === \"class\" ? \"class\" : \"function\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractPythonDocstring(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n const summary = extractPythonModuleDocstring(source);\n return { ...(summary ? { summary } : {}), exports, loc: lines.length };\n}\n\nfunction parseGoFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n GO_DECL_RE.lastIndex = 0;\n while ((m = GO_DECL_RE.exec(source))) {\n const name = m[1] ?? \"\";\n if (!name || !/^[A-Z]/.test(name)) continue; // Only exported (uppercase) in Go\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind: \"function\", ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n return { exports, loc: lines.length };\n}\n\nfunction parseRustFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n RUST_DECL_RE.lastIndex = 0;\n while ((m = RUST_DECL_RE.exec(source))) {\n const kindRaw = m[1] ?? \"\";\n const name = m[2] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"struct\" || kindRaw === \"impl\" ? \"class\" :\n kindRaw === \"enum\" ? \"enum\" :\n kindRaw === \"trait\" ? \"interface\" :\n kindRaw === \"fn\" ? \"function\" :\n kindRaw === \"type\" ? \"type\" : \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n return { exports, loc: lines.length };\n}\n\nfunction extractJavaSummary(source: string): string | undefined {\n // Java/Kotlin: file-level Javadoc before first class/interface\n const m = source.match(/^\\/\\*\\*([\\s\\S]*?)\\*\\//);\n if (!m) return undefined;\n const block = (m[1] ?? \"\")\n .split(\"\\n\")\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter((l) => l && !l.startsWith(\"@\"))\n .join(\" \");\n return block ? firstSentence(block) : undefined;\n}\n\nfunction extractPythonDocstring(lines: string[], defLine: number): string | undefined {\n const next = lines[defLine + 1] ?? \"\";\n const stripped = next.trim();\n if (stripped.startsWith('\"\"\"') || stripped.startsWith(\"'''\")) {\n const inner = stripped.replace(/^[\"']{3}/, \"\").replace(/[\"']{3}.*$/, \"\").trim();\n return inner || undefined;\n }\n return undefined;\n}\n\nfunction extractPythonModuleDocstring(source: string): string | undefined {\n const m = source.match(/^[\"']{3}([\\s\\S]*?)[\"']{3}/);\n if (!m) return undefined;\n return firstSentence((m[1] ?? \"\").trim());\n}\n\nfunction computeLineOffsets(source: string): number[] {\n const out: number[] = [0];\n for (let i = 0; i < source.length; i++) {\n if (source[i] === \"\\n\") out.push(i + 1);\n }\n return out;\n}\n\nfunction byteToLine(byte: number, offsets: number[]): number {\n let lo = 0;\n let hi = offsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n const off = offsets[mid] ?? 0;\n if (off <= byte) lo = mid;\n else hi = mid - 1;\n }\n return lo;\n}\n\nfunction extractJSDocAbove(lines: string[], exportLine: number): string | undefined {\n let i = exportLine - 1;\n // Skip blank lines between JSDoc and export\n while (i >= 0 && (lines[i] ?? \"\").trim() === \"\") i--;\n if (i < 0) return undefined;\n const line = (lines[i] ?? \"\").trim();\n\n if (line.startsWith(\"//\")) {\n return line.replace(/^\\/\\/\\s*/, \"\").trim() || undefined;\n }\n\n // Single-line JSDoc: /** Adds two numbers. */\n const singleLine = line.match(/^\\/\\*\\*\\s*(.*?)\\s*\\*\\/\\s*$/);\n if (singleLine && singleLine[1]) {\n return firstSentence(singleLine[1]);\n }\n\n if (line.endsWith(\"*/\")) {\n // Walk up until /**\n const collected: string[] = [];\n // First piece: content of the line before */\n const firstPiece = line.replace(/\\*\\/\\s*$/, \"\").replace(/^\\*\\s?/, \"\").trim();\n if (firstPiece) collected.unshift(firstPiece);\n let j = i - 1;\n while (j >= 0) {\n const l = (lines[j] ?? \"\").trim();\n if (l.startsWith(\"/**\")) {\n const inner = l.replace(/^\\/\\*\\*/, \"\").trim();\n if (inner) collected.unshift(inner);\n break;\n }\n collected.unshift(l.replace(/^\\*\\s?/, \"\").trim());\n j--;\n }\n const joined = collected.join(\" \").trim();\n if (!joined) return undefined;\n return firstSentence(joined);\n }\n return undefined;\n}\n\nfunction firstSentence(text: string): string | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n return trimmed.split(/(?<=\\.)\\s+/)[0]?.trim();\n}\n\nfunction extractFileSummary(source: string): string | undefined {\n const m = source.match(FILE_HEADER_COMMENT_RE);\n if (!m) return undefined;\n const block = (m[1] ?? \"\")\n .split(\"\\n\")\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter(Boolean)\n .join(\" \");\n if (!block) return undefined;\n const sentence = block.split(/(?<=\\.)\\s+/)[0]?.trim();\n return sentence;\n}\n\nexport interface CodeMapQueryOptions {\n file?: string;\n symbol?: string;\n}\n\nexport function queryCodeMap(map: CodeMap, options: CodeMapQueryOptions): {\n files: Array<{ path: string; entry: CodeFileEntry }>;\n} {\n const files: Array<{ path: string; entry: CodeFileEntry }> = [];\n for (const [filePath, entry] of Object.entries(map.files)) {\n if (options.file) {\n if (!filePath.includes(options.file)) continue;\n }\n if (options.symbol) {\n const sym = options.symbol.toLowerCase();\n if (!entry.exports.some((e) => e.name.toLowerCase().includes(sym))) continue;\n }\n files.push({ path: filePath, entry });\n }\n return { files };\n}\n","/**\n * hAIve project configuration — .ai/haive.config.json\n *\n * In autopilot mode, hAIve operates with zero human intervention:\n * - Memories go directly to `validated` (no approval cycle)\n * - `haive sync` auto-approves proposed memories after the delay\n * - The MCP server saves a session recap automatically on exit\n * - `get_briefing` auto-generates a minimal project context if none exists\n * - `haive sync` applies safe self-maintenance repairs (context version, headings,\n * needs_anchor tags, code-map refresh) without human intervention\n *\n * Multi-repo support:\n * - crossRepoSources: pull shared memories from other repos on haive sync\n * - contractFiles: watch API contract files for breaking changes\n * - hubPath: local path to a shared team-knowledge hub repo\n */\nimport { existsSync } from \"node:fs\";\nimport { readFileSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const CONFIG_FILE = \"haive.config.json\";\n\n/** A remote or local repo to pull shared memories from. */\nexport interface CrossRepoSource {\n /** Human-readable name for this source (used in imported memory tags). */\n name: string;\n /** Local filesystem path to the other project's root (relative or absolute). */\n path?: string;\n /** Git URL — clone/fetch performed automatically. */\n git?: string;\n /** Only import memories matching all of these filters. */\n filter?: {\n /** Only import memories with these tags. */\n tags?: string[];\n /** Only import memories of these types. */\n types?: string[];\n };\n}\n\n/** An API contract file to snapshot and monitor for breaking changes. */\nexport interface ContractFile {\n /** Human-readable name for this contract. */\n name: string;\n /** Path to the contract file, relative to the project root. */\n path: string;\n /** Format of the contract file. */\n format: \"openapi\" | \"graphql\" | \"proto\" | \"typescript\" | \"json-schema\";\n}\n\nexport interface HaiveConfig {\n /** Autopilot mode: maximum autonomy, minimum human intervention. Default: false. */\n autopilot?: boolean;\n\n /**\n * Adaptive briefing: when get_briefing finds no team-specific (unguessable) memory for the\n * task/files, trim the auto-generated project context so the call stays near-zero-cost.\n * A capable model needs nothing extra in that case. Curated context is never trimmed.\n * Default: true.\n */\n adaptiveBriefing?: boolean;\n\n /** Default scope for new memories. Default: \"personal\". Autopilot sets \"team\". */\n defaultScope?: \"personal\" | \"team\";\n\n /**\n * Default status for new memories saved via mem_save.\n * Autopilot sets \"validated\" — skips the approval cycle entirely.\n * Default: \"draft\".\n */\n defaultStatus?: \"draft\" | \"validated\";\n\n /** Auto-approve proposed memories after N hours without rejection. Default: null (disabled). */\n autoApproveDelayHours?: number | null;\n\n /**\n * Auto-promote proposed→validated after N reads (overrides DEFAULT_AUTO_PROMOTE_RULE).\n * Autopilot sets 1 (immediate on first use).\n */\n autoPromoteMinReads?: number;\n\n /** Auto-save session recap on MCP server exit. Default: true in autopilot, false otherwise. */\n autoSessionEnd?: boolean;\n\n /**\n * Auto-generate a minimal project context from code-map when project-context.md is still\n * the template. Default: true in autopilot, false otherwise.\n */\n autoContext?: boolean;\n\n /**\n * Safe self-maintenance performed automatically in autopilot mode.\n * These repairs are intentionally conservative: no guessed anchor is applied\n * without strong evidence, but headings/tags/indexes/context metadata can be\n * kept fresh by the tool itself.\n */\n autoRepair?: {\n /** Keep .ai/project-context.md version metadata aligned with package.json. */\n context?: boolean;\n /** Apply safe memory lint fixes: headings and `needs_anchor` tags. */\n corpus?: boolean;\n /** Refresh .ai/code-map.json during sync when needed. */\n codeMap?: boolean;\n /** Best-effort build of code-search embeddings when @hiveai/embeddings is available. */\n codeSearch?: boolean;\n };\n\n // ── Multi-repo support ──────────────────────────────────────────────────\n\n /**\n * Other repos to pull `shared`-scoped memories from during `haive sync`.\n * Each source must have either `path` (local) or `git` (remote URL).\n *\n * Example:\n * { \"name\": \"backend\", \"path\": \"../repo-backend\", \"filter\": { \"tags\": [\"api-contract\"] } }\n */\n crossRepoSources?: CrossRepoSource[];\n\n /**\n * API contract files to snapshot and watch for breaking changes.\n * `haive sync` compares the current file against `.ai/contracts/<name>.lock`\n * and creates a `gotcha` memory if a breaking change is detected.\n *\n * Example:\n * { \"name\": \"payment-api\", \"path\": \"docs/openapi.yaml\", \"format\": \"openapi\" }\n */\n contractFiles?: ContractFile[];\n\n /**\n * Local path to a shared team-knowledge hub repo.\n * Used by `haive hub pull` and `haive hub push`.\n * Can be relative (resolved from project root) or absolute.\n */\n hubPath?: string;\n\n /**\n * Lock file paths to watch for dependency version changes.\n * Auto-detected if not specified (package.json, pom.xml, go.mod, etc.).\n * Set to [] to disable dependency tracking entirely.\n */\n dependencyFiles?: string[];\n\n /**\n * Agent-enforcement settings. Enabled by default so initialized projects\n * treat hAIve as infrastructure, not an optional convention.\n */\n enforcement?: {\n /** Enforcement posture: advisory reports only, warn in hooks, or block workflow gates. */\n mode?: \"off\" | \"advisory\" | \"strict\";\n /** Require get_briefing / mem_relevant_to before state-changing MCP tools. */\n requireBriefingFirst?: boolean;\n /** Require a session recap before pre-push / CI gates pass. */\n requireSessionRecap?: boolean;\n /** Require memory anchor verification before pre-commit / CI gates pass. */\n requireMemoryVerify?: boolean;\n /** Block changes when anchored decisions/gotchas have become stale. */\n blockStaleDecisionChanges?: boolean;\n /** Require changed files to be covered by relevant surfaced decisions/policies. */\n requireDecisionCoverage?: boolean;\n /**\n * How hard the pre-commit anti-pattern gate blocks a matching attempt/gotcha:\n * - off: never block on anti-patterns (report only)\n * - review: block only on a very strong semantic match (score ≥ 0.75) — soft, legacy default\n * - anchored: ALSO block when a high-confidence anti-pattern is anchored to a touched file\n * and corroborated by the diff (literal token or semantic ≥ 0.45). High precision.\n * - strict: block on any high-confidence anti-pattern match (anchor, literal, or semantic)\n * Config/docs-only commits are always downgraded regardless of this setting.\n * Default: \"anchored\" — makes \"known bad approaches are blocked\" true for the precise case.\n */\n antiPatternGate?: \"off\" | \"review\" | \"anchored\" | \"strict\";\n /**\n * Default unread-age window (in days) for `haive memory archive` corpus decay.\n * A noisy or stale corpus is actively harmful — it makes the agent follow outdated policy.\n * Default: 180.\n */\n decayAfterDays?: number;\n /** Minimum score required for strict enforcement gates. */\n scoreThreshold?: number;\n /** Remove generated hAIve runtime/cache files during cleanup gates. */\n cleanupGeneratedArtifacts?: boolean;\n /**\n * MCP tool surface:\n * - enforcement: compact default harness for coding agents\n * - maintenance: corpus/admin tools for humans and team stewards\n * - experimental: research/diagnostic tools that are not core product surface\n * - full: legacy alias for experimental\n */\n toolProfile?: \"enforcement\" | \"maintenance\" | \"experimental\" | \"full\";\n /** Named memory/policy families enabled for this project. */\n policyPacks?: string[];\n };\n}\n\nexport const DEFAULT_CONFIG: HaiveConfig = {\n autopilot: false,\n defaultScope: \"personal\",\n defaultStatus: \"draft\",\n autoApproveDelayHours: null,\n autoPromoteMinReads: 5,\n autoSessionEnd: false,\n autoContext: false,\n autoRepair: {\n context: false,\n corpus: false,\n codeMap: false,\n codeSearch: false,\n },\n enforcement: {\n mode: \"strict\",\n requireBriefingFirst: true,\n requireSessionRecap: true,\n requireMemoryVerify: true,\n blockStaleDecisionChanges: true,\n requireDecisionCoverage: true,\n antiPatternGate: \"anchored\",\n scoreThreshold: 80,\n cleanupGeneratedArtifacts: true,\n toolProfile: \"enforcement\",\n policyPacks: [\"architecture\", \"gotchas\", \"security\", \"domain\", \"release\"],\n },\n};\n\nexport const AUTOPILOT_DEFAULTS: HaiveConfig = {\n autopilot: true,\n defaultScope: \"team\",\n defaultStatus: \"validated\",\n autoApproveDelayHours: 72,\n autoPromoteMinReads: 1,\n autoSessionEnd: true,\n autoContext: true,\n autoRepair: {\n context: true,\n corpus: true,\n codeMap: true,\n codeSearch: true,\n },\n enforcement: {\n mode: \"strict\",\n requireBriefingFirst: true,\n requireSessionRecap: true,\n requireMemoryVerify: true,\n blockStaleDecisionChanges: true,\n requireDecisionCoverage: true,\n antiPatternGate: \"anchored\",\n scoreThreshold: 85,\n cleanupGeneratedArtifacts: true,\n toolProfile: \"enforcement\",\n policyPacks: [\"architecture\", \"gotchas\", \"security\", \"domain\", \"release\"],\n },\n};\n\n/** The pre-commit anti-pattern gate hardness levels. */\nexport type AntiPatternGate = \"off\" | \"review\" | \"anchored\" | \"strict\";\n\n/**\n * Single source of truth mapping a configured `antiPatternGate` to the\n * `pre_commit_check` parameters that implement it. Both the git-hook path\n * (`haive enforce check`) and the standalone `haive precommit` command derive\n * their behavior from this so the two surfaces can never drift apart.\n */\nexport function antiPatternGateParams(\n gate: AntiPatternGate,\n): { block_on: \"any\" | \"high-confidence\" | \"never\"; anchored_blocks: boolean } {\n switch (gate) {\n case \"off\":\n return { block_on: \"never\", anchored_blocks: false };\n case \"review\":\n return { block_on: \"high-confidence\", anchored_blocks: false };\n case \"strict\":\n return { block_on: \"any\", anchored_blocks: true };\n case \"anchored\":\n default:\n return { block_on: \"high-confidence\", anchored_blocks: true };\n }\n}\n\nexport function configPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, CONFIG_FILE);\n}\n\nexport async function loadConfig(paths: HaivePaths): Promise<HaiveConfig> {\n const file = configPath(paths);\n if (!existsSync(file)) return { ...DEFAULT_CONFIG };\n try {\n const raw = await readFile(file, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<HaiveConfig>;\n const merged = mergeConfig(DEFAULT_CONFIG, parsed);\n // In autopilot mode, apply autopilot defaults for any field not explicitly set\n if (merged.autopilot) {\n return mergeConfig(AUTOPILOT_DEFAULTS, parsed);\n }\n return merged;\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function loadConfigSync(paths: HaivePaths): HaiveConfig {\n const file = configPath(paths);\n if (!existsSync(file)) return { ...DEFAULT_CONFIG };\n try {\n const parsed = JSON.parse(readFileSync(file, \"utf8\")) as Partial<HaiveConfig>;\n const merged = mergeConfig(DEFAULT_CONFIG, parsed);\n return merged.autopilot\n ? mergeConfig(AUTOPILOT_DEFAULTS, parsed)\n : merged;\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(paths: HaivePaths, config: HaiveConfig): Promise<void> {\n await writeFile(configPath(paths), JSON.stringify(config, null, 2) + \"\\n\", \"utf8\");\n}\n\nfunction mergeConfig(base: HaiveConfig, override: Partial<HaiveConfig>): HaiveConfig {\n return {\n ...base,\n ...override,\n autoRepair: {\n ...base.autoRepair,\n ...override.autoRepair,\n },\n enforcement: {\n ...base.enforcement,\n ...override.enforcement,\n },\n };\n}\n","/**\n * Cross-repo memory import — pulls `shared`-scoped memories from other projects.\n *\n * Strategy:\n * 1. For each CrossRepoSource in haive.config.json, resolve the source root.\n * 2. Load memories from <source>/.ai/memories/ where scope=shared (+ optional filter).\n * 3. Track imports via .ai/.cache/cross-repo/<name>/import-map.json\n * (sourceId → localFilePath).\n * 4. Write new/updated memories to .ai/memories/shared/<source-name>/.\n * 5. Return a report: { imported, updated, skipped, errors }.\n *\n * Imported memories are tagged with `cross-repo:<source-name>` so they are\n * identifiable and excluded from cross-repo-push to prevent echo loops.\n */\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport {\n buildFrontmatter,\n loadMemoriesFromDir,\n resolveHaivePaths,\n serializeMemory,\n} from \"./index.js\";\nimport type { CrossRepoSource, HaiveConfig } from \"./config.js\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport interface CrossRepoReport {\n source: string;\n imported: string[];\n updated: string[];\n skipped: string[];\n errors: string[];\n}\n\ntype ImportMap = Record<string, string>; // sourceId → local absolute filePath\n\nasync function loadImportMap(cacheDir: string): Promise<ImportMap> {\n const mapPath = path.join(cacheDir, \"import-map.json\");\n if (!existsSync(mapPath)) return {};\n try {\n return JSON.parse(await readFile(mapPath, \"utf8\")) as ImportMap;\n } catch {\n return {};\n }\n}\n\nasync function saveImportMap(cacheDir: string, map: ImportMap): Promise<void> {\n await writeFile(path.join(cacheDir, \"import-map.json\"), JSON.stringify(map, null, 2) + \"\\n\", \"utf8\");\n}\n\n/**\n * Pull shared memories from all configured cross-repo sources.\n * Returns one report per source.\n */\nexport async function pullCrossRepoSources(\n paths: HaivePaths,\n config: HaiveConfig,\n projectRoot: string,\n): Promise<CrossRepoReport[]> {\n const sources = config.crossRepoSources ?? [];\n if (sources.length === 0) return [];\n\n const reports: CrossRepoReport[] = [];\n for (const source of sources) {\n reports.push(await pullFromSource(paths, source, projectRoot));\n }\n return reports;\n}\n\nasync function pullFromSource(\n paths: HaivePaths,\n source: CrossRepoSource,\n projectRoot: string,\n): Promise<CrossRepoReport> {\n const report: CrossRepoReport = {\n source: source.name,\n imported: [],\n updated: [],\n skipped: [],\n errors: [],\n };\n\n // Resolve source root\n let sourceRoot: string | null = null;\n if (source.path) {\n const resolved = path.resolve(projectRoot, source.path);\n if (!existsSync(resolved)) {\n report.errors.push(`Path not found: ${resolved}`);\n return report;\n }\n sourceRoot = resolved;\n } else if (source.git) {\n sourceRoot = await cloneOrFetchGitSource(source, paths, report);\n if (!sourceRoot) return report;\n } else {\n report.errors.push(`Source \"${source.name}\" has neither path nor git — skipping.`);\n return report;\n }\n\n const sourcePaths = resolveHaivePaths(sourceRoot);\n if (!existsSync(sourcePaths.memoriesDir)) {\n report.errors.push(`No .ai/memories/ found at ${sourceRoot}`);\n return report;\n }\n\n // Load source memories filtered to scope=shared\n const sourceMemories = (await loadMemoriesFromDir(sourcePaths.memoriesDir)).filter(\n ({ memory }) => {\n const fm = memory.frontmatter;\n if (fm.scope !== \"shared\") return false;\n if (fm.status === \"rejected\" || fm.status === \"deprecated\") return false;\n if (source.filter?.tags && source.filter.tags.length > 0) {\n const hasTag = source.filter.tags.some((t) => fm.tags.includes(t));\n if (!hasTag) return false;\n }\n if (source.filter?.types && source.filter.types.length > 0) {\n if (!source.filter.types.includes(fm.type)) return false;\n }\n return true;\n },\n );\n\n if (sourceMemories.length === 0) {\n report.skipped.push(\"no shared memories found in source\");\n return report;\n }\n\n // Destination: .ai/memories/shared/<source-name>/\n const destDir = path.join(paths.memoriesDir, \"shared\", source.name);\n await mkdir(destDir, { recursive: true });\n\n // Cache dir for import tracking\n const cacheDir = path.join(paths.haiveDir, \".cache\", \"cross-repo\", source.name);\n await mkdir(cacheDir, { recursive: true });\n const importMap = await loadImportMap(cacheDir);\n const mapDirty = false;\n let dirty = mapDirty;\n\n for (const { memory } of sourceMemories) {\n const fm = memory.frontmatter;\n const sourceId = fm.id;\n const importTag = `cross-repo:${source.name}`;\n const tags = [...new Set([...fm.tags, importTag])];\n\n const importedBodyPrefix =\n `> **Imported from \\`${source.name}\\`** (original id: \\`${sourceId}\\`) \\n` +\n `> Imported at: ${new Date().toISOString()}\\n\\n`;\n\n const existingLocalPath = importMap[sourceId];\n\n if (existingLocalPath && existsSync(existingLocalPath)) {\n // Already imported — check if body changed in source\n const existingFiles = await loadMemoriesFromDir(destDir);\n const existingEntry = existingFiles.find(({ filePath }) => filePath === existingLocalPath);\n const sourceBodyStripped = memory.body.trim();\n const existingBodyStripped = (existingEntry?.memory.body ?? \"\")\n .replace(/^>.*\\n>.*\\n\\n/m, \"\")\n .trim();\n\n if (existingBodyStripped === sourceBodyStripped) {\n report.skipped.push(sourceId);\n continue;\n }\n\n // Body changed — update\n const updatedBody = importedBodyPrefix + memory.body;\n if (existingEntry) {\n await writeFile(\n existingLocalPath,\n serializeMemory({ frontmatter: existingEntry.memory.frontmatter, body: updatedBody }),\n \"utf8\",\n );\n }\n report.updated.push(sourceId);\n } else {\n // New import\n const slug = `${source.name}-${fm.id.slice(0, 40)}`;\n const newFm = buildFrontmatter({\n type: fm.type,\n slug,\n scope: \"team\" as const,\n module: undefined,\n status: \"validated\",\n tags,\n domain: fm.domain,\n author: fm.author,\n paths: fm.anchor.paths,\n symbols: fm.anchor.symbols,\n commit: fm.anchor.commit,\n topic: fm.topic ? `${source.name}:${fm.topic}` : undefined,\n });\n\n const body = importedBodyPrefix + memory.body;\n const destPath = path.join(destDir, `${newFm.id}.md`);\n await writeFile(destPath, serializeMemory({ frontmatter: newFm, body }), \"utf8\");\n importMap[sourceId] = destPath;\n dirty = true;\n report.imported.push(sourceId);\n }\n }\n\n if (dirty) await saveImportMap(cacheDir, importMap);\n return report;\n}\n\n/**\n * Clone or fetch a git source into .ai/.cache/cross-repo/<name>/.\n * Returns the resolved local path, or null on error.\n */\nasync function cloneOrFetchGitSource(\n source: CrossRepoSource,\n paths: HaivePaths,\n report: CrossRepoReport,\n): Promise<string | null> {\n const cacheDir = path.join(paths.haiveDir, \".cache\", \"cross-repo\", source.name);\n await mkdir(cacheDir, { recursive: true });\n\n if (existsSync(path.join(cacheDir, \".git\"))) {\n const result = spawnSync(\"git\", [\"fetch\", \"--depth=1\", \"origin\"], {\n cwd: cacheDir,\n encoding: \"utf8\",\n });\n if (result.status !== 0) {\n report.errors.push(`git fetch failed for ${source.name}: ${result.stderr}`);\n return null;\n }\n spawnSync(\"git\", [\"reset\", \"--hard\", \"FETCH_HEAD\"], { cwd: cacheDir });\n } else {\n const result = spawnSync(\n \"git\",\n [\"clone\", \"--depth=1\", source.git!, \".\"],\n { cwd: cacheDir, encoding: \"utf8\" },\n );\n if (result.status !== 0) {\n report.errors.push(`git clone failed for ${source.name}: ${result.stderr}`);\n return null;\n }\n }\n\n return cacheDir;\n}\n","/**\n * Dependency version tracker.\n *\n * During `haive sync`, parse the project's dependency manifest files\n * (package.json, pom.xml, go.mod, Cargo.toml, requirements.txt, etc.),\n * compare against a snapshot stored at `.ai/contracts/deps-<name>.lock`,\n * and return memories that should be marked stale because a dependency\n * they reference has changed version (major bump = breaking change risk).\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport interface DependencySnapshot {\n file: string;\n format: string;\n captured_at: string;\n deps: Record<string, string>; // name → version\n}\n\nexport interface DepChange {\n name: string;\n from: string;\n to: string;\n /** true if the major version number changed */\n isMajorBump: boolean;\n}\n\nexport interface DepTrackResult {\n file: string;\n changes: DepChange[];\n}\n\n// ── Manifest parsers ───────────────────────────────────────────────────────\n\n/** Parse package.json (npm/pnpm/yarn) — returns name→version map */\nfunction parsePackageJson(content: string): Record<string, string> {\n try {\n const pkg = JSON.parse(content) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n };\n return {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n } catch {\n return {};\n }\n}\n\n/** Parse go.mod — returns module→version map */\nfunction parseGoMod(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split(\"\\n\")) {\n const m = line.trim().match(/^(\\S+)\\s+(v[\\d.]+)/);\n if (m?.[1] && m[2]) result[m[1]] = m[2];\n }\n return result;\n}\n\n/** Parse requirements.txt (Python) — returns package→version map */\nfunction parseRequirementsTxt(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split(\"\\n\")) {\n const clean = (line.split(\"#\")[0] ?? \"\").trim();\n const m = clean.match(/^([A-Za-z0-9_.-]+)[=><~!]+(.+)$/);\n if (m?.[1] && m[2]) result[m[1].toLowerCase()] = m[2].trim();\n }\n return result;\n}\n\n/** Parse Cargo.toml (Rust) — returns crate→version map */\nfunction parseCargotoml(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n let inDeps = false;\n for (const line of content.split(\"\\n\")) {\n if (/^\\[(dependencies|dev-dependencies|build-dependencies)\\]/.test(line.trim())) {\n inDeps = true;\n continue;\n }\n if (line.startsWith(\"[\") && !line.includes(\"dependencies\")) {\n inDeps = false;\n continue;\n }\n if (!inDeps) continue;\n const simple = line.match(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/);\n if (simple?.[1] && simple[2]) { result[simple[1]] = simple[2]; continue; }\n const table = line.match(/^(\\w[\\w-]*)\\s*=\\s*\\{[^}]*version\\s*=\\s*\"([^\"]+)\"/);\n if (table?.[1] && table[2]) result[table[1]] = table[2];\n }\n return result;\n}\n\n/** Parse pom.xml (Maven) — returns groupId:artifactId→version map */\nfunction parsePomXml(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n const depRe = /<dependency>[\\s\\S]*?<groupId>([^<]+)<\\/groupId>[\\s\\S]*?<artifactId>([^<]+)<\\/artifactId>[\\s\\S]*?<version>([^<]+)<\\/version>[\\s\\S]*?<\\/dependency>/g;\n let m: RegExpExecArray | null;\n while ((m = depRe.exec(content)) !== null) {\n if (m[1] && m[2] && m[3]) {\n result[`${m[1].trim()}:${m[2].trim()}`] = m[3].trim();\n }\n }\n return result;\n}\n\n// ── Auto-detection of manifest files ──────────────────────────────────────\n\nconst KNOWN_MANIFESTS: Array<{ name: string; parser: (c: string) => Record<string, string> }> = [\n { name: \"package.json\", parser: parsePackageJson },\n { name: \"go.mod\", parser: parseGoMod },\n { name: \"requirements.txt\", parser: parseRequirementsTxt },\n { name: \"Cargo.toml\", parser: parseCargotoml },\n { name: \"pom.xml\", parser: parsePomXml },\n];\n\nfunction getParser(file: string): ((c: string) => Record<string, string>) | null {\n const base = path.basename(file);\n return KNOWN_MANIFESTS.find((m) => m.name === base)?.parser ?? null;\n}\n\n// ── Version comparison ─────────────────────────────────────────────────────\n\nfunction extractMajor(version: string): number | null {\n const clean = version.replace(/^[^0-9]*/, \"\"); // strip ^, ~, >=, v, etc.\n const firstPart = clean.split(\".\")[0];\n if (!firstPart) return null;\n const n = parseInt(firstPart, 10);\n return isNaN(n) ? null : n;\n}\n\nfunction isMajorBump(from: string, to: string): boolean {\n const fromMajor = extractMajor(from);\n const toMajor = extractMajor(to);\n if (fromMajor === null || toMajor === null) return false;\n return toMajor > fromMajor;\n}\n\n// ── Public API ─────────────────────────────────────────────────────────────\n\n/**\n * Resolve which manifest files to track.\n * Uses config.dependencyFiles if set, otherwise auto-detects from KNOWN_MANIFESTS.\n */\nexport function resolveManifestFiles(\n projectRoot: string,\n configuredFiles?: string[],\n): string[] {\n if (configuredFiles !== undefined) {\n // Explicitly configured (can be [] to disable)\n return configuredFiles.map((f) => path.resolve(projectRoot, f)).filter(existsSync);\n }\n return KNOWN_MANIFESTS\n .map(({ name }) => path.join(projectRoot, name))\n .filter(existsSync);\n}\n\n/**\n * Check all manifest files for version changes since last snapshot.\n * Returns one result per file that has changes.\n */\nexport async function trackDependencies(\n projectRoot: string,\n haiveDir: string,\n manifestFiles: string[],\n): Promise<DepTrackResult[]> {\n const contractsDir = path.join(haiveDir, \"contracts\");\n await mkdir(contractsDir, { recursive: true });\n\n const results: DepTrackResult[] = [];\n\n for (const manifestPath of manifestFiles) {\n const parser = getParser(manifestPath);\n if (!parser) continue;\n\n const content = await readFile(manifestPath, \"utf8\");\n const currentDeps = parser(content);\n const lockName = `deps-${path.basename(manifestPath)}.lock`;\n const lockPath = path.join(contractsDir, lockName);\n\n if (!existsSync(lockPath)) {\n // First run — save snapshot, no changes to report\n const snapshot: DependencySnapshot = {\n file: path.relative(projectRoot, manifestPath),\n format: path.basename(manifestPath),\n captured_at: new Date().toISOString(),\n deps: currentDeps,\n };\n await writeFile(lockPath, JSON.stringify(snapshot, null, 2) + \"\\n\", \"utf8\");\n continue;\n }\n\n const snapshot = JSON.parse(await readFile(lockPath, \"utf8\")) as DependencySnapshot;\n const changes: DepChange[] = [];\n\n for (const [name, currentVer] of Object.entries(currentDeps)) {\n const prevVer = snapshot.deps[name];\n if (prevVer && prevVer !== currentVer) {\n changes.push({\n name,\n from: prevVer,\n to: currentVer,\n isMajorBump: isMajorBump(prevVer, currentVer),\n });\n }\n }\n\n if (changes.length > 0) {\n results.push({ file: path.relative(projectRoot, manifestPath), changes });\n // Update snapshot\n const updated: DependencySnapshot = {\n ...snapshot,\n captured_at: new Date().toISOString(),\n deps: currentDeps,\n };\n await writeFile(lockPath, JSON.stringify(updated, null, 2) + \"\\n\", \"utf8\");\n }\n }\n\n return results;\n}\n","/**\n * Contract snapshot and diff watcher.\n *\n * Supports:\n * - OpenAPI/Swagger (JSON or YAML)\n * - GraphQL schema\n * - Protocol Buffers (.proto)\n * - TypeScript declaration files (.d.ts)\n * - JSON Schema\n *\n * `haive snapshot --contract <file>` saves a snapshot to .ai/contracts/<name>.lock\n * `haive sync` compares current file against snapshot and returns BreakingChange[].\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport type { ContractFile } from \"./config.js\";\n\nexport interface ContractSnapshot {\n name: string;\n path: string;\n format: string;\n captured_at: string;\n hash: string; // SHA-256 of file content\n endpoints?: string[]; // OpenAPI: list of \"METHOD /path\"\n types?: string[]; // GraphQL/TS: list of type/interface/message names\n fields?: Record<string, string[]>; // type → list of field names\n raw_lines?: string[]; // fallback: full file lines for line-by-line diff\n}\n\nexport interface BreakingChange {\n kind:\n | \"endpoint_removed\"\n | \"endpoint_added\"\n | \"type_removed\"\n | \"type_added\"\n | \"field_removed\"\n | \"field_added\"\n | \"content_changed\";\n description: string;\n severity: \"breaking\" | \"additive\" | \"unknown\";\n}\n\nexport interface ContractDiffResult {\n contract: string;\n file: string;\n changes: BreakingChange[];\n unchanged: boolean;\n}\n\n// ── Parsers ────────────────────────────────────────────────────────────────\n\nfunction sha256(content: string): string {\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n/** Parse OpenAPI/Swagger — extract endpoint list and schemas */\nfunction parseOpenApi(content: string, file: string): Partial<ContractSnapshot> {\n try {\n let doc: Record<string, unknown>;\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\n // Simple YAML line-based extraction (no full YAML parser dep)\n doc = parseYamlPaths(content);\n } else {\n doc = JSON.parse(content) as Record<string, unknown>;\n }\n const paths = (doc.paths ?? {}) as Record<string, Record<string, unknown>>;\n const endpoints: string[] = [];\n for (const [routePath, methods] of Object.entries(paths)) {\n for (const method of Object.keys(methods)) {\n if ([\"get\",\"post\",\"put\",\"patch\",\"delete\",\"head\",\"options\"].includes(method)) {\n endpoints.push(`${method.toUpperCase()} ${routePath}`);\n }\n }\n }\n // Extract schema/component names\n const schemas = (\n (doc.components as Record<string, unknown> | undefined)?.schemas ??\n (doc.definitions as Record<string, unknown> | undefined) ??\n {}\n ) as Record<string, Record<string, unknown>>;\n const types = Object.keys(schemas);\n const fields: Record<string, string[]> = {};\n for (const [typeName, schema] of Object.entries(schemas)) {\n const props = (schema.properties ?? {}) as Record<string, unknown>;\n fields[typeName] = Object.keys(props);\n }\n return { endpoints, types, fields };\n } catch {\n return {};\n }\n}\n\n/** Naive YAML paths extractor — avoids needing js-yaml dep */\nfunction parseYamlPaths(content: string): Record<string, unknown> {\n const result: Record<string, Record<string, boolean>> = {};\n let currentPath = \"\";\n for (const line of content.split(\"\\n\")) {\n const pathMatch = line.match(/^ (\\/[^\\s:]+):/);\n if (pathMatch?.[1]) {\n currentPath = pathMatch[1];\n result[currentPath] = {};\n continue;\n }\n if (currentPath) {\n const methodMatch = line.match(/^ (get|post|put|patch|delete|head|options):/);\n if (methodMatch?.[1]) (result[currentPath] ??= {})[methodMatch[1]] = true;\n }\n }\n return { paths: result };\n}\n\n/** Parse GraphQL schema — extract type/interface/union/enum names */\nfunction parseGraphQL(content: string): Partial<ContractSnapshot> {\n const types: string[] = [];\n const fields: Record<string, string[]> = {};\n let currentType = \"\";\n\n for (const line of content.split(\"\\n\")) {\n const typeMatch = line.match(/^(?:type|interface|union|enum|input)\\s+(\\w+)/);\n if (typeMatch?.[1]) {\n currentType = typeMatch[1];\n types.push(currentType);\n fields[currentType] = [];\n continue;\n }\n if (currentType && line.trim().startsWith(\"}\")) {\n currentType = \"\";\n continue;\n }\n if (currentType) {\n const fieldMatch = line.match(/^\\s+(\\w+)\\s*[:(]/);\n if (fieldMatch?.[1]) (fields[currentType] ??= []).push(fieldMatch[1]);\n }\n }\n return { types, fields };\n}\n\n/** Parse .proto (Protocol Buffers) — extract message/service names */\nfunction parseProto(content: string): Partial<ContractSnapshot> {\n const types: string[] = [];\n const fields: Record<string, string[]> = {};\n let currentMsg = \"\";\n\n for (const line of content.split(\"\\n\")) {\n const msgMatch = line.match(/^(?:message|service|enum)\\s+(\\w+)/);\n if (msgMatch?.[1]) {\n currentMsg = msgMatch[1];\n types.push(currentMsg);\n fields[currentMsg] = [];\n continue;\n }\n if (currentMsg && line.trim() === \"}\") {\n currentMsg = \"\";\n continue;\n }\n if (currentMsg) {\n const fieldMatch = line.match(/^\\s+(?:optional|required|repeated)?\\s*\\w+\\s+(\\w+)\\s*=/);\n if (fieldMatch?.[1]) (fields[currentMsg] ??= []).push(fieldMatch[1]);\n const rpcMatch = line.match(/^\\s+rpc\\s+(\\w+)/);\n if (rpcMatch?.[1]) (fields[currentMsg] ??= []).push(`rpc:${rpcMatch[1]}`);\n }\n }\n return { types, fields };\n}\n\n/** Parse TypeScript .d.ts — extract exported interface/class/type names */\nfunction parseTypescript(content: string): Partial<ContractSnapshot> {\n const types: string[] = [];\n const fields: Record<string, string[]> = {};\n let currentType = \"\";\n let braceDepth = 0;\n\n for (const line of content.split(\"\\n\")) {\n const exportMatch = line.match(/^export\\s+(?:declare\\s+)?(?:interface|class|type|enum)\\s+(\\w+)/);\n if (exportMatch?.[1]) {\n currentType = exportMatch[1];\n types.push(currentType);\n fields[currentType] = [];\n }\n if (currentType) {\n braceDepth += (line.match(/{/g) ?? []).length;\n braceDepth -= (line.match(/}/g) ?? []).length;\n if (braceDepth <= 0 && line.includes(\"}\")) { currentType = \"\"; braceDepth = 0; continue; }\n const memberMatch = line.match(/^\\s+(?:readonly\\s+)?(\\w+)\\s*[?:(!]/);\n if (memberMatch?.[1] && currentType) (fields[currentType] ??= []).push(memberMatch[1]);\n }\n }\n return { types, fields };\n}\n\nfunction parseByFormat(\n content: string,\n format: ContractFile[\"format\"],\n filePath: string,\n): Partial<ContractSnapshot> {\n switch (format) {\n case \"openapi\": return parseOpenApi(content, filePath);\n case \"graphql\": return parseGraphQL(content);\n case \"proto\": return parseProto(content);\n case \"typescript\": return parseTypescript(content);\n case \"json-schema\": {\n try {\n const schema = JSON.parse(content) as Record<string, Record<string, unknown>>;\n const types = Object.keys((schema.definitions ?? schema.properties ?? {}) as Record<string, unknown>);\n return { types };\n } catch { return {}; }\n }\n default: return {};\n }\n}\n\n// ── Diff logic ─────────────────────────────────────────────────────────────\n\nfunction diffLists(before: string[], after: string[], kind: string): BreakingChange[] {\n const changes: BreakingChange[] = [];\n const beforeSet = new Set(before);\n const afterSet = new Set(after);\n for (const item of beforeSet) {\n if (!afterSet.has(item)) {\n const isBreaking = kind === \"endpoint\" || kind === \"field\" || kind === \"type\";\n changes.push({\n kind: `${kind}_removed` as BreakingChange[\"kind\"],\n description: `${kind} removed: ${item}`,\n severity: isBreaking ? \"breaking\" : \"unknown\",\n });\n }\n }\n for (const item of afterSet) {\n if (!beforeSet.has(item)) {\n changes.push({\n kind: `${kind}_added` as BreakingChange[\"kind\"],\n description: `${kind} added: ${item}`,\n severity: \"additive\",\n });\n }\n }\n return changes;\n}\n\nfunction diffSnapshots(before: ContractSnapshot, after: ContractSnapshot): BreakingChange[] {\n if (before.hash === after.hash) return [];\n\n const changes: BreakingChange[] = [];\n\n // Endpoint diff (OpenAPI)\n if (before.endpoints && after.endpoints) {\n changes.push(...diffLists(before.endpoints, after.endpoints, \"endpoint\"));\n }\n\n // Type diff (all formats)\n if (before.types && after.types) {\n changes.push(...diffLists(before.types, after.types, \"type\"));\n }\n\n // Field diff per type\n if (before.fields && after.fields) {\n const allTypes = new Set([...Object.keys(before.fields), ...Object.keys(after.fields)]);\n for (const typeName of allTypes) {\n const beforeFields = before.fields[typeName] ?? [];\n const afterFields = after.fields[typeName] ?? [];\n const fieldChanges = diffLists(beforeFields, afterFields, \"field\");\n for (const fc of fieldChanges) {\n changes.push({ ...fc, description: `${typeName}.${fc.description}` });\n }\n }\n }\n\n // Fallback: file changed but no structured diff\n if (changes.length === 0) {\n changes.push({\n kind: \"content_changed\",\n description: \"Contract file content changed (no structured diff available)\",\n severity: \"unknown\",\n });\n }\n\n return changes;\n}\n\n// ── Public API ─────────────────────────────────────────────────────────────\n\nexport function contractLockPath(haiveDir: string, name: string): string {\n return path.join(haiveDir, \"contracts\", `${name}.lock`);\n}\n\n/**\n * Take a snapshot of a contract file and save it to .ai/contracts/<name>.lock.\n * Returns the snapshot.\n */\nexport async function snapshotContract(\n projectRoot: string,\n haiveDir: string,\n contract: ContractFile,\n): Promise<ContractSnapshot> {\n const filePath = path.resolve(projectRoot, contract.path);\n if (!existsSync(filePath)) {\n throw new Error(`Contract file not found: ${filePath}`);\n }\n const content = await readFile(filePath, \"utf8\");\n const parsed = parseByFormat(content, contract.format, filePath);\n const snapshot: ContractSnapshot = {\n name: contract.name,\n path: contract.path,\n format: contract.format,\n captured_at: new Date().toISOString(),\n hash: sha256(content),\n ...parsed,\n };\n const contractsDir = path.join(haiveDir, \"contracts\");\n await mkdir(contractsDir, { recursive: true });\n await writeFile(contractLockPath(haiveDir, contract.name), JSON.stringify(snapshot, null, 2) + \"\\n\", \"utf8\");\n return snapshot;\n}\n\n/**\n * Compare a contract file against its stored snapshot.\n * Returns the diff result. If no snapshot exists, creates one and returns unchanged.\n */\nexport async function diffContract(\n projectRoot: string,\n haiveDir: string,\n contract: ContractFile,\n): Promise<ContractDiffResult> {\n const filePath = path.resolve(projectRoot, contract.path);\n if (!existsSync(filePath)) {\n return { contract: contract.name, file: contract.path, changes: [], unchanged: true };\n }\n\n const lockPath = contractLockPath(haiveDir, contract.name);\n\n if (!existsSync(lockPath)) {\n // First time — save snapshot\n await snapshotContract(projectRoot, haiveDir, contract);\n return { contract: contract.name, file: contract.path, changes: [], unchanged: true };\n }\n\n const content = await readFile(filePath, \"utf8\");\n const beforeSnapshot = JSON.parse(await readFile(lockPath, \"utf8\")) as ContractSnapshot;\n const afterParsed = parseByFormat(content, contract.format, filePath);\n const afterSnapshot: ContractSnapshot = {\n ...beforeSnapshot,\n hash: sha256(content),\n captured_at: new Date().toISOString(),\n ...afterParsed,\n };\n\n const changes = diffSnapshots(beforeSnapshot, afterSnapshot);\n\n if (changes.length > 0) {\n // Update snapshot to current state\n await writeFile(lockPath, JSON.stringify(afterSnapshot, null, 2) + \"\\n\", \"utf8\");\n }\n\n return {\n contract: contract.name,\n file: contract.path,\n changes,\n unchanged: changes.length === 0,\n };\n}\n\n/**\n * Check all configured contract files for changes.\n */\nexport async function watchContracts(\n projectRoot: string,\n haiveDir: string,\n contractFiles: ContractFile[],\n): Promise<ContractDiffResult[]> {\n const results: ContractDiffResult[] = [];\n for (const contract of contractFiles) {\n results.push(await diffContract(projectRoot, haiveDir, contract));\n }\n return results.filter((r) => !r.unchanged);\n}\n","import { appendFile, mkdir, readFile, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const USAGE_LOG_FILE = \"tool-usage.jsonl\";\nexport const USAGE_LOG_DIR = \".usage\";\n\nexport interface UsageEvent {\n /** ISO timestamp */\n at: string;\n /** Tool name (MCP tool or CLI command) */\n tool: string;\n /** Truncated, non-sensitive snapshot of the input */\n summary?: string;\n}\n\nexport function usageLogPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, USAGE_LOG_DIR, USAGE_LOG_FILE);\n}\n\n/**\n * Append a single usage event to the rolling log. Best-effort: failures are\n * swallowed since logging must never block tool execution.\n */\nexport async function appendUsageEvent(paths: HaivePaths, event: UsageEvent): Promise<void> {\n try {\n const file = usageLogPath(paths);\n const dir = path.dirname(file);\n if (!existsSync(dir)) await mkdir(dir, { recursive: true });\n await appendFile(file, JSON.stringify(event) + \"\\n\", \"utf8\");\n } catch {\n // Logging is best-effort.\n }\n}\n\n/**\n * Read all usage events from disk. Skips malformed lines silently.\n * For very large logs (>50k lines), prefer `streamUsageEvents` (not implemented yet).\n */\nexport async function readUsageEvents(paths: HaivePaths): Promise<UsageEvent[]> {\n const file = usageLogPath(paths);\n if (!existsSync(file)) return [];\n const raw = await readFile(file, \"utf8\");\n const out: UsageEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line) continue;\n try {\n const parsed = JSON.parse(line) as UsageEvent;\n if (parsed.tool && parsed.at) out.push(parsed);\n } catch {\n // skip malformed lines\n }\n }\n return out;\n}\n\nexport interface UsageAggregate {\n total: number;\n by_tool: Array<{ tool: string; count: number; last_used: string }>;\n /** Most-frequently called tools first */\n top: Array<{ tool: string; count: number }>;\n window_start: string | null;\n window_end: string | null;\n}\n\n/**\n * Bucket events by tool, optionally filtered by a since cutoff (ISO date or relative like '7d').\n */\nexport function aggregateUsage(events: UsageEvent[], since?: Date): UsageAggregate {\n const cutoff = since ? since.getTime() : 0;\n const filtered = cutoff > 0\n ? events.filter((e) => Date.parse(e.at) >= cutoff)\n : events;\n\n const counts = new Map<string, { count: number; last: string }>();\n for (const e of filtered) {\n const prior = counts.get(e.tool);\n if (!prior) counts.set(e.tool, { count: 1, last: e.at });\n else {\n prior.count++;\n if (e.at > prior.last) prior.last = e.at;\n }\n }\n\n const by_tool = [...counts.entries()]\n .map(([tool, { count, last }]) => ({ tool, count, last_used: last }))\n .sort((a, b) => b.count - a.count);\n\n const sorted = filtered.slice().sort((a, b) => a.at.localeCompare(b.at));\n\n return {\n total: filtered.length,\n by_tool,\n top: by_tool.slice(0, 10).map(({ tool, count }) => ({ tool, count })),\n window_start: sorted[0]?.at ?? null,\n window_end: sorted[sorted.length - 1]?.at ?? null,\n };\n}\n\n/**\n * Parse a since string: ISO date, or relative like '7d', '24h', '30m'.\n * Returns null when input is empty/undefined.\n */\nexport function parseSince(input: string | undefined): Date | null {\n if (!input) return null;\n const m = input.match(/^(\\d+)([dhm])$/);\n if (m) {\n const n = parseInt(m[1] ?? \"0\", 10);\n const unit = m[2] ?? \"d\";\n const ms = unit === \"d\" ? n * 86400_000 : unit === \"h\" ? n * 3600_000 : n * 60_000;\n return new Date(Date.now() - ms);\n }\n const parsed = new Date(input);\n if (Number.isNaN(parsed.getTime())) return null;\n return parsed;\n}\n\nexport async function usageLogSize(paths: HaivePaths): Promise<{ exists: boolean; size_bytes: number; lines: number }> {\n const file = usageLogPath(paths);\n if (!existsSync(file)) return { exists: false, size_bytes: 0, lines: 0 };\n const st = await stat(file);\n const raw = await readFile(file, \"utf8\");\n return { exists: true, size_bytes: st.size, lines: raw.split(\"\\n\").filter((l) => l).length };\n}\n","/**\n * Named budgets for get_briefing so agents choose quality vs token cost intentionally.\n */\n\nexport type BriefingBudgetPreset = \"quick\" | \"balanced\" | \"deep\";\n\nexport interface BriefingBudgetNumbers {\n max_tokens: number;\n max_memories: number;\n include_module_contexts: boolean;\n}\n\nexport const BRIEFING_PRESET_DEFAULTS: Record<BriefingBudgetPreset, BriefingBudgetNumbers> = {\n /** Fast session start — minimal tokens, skip module CONTEXT.md slices */\n quick: { max_tokens: 2500, max_memories: 5, include_module_contexts: false },\n /** Historical defaults for get_briefing */\n balanced: { max_tokens: 8000, max_memories: 8, include_module_contexts: true },\n /** Deep refactor / onboarding — richer memory surface */\n deep: { max_tokens: 16_000, max_memories: 14, include_module_contexts: true },\n};\n\n/**\n * Merge preset-derived numbers with caller overrides when no preset was selected.\n */\nexport function resolveBriefingBudget(\n preset: BriefingBudgetPreset | undefined,\n overrides: BriefingBudgetNumbers,\n): BriefingBudgetNumbers {\n if (!preset) return { ...overrides };\n const p = BRIEFING_PRESET_DEFAULTS[preset];\n return {\n max_tokens: p.max_tokens,\n max_memories: p.max_memories,\n include_module_contexts: p.include_module_contexts,\n };\n}\n","/**\n * Strip memory markdown down to actionable bullet lines — cheaper for briefing payloads.\n */\n\nconst MAX_DEFAULT_CHARS = 1200;\n\n/**\n * Prefer markdown list lines; fall back to the first substantive paragraph block.\n */\nexport function extractActionsBriefBody(markdown: string, maxChars = MAX_DEFAULT_CHARS): string {\n const stripped = markdown.replace(/\\r/g, \"\").trim();\n if (!stripped) return \"\";\n\n const lines = stripped.split(\"\\n\");\n const bullets: string[] = [];\n for (const line of lines) {\n const m = line.match(/^\\s*[-*+]\\s+(.+)/);\n if (m?.[1]) {\n bullets.push(`- ${m[1].trim()}`);\n if (bullets.join(\"\\n\").length >= maxChars) break;\n }\n }\n if (bullets.length >= 2) {\n let text = bullets.join(\"\\n\");\n if (text.length > maxChars) text = text.slice(0, maxChars).trimEnd() + \"…\";\n return text;\n }\n\n // Single bullet or none — take contiguous non-empty paragraphs (skip headings)\n const paragraphs: string[] = [];\n let buf: string[] = [];\n for (const line of lines) {\n const t = line.trim();\n if (!t) {\n if (buf.length) {\n paragraphs.push(buf.join(\" \").trim());\n buf = [];\n }\n continue;\n }\n if (t.startsWith(\"#\") || t.startsWith(\"```\")) {\n if (buf.length) {\n paragraphs.push(buf.join(\" \").trim());\n buf = [];\n }\n continue;\n }\n buf.push(t);\n }\n if (buf.length) paragraphs.push(buf.join(\" \").trim());\n\n let out = paragraphs[0] ?? stripped.slice(0, maxChars);\n if (!out.trim()) out = stripped.slice(0, maxChars);\n if (out.length > maxChars) out = out.slice(0, maxChars).trimEnd() + \"…\";\n return out;\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { findProjectRoot, resolveHaivePaths } from \"./paths.js\";\n\nconst ROOT_MARKERS = [\".ai\", \".git\", \"package.json\"] as const;\n\nexport interface ResolveProjectInfo {\n cwd: string;\n resolved_root: string;\n haive_project_root_env: string | null;\n explicit_root: boolean;\n haive_dir_exists: boolean;\n memories_dir_exists: boolean;\n runtime_dir: string;\n /** Which of `.ai`, `.git`, `package.json` exist at `resolved_root`. */\n markers_found: string[];\n}\n\nfunction markersAtRoot(root: string): string[] {\n const found: string[] = [];\n for (const m of ROOT_MARKERS) {\n if (existsSync(path.join(root, m))) found.push(m);\n }\n return found;\n}\n\n/**\n * Resolve the hAIve project root for diagnostics (MCP / CLI). Never throws.\n */\nexport function resolveProjectInfo(opts: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n} = {}): ResolveProjectInfo {\n const env = opts.env ?? process.env;\n const cwd = path.resolve(opts.cwd ?? process.cwd());\n const raw = env.HAIVE_PROJECT_ROOT;\n const explicit =\n raw !== undefined && raw !== \"\" ? path.resolve(raw) : null;\n const resolvedRoot = explicit ?? findProjectRoot(cwd);\n const paths = resolveHaivePaths(resolvedRoot);\n return {\n cwd,\n resolved_root: resolvedRoot,\n haive_project_root_env: explicit,\n explicit_root: explicit != null,\n haive_dir_exists: existsSync(paths.haiveDir),\n memories_dir_exists: existsSync(paths.memoriesDir),\n runtime_dir: paths.runtimeDir,\n markers_found: markersAtRoot(resolvedRoot),\n };\n}\n","import type { MemoryType } from \"./types.js\";\n\nconst TYPE_TO_FAMILY: Partial<Record<MemoryType, string>> = {\n architecture: \"architecture\",\n convention: \"pattern\",\n decision: \"decision\",\n gotcha: \"bug\",\n attempt: \"bug\",\n glossary: \"discovery\",\n skill: \"skill\",\n session_recap: \"session\",\n};\n\nfunction slugifyTitle(title: string): string {\n const s = title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return s.length > 0 ? s.slice(0, 60) : \"untitled\";\n}\n\n/**\n * Suggest a stable `topic` frontmatter key (topic-upsert) from type + title.\n */\nexport function suggestTopicKey(\n type: string,\n titleOrPhrase: string,\n): { topic_key: string; family: string } {\n const family = TYPE_TO_FAMILY[type as MemoryType] ?? \"discovery\";\n const slug = slugifyTitle(titleOrPhrase);\n return { topic_key: `${family}/${slug}`, family };\n}\n","import type { LoadedMemory } from \"./loader.js\";\n\nfunction tokenizeDoc(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9_]+/)\n .map((w) => w.trim())\n .filter((w) => w.length >= 2);\n}\n\nfunction memorySearchText(loaded: LoadedMemory): string {\n const fm = loaded.memory.frontmatter;\n return [\n fm.id,\n fm.type,\n fm.tags.join(\" \"),\n loaded.memory.body,\n fm.module ?? \"\",\n fm.topic ?? \"\",\n ...fm.anchor.paths,\n ...fm.anchor.symbols,\n ].join(\" \");\n}\n\nexport interface LexicalRankResult {\n ranked: LoadedMemory[];\n scores: number[];\n}\n\n/**\n * Okapi-BM25–style ranking over a small in-memory corpus (no extra index file).\n */\nexport function rankMemoriesLexical(\n loadedMemories: LoadedMemory[],\n query: string,\n limit: number,\n): LexicalRankResult {\n const qTokens = tokenizeDoc(query);\n if (qTokens.length === 0 || loadedMemories.length === 0) {\n return { ranked: [], scores: [] };\n }\n\n const docs = loadedMemories.map((loaded) => ({\n loaded,\n tokens: tokenizeDoc(memorySearchText(loaded)),\n }));\n\n const N = docs.length;\n const df = new Map<string, number>();\n for (const { tokens } of docs) {\n const seen = new Set(tokens);\n for (const t of seen) {\n df.set(t, (df.get(t) ?? 0) + 1);\n }\n }\n\n const avgdl =\n docs.reduce((s, d) => s + d.tokens.length, 0) / Math.max(N, 1);\n const k1 = 1.2;\n const b = 0.75;\n\n function scoreDoc(tokens: string[]): number {\n if (tokens.length === 0) return 0;\n let score = 0;\n const len = tokens.length;\n const tfCounts = new Map<string, number>();\n for (const t of tokens) {\n tfCounts.set(t, (tfCounts.get(t) ?? 0) + 1);\n }\n\n for (const qt of qTokens) {\n const tf = tfCounts.get(qt) ?? 0;\n if (tf === 0) continue;\n const dfi = df.get(qt) ?? 0;\n const idf = Math.log(1 + (N - dfi + 0.5) / (dfi + 0.5));\n const denom = tf + k1 * (1 - b + (b * len) / avgdl);\n const okapiTf = (tf * (k1 + 1)) / denom;\n score += idf * okapiTf;\n }\n return score;\n }\n\n const scored = docs\n .map(({ loaded, tokens }) => ({ loaded, score: scoreDoc(tokens) }))\n .filter((x) => x.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n\n return {\n ranked: scored.map((x) => x.loaded),\n scores: scored.map((x) => x.score),\n };\n}\n","import type { LoadedMemory } from \"./loader.js\";\nimport { pathsOverlap } from \"./relevance.js\";\n\nfunction anchorPathsOverlap(\n fmA: LoadedMemory[\"memory\"][\"frontmatter\"],\n fmB: LoadedMemory[\"memory\"][\"frontmatter\"],\n): boolean {\n for (const a of fmA.anchor.paths) {\n for (const b of fmB.anchor.paths) {\n if (pathsOverlap(a, b)) return true;\n }\n }\n return false;\n}\n\nexport function firstMemoryOneLine(body: string): string {\n const heading = body.match(/^\\s*#\\s+(.+)$/m)?.[1]?.trim();\n const line =\n heading ??\n body\n .split(\"\\n\")\n .map((l) => l.trim())\n .find((l) => l.length > 0);\n return (line ?? \"\").slice(0, 280);\n}\n\nexport interface TimelineEntry {\n id: string;\n type: string;\n scope: string;\n created_at: string;\n one_line: string;\n topic?: string;\n}\n\nexport interface CollectTimelineOpts {\n memoryId?: string;\n topic?: string;\n limit: number;\n}\n\n/**\n * Memories related by id seed (related_ids, shared topic, anchor overlap) or by topic alone.\n */\nexport function collectTimelineEntries(\n all: LoadedMemory[],\n opts: CollectTimelineOpts,\n): { entries: TimelineEntry[]; notice?: string } {\n if (!opts.memoryId && !opts.topic) {\n return { entries: [], notice: \"Provide memory_id and/or topic\" };\n }\n\n const byId = new Map(all.map((l) => [l.memory.frontmatter.id, l]));\n\n if (opts.topic && !opts.memoryId) {\n const matches = all.filter((l) => l.memory.frontmatter.topic === opts.topic);\n matches.sort((a, b) =>\n a.memory.frontmatter.created_at.localeCompare(b.memory.frontmatter.created_at),\n );\n return {\n entries: matches.slice(0, opts.limit).map((l) => toEntry(l)),\n };\n }\n\n const seed = byId.get(opts.memoryId!);\n if (!seed) {\n return { entries: [], notice: `No memory with id \"${opts.memoryId}\"` };\n }\n\n const collected = new Set<string>();\n const add = (id: string) => {\n if (byId.has(id)) collected.add(id);\n };\n\n add(seed.memory.frontmatter.id);\n for (const rid of seed.memory.frontmatter.related_ids) add(rid);\n\n const seedTopic = seed.memory.frontmatter.topic;\n if (seedTopic) {\n for (const l of all) {\n if (l.memory.frontmatter.topic === seedTopic) add(l.memory.frontmatter.id);\n }\n }\n\n for (const l of all) {\n if (anchorPathsOverlap(seed.memory.frontmatter, l.memory.frontmatter)) {\n add(l.memory.frontmatter.id);\n }\n }\n\n const firstHop = [...collected];\n for (const id of firstHop) {\n const m = byId.get(id);\n if (!m) continue;\n for (const rid of m.memory.frontmatter.related_ids) add(rid);\n }\n\n let sorted = [...collected]\n .map((id) => byId.get(id)!)\n .filter(Boolean)\n .sort((a, b) =>\n a.memory.frontmatter.created_at.localeCompare(b.memory.frontmatter.created_at),\n );\n\n if (opts.topic) {\n sorted = sorted.filter((l) => l.memory.frontmatter.topic === opts.topic);\n }\n\n return {\n entries: sorted.slice(0, opts.limit).map((l) => toEntry(l)),\n };\n}\n\nfunction toEntry(l: LoadedMemory): TimelineEntry {\n const fm = l.memory.frontmatter;\n const base: TimelineEntry = {\n id: fm.id,\n type: fm.type,\n scope: fm.scope,\n created_at: fm.created_at,\n one_line: firstMemoryOneLine(l.memory.body),\n };\n if (fm.topic !== undefined && fm.topic !== \"\") {\n return { ...base, topic: fm.topic };\n }\n return base;\n}\n","import type { LoadedMemory } from \"./loader.js\";\n\nfunction tokenSetForConflict(loaded: LoadedMemory): Set<string> {\n const fm = loaded.memory.frontmatter;\n const heading = loaded.memory.body.match(/^\\s*#\\s+(.+)$/m)?.[1] ?? \"\";\n const blob = `${fm.id} ${heading} ${loaded.memory.body.slice(0, 2000)}`;\n const tokens = blob\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .map((w) => w.trim())\n .filter((w) => w.length >= 3);\n return new Set(tokens);\n}\n\nfunction jaccard(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 || b.size === 0) return 0;\n let inter = 0;\n for (const x of a) {\n if (b.has(x)) inter++;\n }\n const uni = a.size + b.size - inter;\n return uni === 0 ? 0 : inter / uni;\n}\n\nexport interface ConflictCandidatesOpts {\n sinceDays: number;\n types: string[];\n minJaccard: number;\n maxPairs: number;\n /** Hard cap on memories considered ( avoids O(n²) explosions). */\n maxScan: number;\n}\n\nexport interface ConflictCandidatePair {\n id_a: string;\n id_b: string;\n jaccard: number;\n}\n\nexport interface TopicStatusPair {\n id_a: string;\n id_b: string;\n topic: string;\n status_a: string;\n status_b: string;\n}\n\n/**\n * Same `topic` key with opposed trust (validated vs rejected) — advisory; use `mem_conflicts_with` per id next.\n */\nexport function findTopicStatusConflictPairs(\n memories: LoadedMemory[],\n maxPairs: number,\n): TopicStatusPair[] {\n const byTopic = new Map<string, LoadedMemory[]>();\n for (const l of memories) {\n const topic = l.memory.frontmatter.topic;\n if (!topic || topic.trim() === \"\") continue;\n const g = byTopic.get(topic);\n if (g) g.push(l);\n else byTopic.set(topic, [l]);\n }\n const out: TopicStatusPair[] = [];\n for (const [topic, group] of byTopic) {\n if (group.length < 2) continue;\n for (let i = 0; i < group.length && out.length < maxPairs; i++) {\n for (let j = i + 1; j < group.length && out.length < maxPairs; j++) {\n const sa = group[i]!.memory.frontmatter.status;\n const sb = group[j]!.memory.frontmatter.status;\n if (\n (sa === \"validated\" && sb === \"rejected\") ||\n (sa === \"rejected\" && sb === \"validated\")\n ) {\n out.push({\n id_a: group[i]!.memory.frontmatter.id,\n id_b: group[j]!.memory.frontmatter.id,\n topic,\n status_a: sa,\n status_b: sb,\n });\n }\n }\n }\n }\n return out;\n}\n\n/**\n * Bulk heuristic: lexical similarity pairs for human review → often followed by `mem_conflicts_with`.\n */\nexport function findLexicalConflictPairs(\n memories: LoadedMemory[],\n opts: ConflictCandidatesOpts,\n): { pairs: ConflictCandidatePair[]; scanned: number; truncated: boolean } {\n const cutoff = Date.now() - opts.sinceDays * 86_400_000;\n let pool = memories.filter((l) => {\n const fm = l.memory.frontmatter;\n if (!opts.types.includes(fm.type)) return false;\n const t = Date.parse(fm.created_at);\n return !Number.isNaN(t) && t >= cutoff;\n });\n pool.sort((a, b) =>\n b.memory.frontmatter.created_at.localeCompare(a.memory.frontmatter.created_at),\n );\n let truncated = false;\n if (pool.length > opts.maxScan) {\n pool = pool.slice(0, opts.maxScan);\n truncated = true;\n }\n const sets = pool.map((l) => ({\n id: l.memory.frontmatter.id,\n set: tokenSetForConflict(l),\n }));\n\n const pairs: ConflictCandidatePair[] = [];\n for (let i = 0; i < sets.length; i++) {\n for (let j = i + 1; j < sets.length; j++) {\n const jac = jaccard(sets[i]!.set, sets[j]!.set);\n if (jac >= opts.minJaccard) {\n pairs.push({ id_a: sets[i]!.id, id_b: sets[j]!.id, jaccard: jac });\n }\n }\n }\n pairs.sort((a, b) => b.jaccard - a.jaccard);\n return {\n pairs: pairs.slice(0, opts.maxPairs),\n scanned: pool.length,\n truncated,\n };\n}\n","import { mkdir, readFile, appendFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const RUNTIME_JOURNAL_FILENAME = \"session-journal.ndjson\";\n\nexport interface RuntimeJournalEntry {\n ts: string;\n kind: \"note\" | \"session_end\" | \"mcp\";\n /** Short human or agent message */\n message: string;\n /** Optional MCP tool name for kind=mcp */\n tool?: string;\n /** Arbitrary JSON-serializable metadata */\n meta?: Record<string, unknown>;\n}\n\nexport function runtimeJournalPath(paths: HaivePaths): string {\n return path.join(paths.runtimeDir, RUNTIME_JOURNAL_FILENAME);\n}\n\n/**\n * Append one NDJSON line under `.ai/.runtime/` (untracked by default).\n * Never throws to callers of shutdown hooks — wraps internally.\n */\nexport async function appendRuntimeJournalEntry(\n paths: HaivePaths,\n entry: Omit<RuntimeJournalEntry, \"ts\"> & { ts?: string },\n): Promise<void> {\n try {\n await mkdir(paths.runtimeDir, { recursive: true });\n const line: RuntimeJournalEntry = {\n ts: entry.ts ?? new Date().toISOString(),\n kind: entry.kind,\n message: entry.message,\n ...(entry.tool !== undefined ? { tool: entry.tool } : {}),\n ...(entry.meta !== undefined ? { meta: entry.meta } : {}),\n };\n await appendFile(\n runtimeJournalPath(paths),\n JSON.stringify(line) + \"\\n\",\n \"utf8\",\n );\n } catch {\n // non-fatal — runtime layer must not break tools\n }\n}\n\n/** Read last N valid JSON lines (oldest-first in returned array). */\nexport async function readRuntimeJournalTail(\n paths: HaivePaths,\n limit: number,\n): Promise<RuntimeJournalEntry[]> {\n const file = runtimeJournalPath(paths);\n if (!existsSync(file) || limit <= 0) return [];\n try {\n const raw = await readFile(file, \"utf8\");\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n const parsed: RuntimeJournalEntry[] = [];\n for (const line of lines.slice(-limit)) {\n try {\n parsed.push(JSON.parse(line) as RuntimeJournalEntry);\n } catch {\n /* skip corrupt line */\n }\n }\n return parsed;\n } catch {\n return [];\n }\n}\n","import { mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const BRIEFING_MARKER_TTL_MS = 12 * 60 * 60 * 1000;\nexport const SESSION_RECAP_TTL_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport interface BriefingMarker {\n session_id: string;\n task?: string;\n source: string;\n created_at: string;\n root: string;\n memory_ids?: string[];\n files?: string[];\n}\n\nexport function enforcementDir(paths: HaivePaths): string {\n return path.join(paths.runtimeDir, \"enforcement\");\n}\n\nexport function briefingMarkersDir(paths: HaivePaths): string {\n return path.join(enforcementDir(paths), \"briefings\");\n}\n\nexport function normalizeSessionId(sessionId?: string): string {\n return (sessionId?.trim() || \"default\").replace(/[^a-zA-Z0-9_.-]+/g, \"-\").slice(0, 120);\n}\n\nexport function briefingMarkerPath(paths: HaivePaths, sessionId?: string): string {\n return path.join(briefingMarkersDir(paths), `${normalizeSessionId(sessionId)}.json`);\n}\n\nexport async function writeBriefingMarker(\n paths: HaivePaths,\n input: { sessionId?: string; task?: string; source: string; memoryIds?: string[]; files?: string[] },\n): Promise<BriefingMarker> {\n const marker: BriefingMarker = {\n session_id: normalizeSessionId(input.sessionId),\n ...(input.task?.trim() ? { task: input.task.trim() } : {}),\n ...(input.memoryIds && input.memoryIds.length > 0 ? { memory_ids: [...new Set(input.memoryIds)] } : {}),\n ...(input.files && input.files.length > 0 ? { files: [...new Set(input.files)] } : {}),\n source: input.source,\n created_at: new Date().toISOString(),\n root: paths.root,\n };\n await mkdir(briefingMarkersDir(paths), { recursive: true });\n await writeFile(\n briefingMarkerPath(paths, marker.session_id),\n JSON.stringify(marker, null, 2) + \"\\n\",\n \"utf8\",\n );\n return marker;\n}\n\nexport async function hasRecentBriefingMarker(\n paths: HaivePaths,\n sessionId?: string,\n ttlMs = BRIEFING_MARKER_TTL_MS,\n): Promise<boolean> {\n const now = Date.now();\n const candidates: string[] = [];\n const exact = briefingMarkerPath(paths, sessionId);\n if (existsSync(exact)) candidates.push(exact);\n try {\n const dir = briefingMarkersDir(paths);\n const files = await readdir(dir);\n for (const file of files) {\n if (file.endsWith(\".json\")) candidates.push(path.join(dir, file));\n }\n } catch {\n // no marker directory yet\n }\n\n for (const file of new Set(candidates)) {\n try {\n const marker = JSON.parse(await readFile(file, \"utf8\")) as BriefingMarker;\n const created = Date.parse(marker.created_at);\n if (Number.isFinite(created) && now - created <= ttlMs) return true;\n } catch {\n // ignore corrupt markers\n }\n }\n return false;\n}\n\nexport async function readRecentBriefingMarker(\n paths: HaivePaths,\n sessionId?: string,\n ttlMs = BRIEFING_MARKER_TTL_MS,\n): Promise<BriefingMarker | null> {\n const now = Date.now();\n const candidates: string[] = [];\n const exact = briefingMarkerPath(paths, sessionId);\n if (existsSync(exact)) candidates.push(exact);\n try {\n const dir = briefingMarkersDir(paths);\n const files = await readdir(dir);\n for (const file of files) {\n if (file.endsWith(\".json\")) candidates.push(path.join(dir, file));\n }\n } catch {\n // no marker directory yet\n }\n\n let freshest: BriefingMarker | null = null;\n let freshestTs = 0;\n for (const file of new Set(candidates)) {\n try {\n const marker = JSON.parse(await readFile(file, \"utf8\")) as BriefingMarker;\n const created = Date.parse(marker.created_at);\n if (!Number.isFinite(created) || now - created > ttlMs) continue;\n if (created > freshestTs) {\n freshest = marker;\n freshestTs = created;\n }\n } catch {\n // ignore corrupt markers\n }\n }\n return freshest;\n}\n\nexport function isFreshIsoDate(value: string | Date, ttlMs: number, now = Date.now()): boolean {\n const ts = value instanceof Date ? value.getTime() : Date.parse(value);\n return Number.isFinite(ts) && now - ts <= ttlMs;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\n\nexport interface RetirementSignal {\n retired: boolean;\n reason?: string;\n}\n\nconst RETIRED_TAGS = new Set([\"superseded\", \"obsolete\", \"archived\"]);\n\nconst RETIRED_BODY_PATTERNS: Array<{ re: RegExp; reason: string }> = [\n { re: /\\bfixed\\s+in\\b[\\s\\S]{0,160}\\b(audit|history|historical|obsolete|no longer applies)\\b/i, reason: \"body says this fixed record is audit/history only\" },\n { re: /\\bresolved\\s+in\\b/i, reason: \"body says this was resolved\" },\n { re: /\\bsuperseded\\s+by\\b/i, reason: \"body says this was superseded\" },\n { re: /\\bno\\s+longer\\s+(applies|true|valid)\\b/i, reason: \"body says this no longer applies\" },\n { re: /\\bobsolete\\b/i, reason: \"body says this is obsolete\" },\n];\n\n/**\n * Explicit lifecycle gate for records that should not be fed back to agents as active policy.\n *\n * `status=deprecated/rejected/stale` is already the hard lifecycle signal. This helper covers\n * softer signals that teams naturally write while curating a corpus: an `expires_when` date,\n * a `superseded`/`obsolete` tag, or a short body note saying the attempt is now obsolete.\n *\n * Note: a plain `fixed` tag is intentionally NOT retired by itself. Many teams keep fixed\n * gotchas active as regression guards. To retire one, mark it deprecated, set expires_when,\n * use `obsolete`/`superseded`, or write that the fixed record is kept for audit/history only.\n */\nexport function retirementSignal(\n fm: MemoryFrontmatter,\n body = \"\",\n now: Date = new Date(),\n): RetirementSignal {\n if (fm.status === \"deprecated\" || fm.status === \"rejected\" || fm.status === \"stale\") {\n return { retired: true, reason: `status=${fm.status}` };\n }\n\n if (fm.expires_when) {\n const expiresAt = Date.parse(fm.expires_when);\n if (Number.isFinite(expiresAt) && expiresAt <= now.getTime()) {\n return { retired: true, reason: `expired on ${fm.expires_when.slice(0, 10)}` };\n }\n }\n\n const retiredTag = fm.tags.find((tag) => RETIRED_TAGS.has(tag.toLowerCase()));\n if (retiredTag) {\n return { retired: true, reason: `tagged ${retiredTag}` };\n }\n\n for (const pattern of RETIRED_BODY_PATTERNS) {\n if (pattern.re.test(body)) return { retired: true, reason: pattern.reason };\n }\n\n return { retired: false };\n}\n\nexport function isRetiredMemory(\n fm: MemoryFrontmatter,\n body = \"\",\n now: Date = new Date(),\n): boolean {\n return retirementSignal(fm, body, now).retired;\n}\n","import type { Memory, Sensor } from \"./types.js\";\n\n/**\n * Sensors — the feedback *computational* layer of the harness.\n *\n * A memory's `sensor` turns a documented lesson (gotcha/attempt) into a deterministic\n * check. Unlike semantic anti-pattern matching (probabilistic, warmup-sensitive), a\n * regex sensor fires the same way every time, so a known mistake becomes a permanent\n * guardrail. Phase 1 supports `kind: \"regex\"` only — pure, no I/O. `shell`/`test`\n * sensors are recognized but not executed here (they must run from the CLI).\n */\n\nexport interface SensorHit {\n /** The memory id whose sensor matched. */\n memory_id: string;\n /** The sensor that matched. */\n sensor: Sensor;\n /** Project-relative file the match was found in (when known). */\n file?: string;\n /** The matched line (trimmed, capped) — useful for review output. */\n matched_line?: string;\n /** LLM-facing self-correction message carried from the sensor. */\n message: string;\n severity: Sensor[\"severity\"];\n}\n\n/** A unit of code to scan: a file path plus the text to match against. */\nexport interface SensorTarget {\n /** Project-relative path (used for path scoping and reporting). */\n path: string;\n /**\n * Text to scan. For a diff, pass only the added lines (callers should pre-filter)\n * so a sensor fires on \"you introduced the bad pattern\", not \"you touched a file\n * that merely mentions it\".\n */\n content: string;\n}\n\nfunction normalizeProjectPath(value: string): string {\n return value\n .replace(/\\\\/g, \"/\")\n .replace(/^\\.\\//, \"\")\n .replace(/^[ab]\\//, \"\")\n .replace(/\\/+$/g, \"\");\n}\n\n/**\n * Does this sensor apply to `path`? A sensor with no explicit `paths` (and whose\n * memory has no anchor paths) applies everywhere. Otherwise it applies only to the\n * exact file or directory prefix. Use an explicit directory path (`src/foo/`) when a\n * sensor should cover a whole subtree.\n */\nexport function sensorAppliesToPath(\n sensor: Sensor,\n anchorPaths: string[],\n path: string,\n): boolean {\n const scopes = sensor.paths.length > 0 ? sensor.paths : anchorPaths;\n if (scopes.length === 0) return true;\n const target = normalizeProjectPath(path);\n return scopes.some((rawScope) => {\n const scope = normalizeProjectPath(rawScope);\n if (!scope) return false;\n return target === scope || target.startsWith(`${scope}/`);\n });\n}\n\n/**\n * Compile a regex sensor. Returns null when the sensor is not a runnable regex\n * (wrong kind, missing/invalid pattern) so callers can skip it safely.\n */\nexport function compileRegexSensor(sensor: Sensor): RegExp | null {\n if (sensor.kind !== \"regex\" || !sensor.pattern) return null;\n try {\n // Always multiline so `^`/`$` work per added line; merge with caller flags.\n const flags = new Set([\"m\", ...(sensor.flags ?? \"\").split(\"\")].filter(Boolean));\n return new RegExp(sensor.pattern, [...flags].join(\"\"));\n } catch {\n return null;\n }\n}\n\n/**\n * Run a single regex sensor over one target. Returns the first matching line as a hit,\n * or null. Deterministic and side-effect-free.\n */\nexport function runRegexSensor(\n memoryId: string,\n sensor: Sensor,\n target: SensorTarget,\n): SensorHit | null {\n const re = compileRegexSensor(sensor);\n if (!re) return null;\n for (const rawLine of target.content.split(\"\\n\")) {\n // Fresh lastIndex each line (no global flag is forced, but be defensive).\n re.lastIndex = 0;\n if (re.test(rawLine)) {\n return {\n memory_id: memoryId,\n sensor,\n file: target.path,\n matched_line: rawLine.trim().slice(0, 200),\n message: sensor.message,\n severity: sensor.severity,\n };\n }\n }\n return null;\n}\n\n/**\n * Run every memory's regex sensor against every applicable target.\n *\n * Memories without a sensor, or with a non-regex sensor, are skipped (non-regex kinds\n * are the CLI's responsibility). At most one hit per (memory, file) pair is returned.\n */\nexport function runSensors(\n memories: Memory[],\n targets: SensorTarget[],\n): SensorHit[] {\n const hits: SensorHit[] = [];\n for (const memory of memories) {\n const sensor = memory.frontmatter.sensor;\n if (!sensor || sensor.kind !== \"regex\") continue;\n const anchorPaths = memory.frontmatter.anchor.paths;\n for (const target of targets) {\n if (!sensorAppliesToPath(sensor, anchorPaths, target.path)) continue;\n const hit = runRegexSensor(memory.frontmatter.id, sensor, target);\n if (hit) hits.push(hit);\n }\n }\n return hits;\n}\n\n/** Split a unified diff into per-file targets containing only added lines. */\nexport function sensorTargetsFromDiff(diff: string): SensorTarget[] {\n const targets: SensorTarget[] = [];\n let currentPath: string | null = null;\n let added: string[] = [];\n\n const flush = (): void => {\n if (!currentPath || added.length === 0) return;\n targets.push({ path: currentPath, content: added.join(\"\\n\") });\n added = [];\n };\n\n for (const line of diff.split(\"\\n\")) {\n if (line.startsWith(\"diff --git \")) {\n flush();\n currentPath = null;\n continue;\n }\n\n if (line.startsWith(\"+++ \")) {\n flush();\n const raw = line.slice(4).trim();\n currentPath = raw === \"/dev/null\" ? null : normalizeProjectPath(raw);\n continue;\n }\n\n if (line.startsWith(\"+\") && !line.startsWith(\"+++\")) {\n if (!currentPath) currentPath = \"\";\n added.push(line.slice(1));\n }\n }\n flush();\n return targets;\n}\n\n/**\n * Extract the added lines from a unified diff (lines starting with a single `+`,\n * excluding the `+++` file header). Mirrors the diff-handling already used by the\n * anti-pattern tokenizer so sensors fire on introductions, not mere mentions.\n */\nexport function addedLinesFromDiff(diff: string): string {\n const targets = sensorTargetsFromDiff(diff);\n if (targets.length > 0) return targets.map((target) => target.content).join(\"\\n\");\n return diff\n .split(\"\\n\")\n .filter((l) => l.startsWith(\"+\") && !l.startsWith(\"+++\"))\n .map((l) => l.slice(1))\n .join(\"\\n\");\n}\n","import type { Sensor } from \"./types.js\";\n\nconst CODE_TOKEN_RE = /`([^`\\n]{3,80})`|[\"']([A-Za-z0-9_.:-]{3,80})[\"']|\\b([A-Za-z][A-Za-z0-9_.:-]{2,79})\\b/g;\n\nconst SENSOR_STOPWORDS = new Set([\n \"about\", \"after\", \"again\", \"agent\", \"always\", \"anchor\", \"approach\", \"because\",\n \"before\", \"break\", \"broken\", \"cannot\", \"change\", \"code\", \"commit\", \"correct\",\n \"could\", \"default\", \"detect\", \"direct\", \"directory\", \"does\", \"error\", \"failed\",\n \"fails\", \"file\", \"files\", \"future\", \"instead\", \"memory\", \"never\", \"project\",\n \"recorded\", \"repo\", \"return\", \"should\", \"source\", \"string\", \"this\",\n \"tried\", \"true\", \"type\", \"undefined\", \"value\", \"when\", \"where\", \"which\", \"with\",\n \"without\",\n]);\n\nexport interface SensorSuggestionOptions {\n /** Extra paths to put on the sensor. Defaults to the memory anchor paths. */\n paths?: string[];\n}\n\n/**\n * Conservatively suggest a regex sensor from a gotcha/attempt body.\n *\n * This helper intentionally returns null more often than it guesses. Autogenerated\n * sensors start as `warn`, never `block`; humans can promote them after seeing them fire.\n */\nexport function suggestSensorFromMemory(\n body: string,\n anchorPaths: string[],\n options: SensorSuggestionOptions = {},\n): Sensor | null {\n const paths = options.paths ?? anchorPaths;\n if (paths.length === 0) return null;\n\n const negativeText = body.split(/\\*\\*Instead,\\s*use:\\*\\*|^##\\s+Instead\\b/im)[0] ?? body;\n const assignment = pickAssignmentPattern(negativeText);\n const lowercaseValue = assignment ? null : pickLowercaseValuePattern(negativeText);\n const token = assignment?.label ?? lowercaseValue?.label ?? pickDistinctiveToken(negativeText);\n if (!token) return null;\n\n return {\n kind: \"regex\",\n pattern: assignment?.pattern ?? lowercaseValue?.pattern ?? escapeRegExp(token),\n paths,\n message: sensorMessageFromBody(body, token),\n severity: \"warn\",\n autogen: true,\n last_fired: null,\n };\n}\n\nfunction pickLowercaseValuePattern(text: string): { label: string; pattern: string; score: number } | null {\n const candidates: Array<{ label: string; pattern: string; score: number }> = [];\n for (const match of text.matchAll(/\\blowercase\\s+([A-Za-z][A-Za-z0-9_.:-]{2,79})\\s+([a-z][a-z0-9_.:-]{1,40})\\b/g)) {\n const key = match[1] ?? \"\";\n const value = match[2] ?? \"\";\n if (!isDistinctiveToken(key, true) || isBoringValue(value)) continue;\n candidates.push({\n label: `${key}=${value}`,\n pattern: `${escapeRegExp(key)}\\\\s*[:=]\\\\s*[\"']?${escapeRegExp(value)}[\"']?`,\n score: key.length + value.length + 35,\n });\n }\n return candidates.sort((a, b) => b.score - a.score)[0] ?? null;\n}\n\nfunction pickAssignmentPattern(text: string): { label: string; pattern: string; score: number } | null {\n const candidates: Array<{ label: string; pattern: string; score: number }> = [];\n for (const source of assignmentSources(text)) {\n for (const match of source.matchAll(/\\b([A-Za-z][A-Za-z0-9_.:-]{2,79})\\b\\s*(=|:)\\s*[\"']?([A-Za-z0-9_.:-]{2,80})[\"']?/g)) {\n const key = match[1] ?? \"\";\n const operator = match[2] ?? \"\";\n const value = match[3] ?? \"\";\n if (!isDistinctiveToken(key, true) || isBoringValue(value)) continue;\n const label = `${key}${operator}${value}`;\n candidates.push({\n label,\n pattern: `${escapeRegExp(key)}\\\\s*${escapeRegExp(operator)}\\\\s*[\"']?${escapeRegExp(value)}[\"']?`,\n score: label.length + assignmentContextScore(source, match.index ?? 0, match[0].length),\n });\n }\n }\n return candidates.sort((a, b) => b.score - a.score)[0] ?? null;\n}\n\nfunction assignmentContextScore(source: string, index: number, length: number): number {\n const before = source.slice(Math.max(0, index - 50), index).toLowerCase();\n const after = source.slice(index + length, Math.min(source.length, index + length + 50)).toLowerCase();\n const window = `${before} ${after}`;\n let score = 0;\n if (/\\b(bad|failed|fails|broke|broken|wrong|avoid|forbid|forbidden|leaks?)\\b/.test(after)) score += 50;\n if (/do\\s+not|don't|never|should\\s+not|must\\s+not/.test(window)) score += 40;\n if (/\\b(keep|instead|correct|right|use|prefer|allowed)\\b/.test(before)) score -= 60;\n if (/\\b(keep|instead|correct|right|use|prefer|allowed)\\b/.test(after)) score -= 25;\n return score;\n}\n\nfunction assignmentSources(text: string): string[] {\n return [text];\n}\n\nfunction pickDistinctiveToken(text: string): string | null {\n const candidates = new Map<string, { raw: string; score: number }>();\n for (const match of text.matchAll(CODE_TOKEN_RE)) {\n const raw = (match[1] ?? match[2] ?? match[3] ?? \"\").trim();\n const token = raw.replace(/^[^\\w.-]+|[^\\w.-]+$/g, \"\");\n const isCodeLike = Boolean(match[1] ?? match[2]);\n if (!isDistinctiveToken(token, isCodeLike)) continue;\n const key = token.toLowerCase();\n const codeSpanBonus = match[1] ? 20 : match[2] ? 8 : 0;\n const shapeBonus =\n /[-_.:]/.test(token) ? 3 :\n /[A-Z]/.test(token.slice(1)) ? 2 :\n /\\d/.test(token) ? 1 : 0;\n const score = token.length + codeSpanBonus + shapeBonus;\n const existing = candidates.get(key);\n if (!existing || score > existing.score) candidates.set(key, { raw: token, score });\n }\n const best = [...candidates.values()].sort((a, b) => b.score - a.score)[0];\n return best?.raw ?? null;\n}\n\nfunction isDistinctiveToken(token: string, isCodeLike: boolean): boolean {\n if (token.length < 4 || token.length > 80) return false;\n if (/^https?:\\/\\//i.test(token)) return false;\n if (/^\\d+$/.test(token)) return false;\n const lower = token.toLowerCase();\n if (SENSOR_STOPWORDS.has(lower)) return false;\n if (!/[A-Za-z]/.test(token)) return false;\n const shaped = /[-_.:\\d]/.test(token) || /[A-Z]/.test(token.slice(1));\n return shaped || isCodeLike;\n}\n\nfunction isBoringValue(value: string): boolean {\n if (!value || value.length > 80) return true;\n const lower = value.toLowerCase();\n if (lower === \"true\" || lower === \"false\") return false;\n return SENSOR_STOPWORDS.has(lower);\n}\n\nfunction sensorMessageFromBody(body: string, token: string): string {\n const instead = body.match(/\\*\\*Instead,\\s*use:\\*\\*\\s*([^\\n]+)/i)?.[1]?.trim();\n if (instead) return `Avoid ${token}; ${instead}`;\n const firstGuidance = body\n .split(\"\\n\")\n .map((line) => line.replace(/^#+\\s*/, \"\").trim())\n .find((line) => line.length > 0 && !line.startsWith(\"---\"));\n return firstGuidance?.slice(0, 180) || `Avoid ${token}; this matched an autogenerated hAIve sensor.`;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":["path","path","readFile","readdir","existsSync","path","path","path","existsSync","readFile","readdir","readFile","existsSync","path","mkdir","readFile","readdir","writeFile","existsSync","path","existsSync","readFile","writeFile","path","existsSync","mkdir","readFile","writeFile","path","spawnSync","path","existsSync","readFile","writeFile","mkdir","spawnSync","existsSync","readFile","writeFile","mkdir","path","snapshot","existsSync","readFile","writeFile","mkdir","path","mkdir","readFile","stat","existsSync","path","existsSync","path","ROOT_MARKERS","existsSync","path","b","mkdir","readFile","appendFile","existsSync","path","mkdir","readdir","readFile","writeFile","existsSync","path","path"]}
1
+ {"version":3,"sources":["../src/schema.ts","../src/parser.ts","../src/paths.ts","../src/loader.ts","../src/search.ts","../src/verifier.ts","../src/relevance.ts","../src/usage.ts","../src/impact.ts","../src/eval.ts","../src/confidence.ts","../src/distinctive.ts","../src/skill-activation.ts","../src/specificity.ts","../src/token-budget.ts","../src/code-map.ts","../src/config.ts","../src/cross-repo.ts","../src/dep-tracker.ts","../src/contract-watcher.ts","../src/usage-log.ts","../src/briefing-preset.ts","../src/briefing-body.ts","../src/resolve-project.ts","../src/topic-suggest.ts","../src/lexical-rank.ts","../src/memory-timeline.ts","../src/conflict-candidates.ts","../src/runtime-journal.ts","../src/enforcement.ts","../src/memory-lifecycle.ts","../src/sensors.ts","../src/sensor-suggest.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const MemoryScopeSchema = z.enum([\"personal\", \"team\", \"module\", \"shared\"]);\n\nexport const MemoryStatusSchema = z.enum([\n \"draft\",\n \"proposed\",\n \"validated\",\n \"deprecated\",\n \"stale\",\n \"rejected\",\n]);\n\nexport const MemoryTypeSchema = z.enum([\n \"convention\",\n \"decision\",\n \"gotcha\",\n \"architecture\",\n \"glossary\",\n \"skill\", // reusable procedure/playbook for a recurring task (feedforward harness guide)\n \"attempt\", // failed approach — \"tried X, failed because Y, use Z instead\"\n \"session_recap\", // end-of-session summary: goal / accomplished / discoveries / next steps\n]);\n\nexport const AnchorSchema = z.object({\n commit: z.string().optional(),\n paths: z.array(z.string()).default([]),\n symbols: z.array(z.string()).default([]),\n});\n\n/**\n * An executable check derived from a memory — the \"feedback computational\" layer.\n *\n * A `gotcha`/`attempt` is normally feedforward (text the agent reads). A sensor turns\n * that lesson into a deterministic check: when a touched file matches `pattern`, the\n * memory's warning fires regardless of semantic ranking. This closes the harness loop —\n * a documented mistake becomes a permanent guardrail.\n *\n * Phase 1 implements `kind: \"regex\"` only. `shell`/`test` are reserved for a later phase\n * (they require I/O and must run from the CLI, not core).\n */\nexport const SensorSchema = z.object({\n kind: z.enum([\"regex\", \"shell\", \"test\"]).default(\"regex\"),\n /** Regex source (for kind=regex), matched against added diff lines / file content. */\n pattern: z.string().optional(),\n /** Regex flags (e.g. \"i\", \"m\"). Ignored for non-regex kinds. */\n flags: z.string().optional(),\n /** Shell/test command to run (for kind=shell|test). Executed by the CLI, never by core. */\n command: z.string().optional(),\n /** Glob-ish path prefixes the sensor applies to. Falls back to the memory's anchor paths when empty. */\n paths: z.array(z.string()).default([]),\n /** LLM-facing self-correction message: what was done wrong and what to do instead. */\n message: z.string().min(1),\n /** `warn` surfaces in review; `block` can hard-block the commit (only when the gate opts in). */\n severity: z.enum([\"warn\", \"block\"]).default(\"warn\"),\n /** True when hAIve generated this sensor automatically (vs. hand-authored). */\n autogen: z.boolean().default(false),\n /** ISO timestamp of the last time this sensor matched a diff. */\n last_fired: z.string().nullable().default(null),\n});\n\n/**\n * Progressive-disclosure activation triggers for a `skill` memory.\n *\n * A skill is a reusable playbook (feedforward harness guide). Injecting every skill\n * on every briefing bloats the context and dilutes signal (the \"instruction budget\"\n * problem). An `activation` block makes a skill surface ONLY when it is relevant:\n * its keywords match the task, or its globs match the files being edited. A skill\n * that defines `activation` and matches none of it is suppressed from the briefing;\n * a skill with no `activation` block keeps the legacy always-eligible behavior.\n */\nexport const ActivationSchema = z.object({\n /** Case-insensitive substrings matched against the task text. */\n keywords: z.array(z.string()).default([]),\n /** Glob-ish path patterns matched against the files being edited. */\n globs: z.array(z.string()).default([]),\n /** Always activate (rare — for truly universal playbooks). */\n always: z.boolean().default(false),\n});\n\nconst IsoDateString = z\n .union([z.string(), z.date()])\n .transform((v) => (v instanceof Date ? v.toISOString() : v))\n .pipe(z.string().datetime());\n\nexport const MemoryFrontmatterSchema = z\n .object({\n id: z.string().min(1),\n scope: MemoryScopeSchema.default(\"personal\"),\n module: z.string().optional(),\n type: MemoryTypeSchema,\n status: MemoryStatusSchema.default(\"draft\"),\n anchor: AnchorSchema.default({ paths: [], symbols: [] }),\n /** Optional executable check derived from this memory (feedback computational layer). */\n sensor: SensorSchema.optional(),\n /** Optional progressive-disclosure triggers — only meaningful for `type: skill`. */\n activation: ActivationSchema.optional(),\n tags: z.array(z.string()).default([]),\n domain: z.string().optional(),\n author: z.string().optional(),\n created_at: IsoDateString,\n expires_when: z.string().nullable().default(null),\n verified_at: z.string().nullable().default(null),\n stale_reason: z.string().nullable().default(null),\n related_ids: z.array(z.string()).default([]),\n last_read_at: z.string().nullable().default(null),\n topic: z.string().optional(), // stable key for upsert — same topic in same scope → update instead of create\n revision_count: z.number().int().min(0).default(0), // incremented each time a topic upsert occurs\n /**\n * When true, the AI MUST NOT act on this memory autonomously.\n * It must surface the information to the human developer and wait\n * for explicit confirmation before modifying any code.\n * Used for cross-repo breaking changes, dependency bumps, contract diffs.\n */\n requires_human_approval: z.boolean().default(false),\n })\n .refine(\n (data) => data.scope !== \"module\" || !!data.module,\n { message: \"module name is required when scope is 'module'\", path: [\"module\"] },\n );\n\n// Additional fields for cross-repo provenance (stored in frontmatter of imported memories)\nexport const CrossRepoProvenanceSchema = z.object({\n source_name: z.string(), // the crossRepoSources name from haive.config.json\n source_path: z.string(), // original file path in the source repo\n source_id: z.string(), // original memory id\n imported_at: z.string(), // ISO timestamp of import\n}).optional();\n","import matter from \"gray-matter\";\nimport { MemoryFrontmatterSchema } from \"./schema.js\";\nimport type { Activation, Memory, MemoryFrontmatter, Sensor } from \"./types.js\";\n\nconst PRIVATE_BLOCK_RE = /<private>[\\s\\S]*?<\\/private>/g;\n\nexport function stripPrivate(body: string): string {\n return body.replace(PRIVATE_BLOCK_RE, \"\").trimEnd();\n}\n\nexport function parseMemory(raw: string): Memory {\n const parsed = matter(raw);\n const frontmatter = MemoryFrontmatterSchema.parse(parsed.data);\n return {\n frontmatter,\n body: stripPrivate(parsed.content.trim()),\n };\n}\n\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((v) => stripUndefined(v)) as unknown as T;\n }\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = stripUndefined(v);\n }\n return out as T;\n }\n return value;\n}\n\nexport function serializeMemory(memory: Memory): string {\n const clean = stripUndefined(memory.frontmatter) as Record<string, unknown>;\n return matter.stringify(memory.body, clean);\n}\n\nexport function newMemoryId(type: string, slug: string, date = new Date()): string {\n const isoDate = date.toISOString().slice(0, 10);\n const safeSlug = slug\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n return `${isoDate}-${type}-${safeSlug}`;\n}\n\nexport function buildFrontmatter(input: {\n type: MemoryFrontmatter[\"type\"];\n slug: string;\n scope?: MemoryFrontmatter[\"scope\"];\n module?: string;\n tags?: string[];\n domain?: string;\n author?: string;\n paths?: string[];\n symbols?: string[];\n commit?: string;\n topic?: string;\n status?: MemoryFrontmatter[\"status\"];\n relatedIds?: string[];\n sensor?: Sensor;\n activation?: Activation;\n}): MemoryFrontmatter {\n const now = new Date();\n const id = newMemoryId(input.type, input.slug, now);\n return MemoryFrontmatterSchema.parse({\n id,\n scope: input.scope ?? \"personal\",\n module: input.module,\n type: input.type,\n status: input.status ?? \"draft\",\n anchor: {\n commit: input.commit,\n paths: input.paths ?? [],\n symbols: input.symbols ?? [],\n },\n tags: input.tags ?? [],\n domain: input.domain,\n author: input.author,\n created_at: now.toISOString(),\n expires_when: null,\n topic: input.topic,\n sensor: input.sensor,\n activation: input.activation,\n revision_count: 0,\n related_ids: input.relatedIds ?? [],\n });\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport const HAIVE_DIR = \".ai\";\n\nconst ROOT_MARKERS = [\".ai\", \".git\", \"package.json\"];\n\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n let current = path.resolve(startDir);\n const fsRoot = path.parse(current).root;\n while (current !== fsRoot) {\n for (const marker of ROOT_MARKERS) {\n if (existsSync(path.join(current, marker))) return current;\n }\n current = path.dirname(current);\n }\n return path.resolve(startDir);\n}\n\nexport const PROJECT_CONTEXT_FILE = \"project-context.md\";\nexport const MEMORIES_DIR = \"memories\";\n\nexport interface HaivePaths {\n root: string;\n haiveDir: string;\n /** Disposable local layer (session journal, caches). Not team truth — see `.ai/.runtime/` layout. */\n runtimeDir: string;\n projectContext: string;\n memoriesDir: string;\n personalDir: string;\n teamDir: string;\n sharedDir: string;\n moduleDir: string;\n modulesContextDir: string;\n}\n\nexport function resolveHaivePaths(projectRoot: string): HaivePaths {\n const haiveDir = path.join(projectRoot, HAIVE_DIR);\n const memoriesDir = path.join(haiveDir, MEMORIES_DIR);\n return {\n root: projectRoot,\n haiveDir,\n runtimeDir: path.join(haiveDir, \".runtime\"),\n projectContext: path.join(haiveDir, PROJECT_CONTEXT_FILE),\n memoriesDir,\n personalDir: path.join(memoriesDir, \"personal\"),\n teamDir: path.join(memoriesDir, \"team\"),\n sharedDir: path.join(memoriesDir, \"shared\"),\n moduleDir: path.join(memoriesDir, \"module\"),\n modulesContextDir: path.join(haiveDir, \"modules\"),\n };\n}\n\nexport function memoryFilePath(\n paths: HaivePaths,\n scope: \"personal\" | \"team\" | \"module\" | \"shared\",\n id: string,\n module?: string,\n): string {\n const base =\n scope === \"personal\"\n ? paths.personalDir\n : scope === \"team\"\n ? paths.teamDir\n : scope === \"shared\"\n ? paths.sharedDir\n : path.join(paths.moduleDir, module ?? \"_unscoped\");\n return path.join(base, `${id}.md`);\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parseMemory } from \"./parser.js\";\nimport type { Memory } from \"./types.js\";\n\nexport interface LoadedMemory {\n memory: Memory;\n filePath: string;\n}\n\nexport async function listMarkdownFilesRecursive(dir: string): Promise<string[]> {\n const out: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return out;\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await listMarkdownFilesRecursive(full)));\n } else if (entry.isFile() && entry.name.endsWith(\".md\")) {\n out.push(full);\n }\n }\n return out;\n}\n\nexport async function loadMemory(filePath: string): Promise<LoadedMemory> {\n const raw = await readFile(filePath, \"utf8\");\n return { memory: parseMemory(raw), filePath };\n}\n\nexport async function loadMemoriesFromDir(dir: string): Promise<LoadedMemory[]> {\n const files = await listMarkdownFilesRecursive(dir);\n const out: LoadedMemory[] = [];\n for (const file of files) {\n try {\n out.push(await loadMemory(file));\n } catch {\n // Skip unparseable files in v0.1; future: surface a warning channel.\n }\n }\n return out;\n}\n","import type { Memory } from \"./types.js\";\n\nexport function tokenizeQuery(query: string): string[] {\n return query\n .toLowerCase()\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\nexport function literalMatchesAllTokens(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return true;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.every((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nfunction collectAnchorPathTokens(paths: readonly string[]): string[] {\n const out = new Set<string>();\n for (const p of paths) {\n const lower = p.toLowerCase();\n out.add(lower);\n // basename without extension\n const base = lower.split(\"/\").pop() ?? lower;\n const noExt = base.replace(/\\.[a-z0-9]+$/, \"\");\n if (noExt) out.add(noExt);\n // each path segment (helps \"verifier\" match \"src/verifier.ts\")\n for (const segment of lower.split(\"/\")) {\n const seg = segment.replace(/\\.[a-z0-9]+$/, \"\");\n if (seg) out.add(seg);\n }\n }\n return [...out];\n}\n\n/**\n * OR-based fallback: returns true if the memory matches at least one token.\n * Used when all-tokens (AND) search returns 0 results.\n */\nexport function literalMatchesAnyToken(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return false;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.some((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nexport function pickSnippetNeedle(query: string): string {\n const tokens = tokenizeQuery(query);\n if (tokens.length === 0) return query.toLowerCase();\n return [...tokens].sort((a, b) => b.length - a.length)[0]!;\n}\n\nexport function extractSnippet(body: string, needle: string, radius = 40): string {\n const lower = body.toLowerCase();\n const idx = needle ? lower.indexOf(needle) : -1;\n if (idx < 0) {\n return body.slice(0, radius * 3).replace(/\\s+/g, \" \").trim();\n }\n const start = Math.max(0, idx - radius);\n const end = Math.min(body.length, idx + needle.length + radius);\n const snippet = body.slice(start, end).replace(/\\s+/g, \" \").trim();\n return (start > 0 ? \"…\" : \"\") + snippet + (end < body.length ? \"…\" : \"\");\n}\n","import { readFile, readdir, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { globToRegExp, isGlobPath } from \"./relevance.js\";\nimport type { Memory } from \"./types.js\";\n\nexport interface VerifyResult {\n stale: boolean;\n reason: string | null;\n checkedPaths: string[];\n checkedSymbols: string[];\n possibleRenames: string[];\n}\n\nexport interface VerifyOptions {\n /** Project root used to resolve relative anchor paths. */\n projectRoot: string;\n}\n\n/**\n * Verify that a memory's anchor still matches the current code.\n * - Every anchor.paths entry must exist on disk\n * - Every anchor.symbols entry must appear at least once across the anchor.paths\n * files (or any tracked file if no paths are recorded)\n *\n * Anchorless memories (no paths and no symbols) are always considered fresh —\n * staleness only applies to memories that opted into anchoring.\n */\nexport async function verifyAnchor(\n memory: Memory,\n options: VerifyOptions,\n): Promise<VerifyResult> {\n const anchor = memory.frontmatter.anchor;\n const checkedPaths = anchor.paths;\n const checkedSymbols = anchor.symbols;\n\n if (checkedPaths.length === 0 && checkedSymbols.length === 0) {\n return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };\n }\n\n const missingPaths: string[] = [];\n const existingAbsPaths: string[] = [];\n for (const rel of checkedPaths) {\n if (isGlobPath(rel)) {\n const matches = await findGlobMatches(rel, options.projectRoot);\n if (matches.length > 0) {\n existingAbsPaths.push(...matches.map((m) => path.join(options.projectRoot, m)));\n } else {\n missingPaths.push(rel);\n }\n continue;\n }\n const abs = path.isAbsolute(rel) ? rel : path.join(options.projectRoot, rel);\n if (existsSync(abs)) {\n existingAbsPaths.push(...await readableFilesForAnchor(abs));\n } else {\n missingPaths.push(rel);\n }\n }\n\n if (missingPaths.length > 0) {\n const possibleRenames = await findPossibleRenames(missingPaths, options.projectRoot);\n return {\n stale: true,\n reason: `anchor path(s) no longer exist: ${missingPaths.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n possibleRenames,\n };\n }\n\n if (checkedSymbols.length > 0) {\n if (existingAbsPaths.length === 0) {\n return {\n stale: true,\n reason: `cannot verify symbols (${checkedSymbols.join(\", \")}): no anchor paths recorded`,\n checkedPaths,\n checkedSymbols,\n possibleRenames: [],\n };\n }\n const missingSymbols: string[] = [];\n for (const sym of checkedSymbols) {\n let found = false;\n for (const file of existingAbsPaths) {\n try {\n const contents = await readFile(file, \"utf8\");\n if (contents.includes(sym)) {\n found = true;\n break;\n }\n } catch {\n // unreadable file; treat as not finding the symbol here\n }\n }\n if (!found) missingSymbols.push(sym);\n }\n if (missingSymbols.length > 0) {\n return {\n stale: true,\n reason: `anchor symbol(s) not found in any anchor path: ${missingSymbols.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n possibleRenames: [],\n };\n }\n }\n\n return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };\n}\n\nasync function findPossibleRenames(\n missingPaths: string[],\n projectRoot: string,\n): Promise<string[]> {\n const basenames = new Set(missingPaths.map((p) => path.basename(p)));\n const found: string[] = [];\n try {\n await walkDir(projectRoot, projectRoot, basenames, found, 0);\n } catch {\n // best-effort\n }\n return found;\n}\n\nasync function findGlobMatches(pattern: string, projectRoot: string): Promise<string[]> {\n const re = globToRegExp(pattern);\n const found: string[] = [];\n try {\n await walkAllFiles(projectRoot, projectRoot, found, 0, re);\n } catch {\n // best-effort\n }\n return found;\n}\n\nasync function readableFilesForAnchor(abs: string): Promise<string[]> {\n try {\n const s = await stat(abs);\n if (s.isDirectory()) {\n const out: string[] = [];\n await walkReadableFiles(abs, out, 0);\n return out;\n }\n if (s.isFile()) return [abs];\n } catch {\n return [abs];\n }\n return [abs];\n}\n\nasync function walkReadableFiles(dir: string, found: string[], depth: number): Promise<void> {\n if (depth > 6) return;\n let entries: string[];\n try {\n entries = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const name of entries) {\n if (name.startsWith(\".\") || name === \"node_modules\") continue;\n const abs = path.join(dir, name);\n try {\n const s = await stat(abs);\n if (s.isDirectory()) await walkReadableFiles(abs, found, depth + 1);\n else if (s.isFile()) found.push(abs);\n } catch {\n continue;\n }\n }\n}\n\nasync function walkAllFiles(\n dir: string,\n root: string,\n found: string[],\n depth: number,\n match: RegExp,\n): Promise<void> {\n if (depth > 12) return;\n let entries: string[];\n try {\n entries = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const name of entries) {\n if (name === \"node_modules\" || name === \".git\" || name === \".ai\") continue;\n const abs = path.join(dir, name);\n try {\n const s = await stat(abs);\n if (s.isDirectory()) {\n await walkAllFiles(abs, root, found, depth + 1, match);\n } else if (s.isFile()) {\n const rel = path.relative(root, abs).replace(/\\\\/g, \"/\");\n if (match.test(rel)) found.push(rel);\n }\n } catch {\n continue;\n }\n }\n}\n\nasync function walkDir(\n dir: string,\n root: string,\n targets: Set<string>,\n found: string[],\n depth: number,\n): Promise<void> {\n if (depth > 6) return;\n let entries: string[];\n try {\n entries = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const name of entries) {\n if (name.startsWith(\".\") || name === \"node_modules\") continue;\n const abs = path.join(dir, name);\n let isDir = false;\n try {\n isDir = (await stat(abs)).isDirectory();\n } catch {\n continue;\n }\n if (isDir) {\n await walkDir(abs, root, targets, found, depth + 1);\n } else if (targets.has(name)) {\n found.push(path.relative(root, abs));\n }\n }\n}\n","import path from \"node:path\";\nimport type { LoadedMemory } from \"./loader.js\";\n\n/**\n * Tag stamped on memories that were pre-seeded from a stack pack at `haive init`\n * (generic framework knowledge the model already largely knows, not repo-specific\n * institutional knowledge). Briefing ranking caps these at `background` priority so\n * a generic seed never displaces a repo-specific memory — unless the seed has been\n * anchored to a file the agent is actually editing.\n */\nexport const STACK_PACK_TAG = \"stack-pack\";\n\n/** True when a memory was pre-seeded from a stack pack (carries {@link STACK_PACK_TAG}). */\nexport function isStackPackSeed(fm: { tags?: string[] } | null | undefined): boolean {\n return Boolean(fm?.tags?.includes(STACK_PACK_TAG));\n}\n\nconst MODULE_PATTERNS = [\n /^packages\\/([^/]+)\\//,\n /^apps\\/([^/]+)\\//,\n /^modules\\/([^/]+)\\//,\n /^src\\/([^/]+)\\//,\n /^libs\\/([^/]+)\\//,\n /^services\\/([^/]+)\\//,\n /^internal\\/([^/]+)\\//,\n /^projects\\/([^/]+)\\//, // Nx layout\n /^cmd\\/([^/]+)\\//, // Go-style\n];\n\n/**\n * Best-effort inference: given a list of file paths, infer module names from\n * conventional layouts (packages/X/, apps/X/, modules/X/, src/X/).\n */\nexport function inferModulesFromPaths(filePaths: string[]): string[] {\n const out = new Set<string>();\n for (const p of filePaths) {\n const norm = normalize(p);\n for (const re of MODULE_PATTERNS) {\n const m = norm.match(re);\n if (m && m[1]) out.add(m[1]);\n }\n }\n return [...out].sort();\n}\n\n/**\n * Path overlap: returns true if `a` and `b` refer to the same path or one is a\n * parent of the other. Both inputs are treated as POSIX-style relative paths.\n */\nexport function pathsOverlap(a: string, b: string): boolean {\n const na = normalize(a);\n const nb = normalize(b);\n if (isGlobPath(na)) return globOverlapsPath(na, nb);\n if (isGlobPath(nb)) return globOverlapsPath(nb, na);\n if (na === nb) return true;\n return na.startsWith(nb + \"/\") || nb.startsWith(na + \"/\");\n}\n\nexport function memoryMatchesAnchorPaths(\n memory: LoadedMemory[\"memory\"],\n inputPaths: string[],\n): boolean {\n const anchorPaths = memory.frontmatter.anchor.paths;\n if (anchorPaths.length === 0) return false;\n for (const ap of anchorPaths) {\n for (const ip of inputPaths) {\n if (pathsOverlap(ap, ip)) return true;\n }\n }\n return false;\n}\n\nfunction normalize(p: string): string {\n // Strip leading \"./\" and trailing \"/\", normalize separators.\n return p.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function isGlobPath(p: string): boolean {\n return /[*?\\[]/.test(p);\n}\n\nexport function globToRegExp(pattern: string): RegExp {\n const norm = normalize(pattern);\n let out = \"^\";\n for (let i = 0; i < norm.length; i++) {\n const ch = norm[i]!;\n const next = norm[i + 1];\n const afterNext = norm[i + 2];\n if (ch === \"*\" && next === \"*\" && afterNext === \"/\") {\n out += \"(?:.*/)?\";\n i += 2;\n } else if (ch === \"*\" && next === \"*\") {\n out += \".*\";\n i++;\n } else if (ch === \"*\") {\n out += \"[^/]*\";\n } else if (ch === \"?\") {\n out += \"[^/]\";\n } else {\n out += ch.replace(/[|\\\\{}()[\\]^$+?.]/g, \"\\\\$&\");\n }\n }\n out += \"$\";\n return new RegExp(out);\n}\n\nfunction globOverlapsPath(globPattern: string, candidate: string): boolean {\n const normalizedCandidate = normalize(candidate);\n if (globToRegExp(globPattern).test(normalizedCandidate)) return true;\n const prefix = globLiteralPrefix(globPattern);\n if (!prefix || prefix.split(\"/\").length < 2) return false;\n return normalizedCandidate === prefix ||\n normalizedCandidate.startsWith(prefix + \"/\") ||\n prefix.startsWith(normalizedCandidate + \"/\");\n}\n\nfunction globLiteralPrefix(pattern: string): string {\n const norm = normalize(pattern);\n const firstGlob = norm.search(/[*?\\[]/);\n if (firstGlob < 0) return norm;\n const slash = norm.slice(0, firstGlob).lastIndexOf(\"/\");\n return slash < 0 ? \"\" : norm.slice(0, slash);\n}\n\nexport function relPathFrom(root: string, abs: string): string {\n return path.relative(root, abs).replace(/\\\\/g, \"/\");\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport interface MemoryUsage {\n read_count: number;\n last_read_at: string | null;\n rejected_count: number;\n last_rejected_at: string | null;\n rejection_reason: string | null;\n /**\n * Number of times the memory was explicitly confirmed *useful* — i.e. an agent\n * or human recorded that it changed what they did (the closed-loop \"applied\"\n * outcome, recorded via `mem_feedback`). A far stronger utility signal than a\n * read: a memory can be surfaced many times and ignored, but `applied` means it\n * demonstrably steered work. Drives impact scoring in {@link ./impact.js}.\n */\n applied_count: number;\n last_applied_at: string | null;\n}\n\nexport interface UsageIndex {\n version: 1;\n updated_at: string;\n by_id: Record<string, MemoryUsage>;\n}\n\nexport const USAGE_FILE = \"usage.json\";\n\nexport function emptyUsage(): MemoryUsage {\n return {\n read_count: 0,\n last_read_at: null,\n rejected_count: 0,\n last_rejected_at: null,\n rejection_reason: null,\n applied_count: 0,\n last_applied_at: null,\n };\n}\n\n/**\n * Normalize a possibly-partial stored usage record (older `usage.json` files\n * predate the `applied_*` fields). Always returns a full {@link MemoryUsage}.\n */\nfunction normalizeUsage(stored: Partial<MemoryUsage> | undefined): MemoryUsage {\n return { ...emptyUsage(), ...(stored ?? {}) };\n}\n\nexport function emptyUsageIndex(): UsageIndex {\n return {\n version: 1,\n updated_at: new Date().toISOString(),\n by_id: {},\n };\n}\n\nexport function usagePath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, \".cache\", USAGE_FILE);\n}\n\nexport async function loadUsageIndex(paths: HaivePaths): Promise<UsageIndex> {\n const file = usagePath(paths);\n if (!existsSync(file)) return emptyUsageIndex();\n const raw = await readFile(file, \"utf8\");\n try {\n const parsed = JSON.parse(raw) as UsageIndex;\n if (parsed.version !== 1) return emptyUsageIndex();\n return parsed;\n } catch {\n return emptyUsageIndex();\n }\n}\n\nexport async function saveUsageIndex(paths: HaivePaths, index: UsageIndex): Promise<void> {\n const file = usagePath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n index.updated_at = new Date().toISOString();\n await writeFile(file, JSON.stringify(index, null, 2), \"utf8\");\n}\n\nexport function getUsage(index: UsageIndex, id: string): MemoryUsage {\n return normalizeUsage(index.by_id[id]);\n}\n\nexport function bumpRead(index: UsageIndex, ids: string[]): UsageIndex {\n if (ids.length === 0) return index;\n const now = new Date().toISOString();\n for (const id of ids) {\n const current = normalizeUsage(index.by_id[id]);\n index.by_id[id] = {\n ...current,\n read_count: current.read_count + 1,\n last_read_at: now,\n };\n }\n return index;\n}\n\nexport function recordRejection(\n index: UsageIndex,\n id: string,\n reason: string | null,\n): UsageIndex {\n const current = normalizeUsage(index.by_id[id]);\n const now = new Date().toISOString();\n index.by_id[id] = {\n ...current,\n rejected_count: current.rejected_count + 1,\n last_rejected_at: now,\n rejection_reason: reason,\n };\n return index;\n}\n\n/**\n * Record that a memory was *applied* — explicitly confirmed to have changed what\n * the agent/human did. This is the closed-loop utility signal that distinguishes\n * a memory that merely got surfaced from one that demonstrably steered work.\n */\nexport function recordApplied(index: UsageIndex, id: string): UsageIndex {\n const current = normalizeUsage(index.by_id[id]);\n const now = new Date().toISOString();\n index.by_id[id] = {\n ...current,\n applied_count: current.applied_count + 1,\n last_applied_at: now,\n };\n return index;\n}\n\nexport const DECAY_DAYS = 90;\n\nexport function isDecaying(usage: MemoryUsage, createdAt: string): boolean {\n const threshold = Date.now() - DECAY_DAYS * 24 * 60 * 60 * 1000;\n const anchor = usage.last_read_at ?? createdAt;\n return new Date(anchor).getTime() < threshold;\n}\n\nexport async function trackReads(\n paths: HaivePaths,\n ids: string[],\n): Promise<UsageIndex> {\n if (ids.length === 0) {\n return await loadUsageIndex(paths);\n }\n const index = await loadUsageIndex(paths);\n bumpRead(index, ids);\n await saveUsageIndex(paths, index);\n return index;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\nimport type { MemoryUsage } from \"./usage.js\";\n\n/**\n * Closed-loop memory-utility scoring — the \"did this memory actually help?\" layer.\n *\n * hAIve already tracks reads ({@link ./usage.js}) and derives a trust level from\n * status + read_count ({@link ./confidence.js}). But a read only means a memory was\n * *surfaced*, not that it *helped* — a memory can be injected on every briefing and\n * silently ignored. Harness engineering's core loop (Fowler / LangChain) is to\n * measure what demonstrably steers work and let that feed back into recall.\n *\n * `computeImpact` combines the signals hAIve already records but never correlated:\n * POSITIVE reads · applied outcomes (mem_feedback) · a sensor that actually fired\n * NEGATIVE rejections · stale/deprecated/rejected status · dormancy\n * into a single 0..1 utility score, a tier, and a prune-candidate flag. It is a pure\n * function (no I/O), unit-tested in `packages/core/test/impact.test.ts`.\n */\n\nexport type ImpactTier = \"high\" | \"medium\" | \"low\" | \"dormant\";\n\nexport interface ImpactScore {\n /** Normalized utility score in [0, 1]. */\n score: number;\n tier: ImpactTier;\n /** Human-readable breakdown of the signals that produced the score. */\n signals: string[];\n /**\n * True when the memory looks like dead weight worth reviewing/pruning:\n * more rejections than reads, or never used with no guardrail, or already\n * stale/deprecated/rejected. A memory carrying a `sensor` or with `applied`\n * outcomes is never a prune candidate — it earns its keep as a guardrail.\n */\n pruneCandidate: boolean;\n}\n\nexport interface ImpactOptions {\n /** Days with no read AND no applied outcome after which a memory is \"dormant\". */\n dormantDays?: number;\n now?: Date;\n}\n\nconst MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/** Default dormancy window — half the confidence hard-decay (365d), so impact reacts sooner. */\nexport const DEFAULT_DORMANT_DAYS = 120;\n\n/** Reads needed to saturate the read component of the score. */\nconst READ_SATURATION = 32;\n\nfunction clamp01(n: number): number {\n if (Number.isNaN(n)) return 0;\n return Math.max(0, Math.min(1, n));\n}\n\nfunction hasSensorFired(fm: MemoryFrontmatter): boolean {\n return Boolean(fm.sensor?.last_fired);\n}\n\nfunction isDeadStatus(fm: MemoryFrontmatter): boolean {\n return fm.status === \"stale\" || fm.status === \"deprecated\" || fm.status === \"rejected\";\n}\n\n/**\n * Compute the demonstrated utility of a single memory from its frontmatter + usage.\n * Pure and deterministic given `now`.\n */\nexport function computeImpact(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n options: ImpactOptions = {},\n): ImpactScore {\n const now = options.now ?? new Date();\n const dormantDays = options.dormantDays ?? DEFAULT_DORMANT_DAYS;\n const signals: string[] = [];\n\n let raw = 0;\n\n // POSITIVE — reads (a memory that keeps getting surfaced has some pull). Log-scaled\n // and capped at 0.35 so reads alone can never reach \"high\": being surfaced is not\n // the same as being useful.\n if (usage.read_count > 0) {\n raw += Math.min(1, Math.log2(usage.read_count + 1) / Math.log2(READ_SATURATION + 1)) * 0.35;\n signals.push(`read ${usage.read_count}×`);\n }\n\n // POSITIVE — applied outcomes: the strongest signal. The agent/human confirmed it\n // changed what they did. 4 applications saturate this 0.60 component — enough to\n // reach \"high\" on its own, since a demonstrably-applied memory has earned it.\n if (usage.applied_count > 0) {\n raw += Math.min(1, usage.applied_count / 4) * 0.6;\n signals.push(`applied ${usage.applied_count}×`);\n }\n\n // POSITIVE — the memory's sensor actually fired on a real diff: a documented\n // mistake became a guardrail that caught a regression. Demonstrated value.\n if (hasSensorFired(fm)) {\n raw += 0.25;\n signals.push(\"sensor fired\");\n }\n\n // NEGATIVE — rejections: explicit \"not useful\" feedback. Heavily weighted.\n if (usage.rejected_count > 0) {\n raw -= Math.min(0.6, usage.rejected_count * 0.25);\n signals.push(`rejected ${usage.rejected_count}×`);\n }\n\n let score = clamp01(raw);\n\n // Dead statuses collapse the score regardless of past reads.\n if (isDeadStatus(fm)) {\n score *= 0.2;\n signals.push(`status=${fm.status}`);\n }\n\n // Dormancy — no read and no application within the window. The clock starts at the\n // most recent activity (applied → read → created).\n const anchor = usage.last_applied_at ?? usage.last_read_at ?? fm.created_at;\n const ageDays = (now.getTime() - new Date(anchor).getTime()) / MS_PER_DAY;\n const dormant =\n Number.isFinite(ageDays) && ageDays >= dormantDays && usage.applied_count === 0;\n if (dormant) {\n score *= 0.5;\n signals.push(`dormant ${Math.floor(ageDays)}d`);\n }\n\n const tier = deriveTier(score, dormant, usage);\n const pruneCandidate = isPruneCandidate(fm, usage, tier);\n\n return { score: round3(score), tier, signals, pruneCandidate };\n}\n\nfunction deriveTier(score: number, dormant: boolean, usage: MemoryUsage): ImpactTier {\n if (dormant && usage.read_count <= 1 && usage.applied_count === 0) return \"dormant\";\n if (score >= 0.55) return \"high\";\n if (score >= 0.2) return \"medium\";\n return \"low\";\n}\n\nfunction isPruneCandidate(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n tier: ImpactTier,\n): boolean {\n // A sensor or any applied outcome means the memory earns its keep.\n if (fm.sensor || usage.applied_count > 0) return false;\n if (isDeadStatus(fm)) return true;\n // More rejected than read = actively unhelpful.\n if (usage.rejected_count > 0 && usage.rejected_count >= usage.read_count) return true;\n // Never used and gone dormant = dead weight.\n if (tier === \"dormant\" && usage.read_count === 0) return true;\n return false;\n}\n\nfunction round3(n: number): number {\n return Math.round(n * 1000) / 1000;\n}\n\n/** Sort comparator: highest impact first, prune candidates last on ties. */\nexport function compareImpact(a: ImpactScore, b: ImpactScore): number {\n if (b.score !== a.score) return b.score - a.score;\n if (a.pruneCandidate !== b.pruneCandidate) return a.pruneCandidate ? 1 : -1;\n return 0;\n}\n\nexport interface ImpactSummary {\n total: number;\n high: number;\n medium: number;\n low: number;\n dormant: number;\n prune_candidates: number;\n}\n\n/** Roll up a set of impact scores into tier counts. */\nexport function summarizeImpact(scores: ImpactScore[]): ImpactSummary {\n const summary: ImpactSummary = {\n total: scores.length,\n high: 0,\n medium: 0,\n low: 0,\n dormant: 0,\n prune_candidates: 0,\n };\n for (const s of scores) {\n summary[s.tier] += 1;\n if (s.pruneCandidate) summary.prune_candidates += 1;\n }\n return summary;\n}\n","import type { LoadedMemory } from \"./loader.js\";\n\n/**\n * A rigorous, model-free, repeatable evaluation of hAIve's core promise: surfacing\n * the right knowledge and guardrails at the right moment. Unlike the agent benchmark\n * (which parses human-written reports), this is deterministic and CI-runnable — it\n * produces a chiffré quality score from labeled cases, so a regression in ranking or\n * sensor coverage fails the build instead of silently degrading every agent session.\n *\n * Two case families:\n * - RETRIEVAL — given a task (+optional files/symbols), do the expected memories\n * surface in the briefing top-k? Measured by recall and mean reciprocal rank.\n * - SENSORS — given a known-bad diff, does the expected memory's sensor fire?\n * Measured by catch-rate.\n *\n * This module is pure: it defines the case/result types, the scoring math, and case\n * synthesis from a repo's own anchored memories. Orchestration (calling get_briefing\n * / anti_patterns_check) lives in the CLI, since core cannot depend on the MCP layer.\n */\n\nexport interface RetrievalCase {\n name: string;\n task: string;\n files?: string[];\n symbols?: string[];\n /** Memory ids that SHOULD surface in the briefing for this case. */\n expect_ids: string[];\n}\n\nexport interface SensorCase {\n name: string;\n /** Unified diff (or added-line text) the sensors run against. */\n diff: string;\n paths?: string[];\n /** Memory ids whose sensor SHOULD fire on this diff. */\n expect_fire_ids: string[];\n}\n\nexport interface EvalSpec {\n retrieval?: RetrievalCase[];\n sensors?: SensorCase[];\n}\n\nexport interface RetrievalCaseResult {\n name: string;\n expect_ids: string[];\n /** Surfaced memory ids, in ranked order, capped at k. */\n surfaced_ids: string[];\n hits: string[];\n misses: string[];\n precision: number;\n recall: number;\n /** 1-based rank of the first expected id among surfaced ids; null if none surfaced. */\n best_rank: number | null;\n}\n\nexport interface SensorCaseResult {\n name: string;\n expect_fire_ids: string[];\n fired_ids: string[];\n hits: string[];\n misses: string[];\n recall: number;\n}\n\nexport interface RetrievalAggregate {\n cases: RetrievalCaseResult[];\n mean_precision: number;\n mean_recall: number;\n /** Mean reciprocal rank of the first expected hit — rewards ranking the right memory high. */\n mrr: number;\n}\n\nexport interface SensorAggregate {\n cases: SensorCaseResult[];\n catch_rate: number;\n}\n\nexport interface EvalReport {\n retrieval: RetrievalAggregate | null;\n sensors: SensorAggregate | null;\n /** Overall quality score 0..100. */\n score: number;\n}\n\nfunction round3(n: number): number {\n return Math.round(n * 1000) / 1000;\n}\n\nfunction uniq(ids: string[]): string[] {\n return [...new Set(ids)];\n}\n\n/**\n * Score one retrieval case from the (ranked) ids the briefing surfaced.\n * `surfacedRanked` should already be capped to the top-k the caller cares about.\n */\nexport function scoreRetrievalCase(\n name: string,\n expectIds: string[],\n surfacedRanked: string[],\n): RetrievalCaseResult {\n const expect = uniq(expectIds);\n const surfaced = uniq(surfacedRanked);\n const surfacedSet = new Set(surfaced);\n const hits = expect.filter((id) => surfacedSet.has(id));\n const misses = expect.filter((id) => !surfacedSet.has(id));\n\n let bestRank: number | null = null;\n for (let i = 0; i < surfaced.length; i++) {\n if (expect.includes(surfaced[i]!)) {\n bestRank = i + 1;\n break;\n }\n }\n\n return {\n name,\n expect_ids: expect,\n surfaced_ids: surfaced,\n hits,\n misses,\n precision: surfaced.length === 0 ? 0 : round3(hits.length / surfaced.length),\n recall: expect.length === 0 ? 1 : round3(hits.length / expect.length),\n best_rank: bestRank,\n };\n}\n\nexport function aggregateRetrieval(cases: RetrievalCaseResult[]): RetrievalAggregate {\n const n = cases.length;\n const mean = (sel: (c: RetrievalCaseResult) => number): number =>\n n === 0 ? 0 : round3(cases.reduce((s, c) => s + sel(c), 0) / n);\n return {\n cases,\n mean_precision: mean((c) => c.precision),\n mean_recall: mean((c) => c.recall),\n mrr: mean((c) => (c.best_rank ? 1 / c.best_rank : 0)),\n };\n}\n\nexport function scoreSensorCase(\n name: string,\n expectFireIds: string[],\n firedIds: string[],\n): SensorCaseResult {\n const expect = uniq(expectFireIds);\n const fired = uniq(firedIds);\n const firedSet = new Set(fired);\n const hits = expect.filter((id) => firedSet.has(id));\n const misses = expect.filter((id) => !firedSet.has(id));\n return {\n name,\n expect_fire_ids: expect,\n fired_ids: fired,\n hits,\n misses,\n recall: expect.length === 0 ? 1 : round3(hits.length / expect.length),\n };\n}\n\nexport function aggregateSensors(cases: SensorCaseResult[]): SensorAggregate {\n const totalExpected = cases.reduce((s, c) => s + c.expect_fire_ids.length, 0);\n const totalHits = cases.reduce((s, c) => s + c.hits.length, 0);\n return {\n cases,\n catch_rate: totalExpected === 0 ? 1 : round3(totalHits / totalExpected),\n };\n}\n\n/** Combine retrieval + sensor aggregates into a single 0..100 quality score. */\nexport function overallScore(\n retrieval: RetrievalAggregate | null,\n sensors: SensorAggregate | null,\n): number {\n if (retrieval && sensors) {\n return Math.round((0.5 * retrieval.mean_recall + 0.2 * retrieval.mrr + 0.3 * sensors.catch_rate) * 100);\n }\n if (retrieval) {\n return Math.round((0.7 * retrieval.mean_recall + 0.3 * retrieval.mrr) * 100);\n }\n if (sensors) {\n return Math.round(sensors.catch_rate * 100);\n }\n return 0;\n}\n\nexport function buildReport(\n retrieval: RetrievalAggregate | null,\n sensors: SensorAggregate | null,\n): EvalReport {\n return { retrieval, sensors, score: overallScore(retrieval, sensors) };\n}\n\n/** Extract a short task-like title from a memory body (first heading or first line). */\nexport function titleFromBody(body: string): string {\n const lines = body.split(\"\\n\");\n for (const line of lines) {\n const heading = /^#+\\s*(.+)$/.exec(line.trim());\n if (heading) return heading[1]!.trim().slice(0, 120);\n }\n for (const line of lines) {\n const t = line.trim();\n if (t) return t.replace(/^[-*]\\s*/, \"\").slice(0, 120);\n }\n return \"\";\n}\n\nexport interface SelfEvalOptions {\n /** Include each memory's anchor paths as the case files (tests anchored retrieval). */\n includeFiles?: boolean;\n /** Skip memories with these statuses (default: stale/deprecated/rejected). */\n skipStatuses?: string[];\n}\n\n/**\n * Synthesize retrieval cases from a repo's own anchored memories — zero-setup eval.\n * Each anchored, non-recap, non-dead memory becomes a case: \"when working on the\n * file(s) this memory anchors, with its title as the task, does hAIve surface it?\".\n * With `includeFiles: false` it becomes a harder semantic-only probe (title alone).\n */\nexport function synthesizeSelfEvalCases(\n memories: LoadedMemory[],\n options: SelfEvalOptions = {},\n): RetrievalCase[] {\n const includeFiles = options.includeFiles ?? true;\n const skip = new Set(options.skipStatuses ?? [\"stale\", \"deprecated\", \"rejected\"]);\n const cases: RetrievalCase[] = [];\n for (const { memory } of memories) {\n const fm = memory.frontmatter;\n if (fm.type === \"session_recap\") continue;\n if (skip.has(fm.status)) continue;\n const paths = fm.anchor.paths;\n if (paths.length === 0) continue;\n const task = titleFromBody(memory.body) || fm.id;\n cases.push({\n name: fm.id,\n task,\n ...(includeFiles ? { files: paths } : {}),\n expect_ids: [fm.id],\n });\n }\n return cases;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\nimport type { MemoryUsage } from \"./usage.js\";\n\nexport type ConfidenceLevel =\n | \"unverified\"\n | \"low\"\n | \"trusted\"\n | \"authoritative\"\n | \"stale\";\n\nexport interface ConfidenceThresholds {\n trustedReads: number;\n authoritativeReads: number;\n /** Days without a read after which confidence drops one tier (authoritative → trusted). */\n decayDays: number;\n /** Days without a read after which confidence drops two tiers (e.g. authoritative → low). */\n hardDecayDays: number;\n}\n\nexport const DEFAULT_CONFIDENCE_THRESHOLDS: ConfidenceThresholds = {\n trustedReads: 3,\n authoritativeReads: 10,\n decayDays: 180,\n hardDecayDays: 365,\n};\n\nconst MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/**\n * Compute the trust level of a memory.\n *\n * Base tier is derived from `status + read_count`:\n * - draft → unverified\n * - proposed (low reads) → low\n * - proposed (3+ reads) → trusted\n * - validated (low reads) → trusted\n * - validated (10+ reads) → authoritative\n * - stale / deprecated / rejected → stale\n *\n * On top of the base tier, a TIME DECAY is applied: a memory that has not been\n * read in `decayDays` (default 180) drops one tier, and one not read in\n * `hardDecayDays` (default 365) drops two tiers. The clock starts at\n * `last_read_at` if any, otherwise `created_at` from the frontmatter.\n *\n * The decay never crosses into `stale` (we keep that signal reserved for the\n * verifier). The intent is to surface \"this used to be authoritative but\n * nobody has touched it in a year — verify before quoting it\" without\n * pretending the memory is wrong.\n */\nexport function deriveConfidence(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n thresholds: ConfidenceThresholds = DEFAULT_CONFIDENCE_THRESHOLDS,\n now: Date = new Date(),\n): ConfidenceLevel {\n if (fm.status === \"stale\" || fm.status === \"deprecated\" || fm.status === \"rejected\") return \"stale\";\n\n const baseLevel = baseConfidence(fm, usage, thresholds);\n\n // Apply decay only to tiers worth lowering.\n if (baseLevel !== \"authoritative\" && baseLevel !== \"trusted\") return baseLevel;\n\n const anchor = usage.last_read_at ?? fm.created_at;\n const ageDays = (now.getTime() - new Date(anchor).getTime()) / MS_PER_DAY;\n if (Number.isNaN(ageDays) || ageDays <= 0) return baseLevel;\n\n if (ageDays >= thresholds.hardDecayDays) {\n // Two-tier drop. authoritative → low, trusted → low.\n return \"low\";\n }\n if (ageDays >= thresholds.decayDays) {\n if (baseLevel === \"authoritative\") return \"trusted\";\n if (baseLevel === \"trusted\") return \"low\";\n }\n return baseLevel;\n}\n\nfunction baseConfidence(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n thresholds: ConfidenceThresholds,\n): ConfidenceLevel {\n if (fm.status === \"validated\") {\n return usage.read_count >= thresholds.authoritativeReads\n ? \"authoritative\"\n : \"trusted\";\n }\n if (fm.status === \"proposed\") {\n return usage.read_count >= thresholds.trustedReads ? \"trusted\" : \"low\";\n }\n // draft\n return \"unverified\";\n}\n\nexport interface AutoPromoteRule {\n /** Minimum read_count to promote proposed → validated. */\n minReads: number;\n /** Maximum rejected_count tolerated (memories with more rejections never auto-promote). */\n maxRejections: number;\n}\n\nexport const DEFAULT_AUTO_PROMOTE_RULE: AutoPromoteRule = {\n minReads: 5,\n maxRejections: 0,\n};\n\nexport function isAutoPromoteEligible(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n rule: AutoPromoteRule = DEFAULT_AUTO_PROMOTE_RULE,\n): boolean {\n if (fm.status !== \"proposed\") return false;\n if (usage.rejected_count > rule.maxRejections) return false;\n return usage.read_count >= rule.minReads;\n}\n","/**\n * Distinctive-token corroboration for the anti-pattern gate.\n *\n * The pre-commit gate used to hard-block whenever a diff shared ANY ≥4-char token\n * with an anchored gotcha's body. That fires on ubiquitous domain words (\"memory\",\n * \"sensor\", \"scope\", \"input\", \"version\") and on version-bump diffs — blocking agents\n * for nothing. The fix: a `literal` overlap only corroborates a BLOCK when at least\n * one shared token is *distinctive* to that gotcha — i.e. rare across the gotcha\n * corpus (low document frequency), like `BigInt`, `open-in-view`, `rec_7`. Common\n * words can still surface the warning for review; they just can't hard-block.\n *\n * Pure module (no I/O), TF-IDF-style. Unit-tested in `test/distinctive.test.ts`.\n */\n\n/**\n * Language keywords + ubiquitous code words that would match almost any memory body\n * and so carry no distinguishing signal. Shared by the diff tokenizer and the\n * distinctiveness check so \"literal\" stays meaningful.\n */\nexport const CODE_STOPWORDS = new Set([\n \"import\", \"export\", \"function\", \"return\", \"const\", \"let\", \"var\", \"class\", \"public\",\n \"private\", \"protected\", \"static\", \"this\", \"true\", \"false\", \"null\", \"undefined\", \"void\",\n \"async\", \"await\", \"from\", \"type\", \"interface\", \"extends\", \"implements\", \"number\", \"string\",\n \"boolean\", \"value\", \"default\", \"case\", \"break\", \"continue\", \"throw\", \"catch\", \"finally\",\n \"else\", \"while\", \"for\", \"new\", \"super\", \"yield\", \"module\", \"require\", \"console\",\n]);\n\n/** Minimum token length kept for word-level matching (shorter tokens are too noisy). */\nexport const MIN_WORD_LEN = 4;\n\n/** Split text into lowercase word tokens (>= MIN_WORD_LEN, excluding code stopwords). */\nexport function tokenizeWords(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length >= MIN_WORD_LEN && !CODE_STOPWORDS.has(t));\n}\n\nexport interface DocFrequency {\n /** token -> number of documents (memory bodies) it appears in */\n df: Map<string, number>;\n /** total number of documents */\n total: number;\n}\n\n/** Build per-token document frequency across a corpus of memory bodies. */\nexport function buildDocFrequency(bodies: string[]): DocFrequency {\n const df = new Map<string, number>();\n for (const body of bodies) {\n const unique = new Set(tokenizeWords(body));\n for (const tok of unique) df.set(tok, (df.get(tok) ?? 0) + 1);\n }\n return { df, total: bodies.length };\n}\n\n/**\n * Document-frequency cap at/below which a token counts as distinctive. Deliberately\n * strict — \"distinctive\" means *rare* (≈ the bottom 10% of the corpus), with a floor\n * of 1 so a token appearing in a single memory is always distinctive. Strictness is\n * intentional: blocking is the aggressive action, so we under-block rather than fire\n * on a word that several gotchas happen to share.\n */\nexport function distinctiveCap(total: number): number {\n return Math.max(1, Math.floor(0.1 * total));\n}\n\n/** True when `token` is distinctive (rare) within the corpus. */\nexport function isDistinctiveToken(token: string, freq: DocFrequency): boolean {\n const tok = token.toLowerCase();\n if (tok.length < MIN_WORD_LEN || CODE_STOPWORDS.has(tok)) return false;\n const df = freq.df.get(tok);\n if (df === undefined) return true; // not seen elsewhere in the corpus → distinctive\n return df <= distinctiveCap(freq.total);\n}\n\n/**\n * True when the added diff text shares at least one *distinctive* word token with the\n * memory body. This is the precise corroboration the block decision should require:\n * \"the change actually contains the specific thing this gotcha warns about\", not\n * \"the change happens to mention a common domain word\".\n */\nexport function diffHasDistinctiveOverlap(\n addedDiffText: string,\n memoryBody: string,\n freq: DocFrequency,\n): boolean {\n const memoryTokens = new Set(tokenizeWords(memoryBody));\n if (memoryTokens.size === 0) return false;\n for (const tok of new Set(tokenizeWords(addedDiffText))) {\n if (memoryTokens.has(tok) && isDistinctiveToken(tok, freq)) return true;\n }\n return false;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\nimport { pathsOverlap } from \"./relevance.js\";\n\n/**\n * Progressive disclosure for `skill` memories.\n *\n * Skills are reusable playbooks. Surfacing all of them on every briefing wastes the\n * instruction budget and buries the relevant one. A skill with an `activation` block\n * is disclosed ONLY when it is relevant to the current task/files; a skill without\n * one keeps the legacy always-eligible behavior. This module is pure (no I/O).\n */\n\nexport interface ActivationContext {\n task?: string;\n files?: string[];\n}\n\nexport interface SkillActivation {\n applicable: boolean;\n activated: boolean;\n reasons: string[];\n}\n\nexport function isSkill(fm: Pick<MemoryFrontmatter, \"type\">): boolean {\n return fm.type === \"skill\";\n}\n\n/**\n * Decide whether a skill should be disclosed for the given context.\n * For non-skills, or skills with no `activation` block, returns `activated: true`\n * (never suppress them). Otherwise activates on `always`, a keyword substring match\n * against the task, or a glob match against the edited files.\n */\nexport function evaluateSkillActivation(\n fm: Pick<MemoryFrontmatter, \"type\" | \"activation\">,\n ctx: ActivationContext,\n): SkillActivation {\n if (!isSkill(fm)) return { applicable: false, activated: true, reasons: [] };\n const act = fm.activation;\n if (!act) return { applicable: false, activated: true, reasons: [\"no-activation\"] };\n\n const reasons: string[] = [];\n if (act.always) reasons.push(\"always\");\n\n const task = (ctx.task ?? \"\").toLowerCase();\n if (task) {\n for (const kw of act.keywords) {\n if (kw && task.includes(kw.toLowerCase())) {\n reasons.push(`keyword:${kw}`);\n break;\n }\n }\n }\n\n const files = ctx.files ?? [];\n if (files.length > 0) {\n outer: for (const glob of act.globs) {\n for (const f of files) {\n if (pathsOverlap(glob, f)) {\n reasons.push(`glob:${glob}`);\n break outer;\n }\n }\n }\n }\n\n return { applicable: true, activated: reasons.length > 0, reasons };\n}\n\n/** Convenience: true when a skill defines activation triggers that the context does NOT satisfy. */\nexport function isSkillSuppressed(\n fm: Pick<MemoryFrontmatter, \"type\" | \"activation\">,\n ctx: ActivationContext,\n): boolean {\n const result = evaluateSkillActivation(fm, ctx);\n return result.applicable && !result.activated;\n}\n","/**\n * Specificity (\"surprise\") scoring for memories.\n *\n * hAIve's measured value is preventing agents from reinventing — wrongly — the team's\n * NON-OBVIOUS, arbitrary decisions (e.g. \"public ids are internal id + 100000 prefixed AC-\",\n * \"the status field must be 'OK'/'KO'\"). A capable model already knows generic best practice\n * (\"use Decimal for money\", \"validate input\"), so surfacing that is pure token overhead.\n *\n * `specificityScore` is a cheap, deterministic heuristic that estimates how *unguessable* a\n * memory is: high when it contains concrete, arbitrary signal (string literals, code\n * identifiers, magic numbers, paths, ALLCAPS constants), low when it is generic prose.\n *\n * It is intentionally a heuristic, not a model call — used to (1) bias briefing ranking toward\n * unguessable knowledge, (2) keep a near-empty briefing cheap when nothing team-specific\n * matches, (3) lint low-value memories, and (4) filter auto-capture candidates.\n */\n\n/** Generic best-practice phrases a capable model already knows — low marginal value to surface. */\nconst GENERIC_PHRASES: readonly string[] = [\n \"validate input\", \"sanitize\", \"prepared statement\", \"parameterized quer\",\n \"never commit secret\", \"use environment variable\", \"handle error\", \"write test\",\n \"avoid sql injection\", \"escape html\", \"hash password\", \"use https\", \"least privilege\",\n \"do not hardcode\", \"don't hardcode\", \"single responsibility\", \"keep it dry\",\n \"follow best practice\", \"use meaningful names\", \"add error handling\", \"check for null\",\n \"use try/catch\", \"use async/await\", \"avoid magic number\", \"write clean code\",\n];\n\nconst STRING_LITERAL = /[\"'`][^\"'`\\n]{1,48}[\"'`]/g;\nconst BACKTICK_SPAN = /`[^`\\n]+`/g;\nconst CAMEL_CASE = /\\b[a-zA-Z_][a-zA-Z0-9_]*[a-z][A-Z][a-zA-Z0-9_]*\\b/g;\nconst SNAKE_CASE = /\\b[a-z][a-z0-9]*_[a-z0-9_]+\\b/g;\nconst DOTTED = /\\b\\w+\\.\\w+(?:\\.\\w+)*\\b/g;\nconst MAGIC_NUMBER = /\\b\\d{2,}\\b|\\b\\d+\\.\\d+\\b/g;\nconst FILE_PATH = /\\b[\\w./-]+\\.[a-z]{1,5}\\b/g;\nconst ALLCAPS_CONST = /\\b[A-Z]{2,}(?:_[A-Z0-9]+)+\\b|\\b[A-Z]{3,}\\b/g;\n\nfunction countMatches(text: string, re: RegExp): number {\n const m = text.match(re);\n return m ? m.length : 0;\n}\n\n/**\n * Estimate how unguessable / team-specific a memory body is, in [0, 1].\n * ~0 = generic advice a model already follows by default.\n * ~1 = arbitrary, repo-specific knowledge no model can infer.\n */\nexport function specificityScore(body: string): number {\n const text = (body ?? \"\").trim();\n if (text.length === 0) return 0;\n const lower = text.toLowerCase();\n const words = lower.split(/\\s+/).filter(Boolean).length || 1;\n\n let hits = 0;\n hits += countMatches(text, STRING_LITERAL) * 2;\n hits += countMatches(text, BACKTICK_SPAN) * 2;\n hits += countMatches(text, CAMEL_CASE);\n hits += countMatches(text, SNAKE_CASE);\n hits += countMatches(text, DOTTED);\n hits += countMatches(text, MAGIC_NUMBER);\n hits += countMatches(text, FILE_PATH);\n hits += countMatches(text, ALLCAPS_CONST);\n\n // Density of concrete signal. The denominator scales with length so a long generic\n // paragraph isn't rescued by a single identifier, while a short, dense rule scores high.\n let score = Math.min(1, hits / Math.max(6, words * 0.35));\n\n // A memory that reads like generic advice and carries little concrete signal is capped low.\n const generic = GENERIC_PHRASES.some((p) => lower.includes(p));\n if (generic && hits < 4) score = Math.min(score, 0.22);\n\n return score;\n}\n\n/** Default threshold below which a memory is considered likely-guessable (low marginal value). */\nexport const GUESSABLE_THRESHOLD = 0.3;\n\n/** True when a memory body looks like generic knowledge a capable model already has. */\nexport function isLikelyGuessable(body: string, threshold: number = GUESSABLE_THRESHOLD): boolean {\n return specificityScore(body) < threshold;\n}\n","/**\n * Token budgeting helpers. We use the standard heuristic of ~4 chars per token,\n * which is conservative for English/code/markdown. Callers that need exact\n * counts should plug in a real tokenizer; this module only ever over-estimates,\n * so the user's hard limits are respected.\n */\n\nexport const CHARS_PER_TOKEN = 4;\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nexport interface TruncateOptions {\n /** Maximum tokens allowed in the result (inclusive). */\n maxTokens: number;\n /** Marker inserted where content was dropped. */\n marker?: string;\n /** Where to keep characters from when truncating. Default: head. */\n mode?: \"head\" | \"tail\" | \"middle\";\n}\n\nexport interface TruncateResult {\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n}\n\nconst DEFAULT_MARKER = \"\\n…[truncated]…\\n\";\n\nexport function truncateToTokens(\n input: string,\n options: TruncateOptions,\n): TruncateResult {\n const originalTokens = estimateTokens(input);\n const max = Math.max(0, options.maxTokens);\n if (originalTokens <= max) {\n return { text: input, truncated: false, estimatedTokens: originalTokens, originalTokens };\n }\n\n if (max === 0) {\n return { text: \"\", truncated: true, estimatedTokens: 0, originalTokens };\n }\n\n const marker = options.marker ?? DEFAULT_MARKER;\n const mode = options.mode ?? \"head\";\n const markerTokens = estimateTokens(marker);\n const budgetChars = Math.max(0, (max - markerTokens) * CHARS_PER_TOKEN);\n\n let result: string;\n if (budgetChars === 0) {\n result = \"\";\n } else if (mode === \"tail\") {\n result = marker + input.slice(input.length - budgetChars);\n } else if (mode === \"middle\") {\n const half = Math.floor(budgetChars / 2);\n result = input.slice(0, half) + marker + input.slice(input.length - half);\n } else {\n result = input.slice(0, budgetChars) + marker;\n }\n\n return {\n text: result,\n truncated: true,\n estimatedTokens: estimateTokens(result),\n originalTokens,\n };\n}\n\n/**\n * Allocate a global token budget across N parts with relative weights, then\n * truncate each part to its share. Returns parts in input order, paired with\n * truncate metadata.\n */\nexport interface BudgetPart {\n key: string;\n text: string;\n weight: number;\n mode?: TruncateOptions[\"mode\"];\n}\n\nexport interface BudgetSlice {\n key: string;\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n allocatedTokens: number;\n}\n\nexport function allocateBudget(\n parts: BudgetPart[],\n maxTokens: number,\n): BudgetSlice[] {\n if (parts.length === 0) return [];\n const totalWeight = parts.reduce((s, p) => s + Math.max(0, p.weight), 0);\n if (totalWeight === 0) {\n return parts.map((p) => ({\n key: p.key,\n text: \"\",\n truncated: estimateTokens(p.text) > 0,\n estimatedTokens: 0,\n originalTokens: estimateTokens(p.text),\n allocatedTokens: 0,\n }));\n }\n\n // First pass: allocate by weight, but if a part's content fits in less than\n // its share, redistribute the surplus to others proportionally.\n const allocations = new Map<string, number>();\n let remaining = maxTokens;\n let remainingWeight = totalWeight;\n\n // Sort parts by share fit ascending so small ones consume their share first.\n const sortedByFit = [...parts]\n .map((p) => ({\n key: p.key,\n tokens: estimateTokens(p.text),\n share: (p.weight / totalWeight) * maxTokens,\n part: p,\n }))\n .sort((a, b) => a.tokens - b.tokens);\n\n for (const item of sortedByFit) {\n const myShare = remainingWeight > 0\n ? (item.part.weight / remainingWeight) * remaining\n : 0;\n const grant = Math.min(item.tokens, Math.floor(myShare));\n allocations.set(item.key, grant);\n remaining -= grant;\n remainingWeight -= item.part.weight;\n }\n\n return parts.map((p) => {\n const allocated = allocations.get(p.key) ?? 0;\n const truncated = truncateToTokens(p.text, {\n maxTokens: allocated,\n mode: p.mode ?? \"head\",\n });\n return {\n key: p.key,\n text: truncated.text,\n truncated: truncated.truncated,\n estimatedTokens: truncated.estimatedTokens,\n originalTokens: truncated.originalTokens,\n allocatedTokens: allocated,\n };\n });\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { spawnSync } from \"node:child_process\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const CODE_MAP_FILE = \"code-map.json\";\n\nexport type CodeExportKind =\n | \"function\"\n | \"class\"\n | \"interface\"\n | \"type\"\n | \"const\"\n | \"enum\"\n | \"default\";\n\nexport interface CodeExport {\n name: string;\n kind: CodeExportKind;\n description?: string;\n line: number;\n}\n\nexport interface CodeFileEntry {\n summary?: string;\n exports: CodeExport[];\n loc: number;\n}\n\nexport interface CodeMap {\n version: 1;\n generated_at: string;\n root: string;\n files: Record<string, CodeFileEntry>;\n}\n\nexport interface BuildCodeMapOptions {\n includeExtensions?: string[];\n excludeDirs?: string[];\n /** Include untracked files that are not ignored by git. Default: false when the root is a git repo. */\n includeUntracked?: boolean;\n}\n\nconst DEFAULT_INCLUDE = [\n \".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\",\n \".java\", \".kt\",\n \".py\",\n \".go\",\n \".rb\",\n \".rs\",\n \".cs\",\n \".php\",\n];\nconst DEFAULT_EXCLUDE = [\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \".git\",\n \".next\",\n \".turbo\",\n \".vitest-cache\",\n \"coverage\",\n \"test\",\n \"tests\",\n \"__tests__\",\n \"__mocks__\",\n \"target\", // Maven/Gradle build output\n \".gradle\",\n \"__pycache__\",\n \".pytest_cache\",\n \"vendor\", // Go / PHP\n];\n\nconst TEST_FILE_RE = /\\.(test|spec)\\.[a-z]+$/i;\n\nexport function codeMapPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, CODE_MAP_FILE);\n}\n\nexport async function loadCodeMap(paths: HaivePaths): Promise<CodeMap | null> {\n const file = codeMapPath(paths);\n if (!existsSync(file)) return null;\n return JSON.parse(await readFile(file, \"utf8\")) as CodeMap;\n}\n\nexport async function saveCodeMap(paths: HaivePaths, map: CodeMap): Promise<void> {\n const file = codeMapPath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, JSON.stringify(map, null, 2), \"utf8\");\n}\n\nexport async function buildCodeMap(\n root: string,\n options: BuildCodeMapOptions = {},\n): Promise<CodeMap> {\n const include = new Set(options.includeExtensions ?? DEFAULT_INCLUDE);\n const exclude = new Set(options.excludeDirs ?? DEFAULT_EXCLUDE);\n const files: Record<string, CodeFileEntry> = {};\n\n for await (const abs of collectSourceFiles(root, include, exclude, options.includeUntracked)) {\n const rel = path.relative(root, abs).replace(/\\\\/g, \"/\");\n if (rel.startsWith(\".ai/\")) continue;\n const content = await readFile(abs, \"utf8\");\n const ext = path.extname(abs).toLowerCase();\n const entry = parseFile(content, ext);\n if (entry.exports.length > 0) files[rel] = entry;\n }\n\n return {\n version: 1,\n generated_at: new Date().toISOString(),\n root,\n files,\n };\n}\n\nasync function* collectSourceFiles(\n root: string,\n include: Set<string>,\n exclude: Set<string>,\n includeUntracked: boolean | undefined,\n): AsyncGenerator<string> {\n const gitFiles = gitSourceFiles(root, include, exclude, includeUntracked === true);\n if (gitFiles) {\n for (const rel of gitFiles) yield path.join(root, rel);\n return;\n }\n\n yield* walkSourceFiles(root, include, exclude);\n}\n\nfunction gitSourceFiles(\n root: string,\n include: Set<string>,\n exclude: Set<string>,\n includeUntracked: boolean,\n): string[] | null {\n const args = includeUntracked\n ? [\"ls-files\", \"--cached\", \"--others\", \"--exclude-standard\"]\n : [\"ls-files\", \"--cached\"];\n const result = spawnSync(\"git\", args, {\n cwd: root,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n if (result.status !== 0) return null;\n\n return result.stdout\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .filter((rel) => isIncludedSourcePath(rel, include, exclude))\n .sort();\n}\n\nasync function* walkSourceFiles(\n dir: string,\n include: Set<string>,\n exclude: Set<string>,\n): AsyncGenerator<string> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") && entry.name !== \".github\") {\n // Skip hidden dirs except .github (workflows can be useful)\n if (entry.isDirectory()) continue;\n }\n if (exclude.has(entry.name)) continue;\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkSourceFiles(full, include, exclude);\n } else if (entry.isFile()) {\n const ext = path.extname(entry.name).toLowerCase();\n if (include.has(ext) && !TEST_FILE_RE.test(entry.name)) yield full;\n }\n }\n}\n\nfunction isIncludedSourcePath(\n rel: string,\n include: Set<string>,\n exclude: Set<string>,\n): boolean {\n const normalized = rel.replace(/\\\\/g, \"/\");\n if (normalized.startsWith(\".ai/\")) return false;\n const parts = normalized.split(\"/\");\n if (parts.some((part) => exclude.has(part))) return false;\n const base = parts.at(-1) ?? \"\";\n const ext = path.extname(base).toLowerCase();\n return include.has(ext) && !TEST_FILE_RE.test(base);\n}\n\nconst EXPORT_RE =\n /^export\\s+(?:default\\s+)?(async\\s+)?(function|class|interface|type|const|let|var|enum)\\s+(\\*?)\\s*([A-Za-z_$][\\w$]*)/gm;\n\nconst NAMED_REEXPORT_RE = /^export\\s*\\{([^}]+)\\}/gm;\n\nconst FILE_HEADER_COMMENT_RE = /^\\/\\*\\*([\\s\\S]*?)\\*\\//;\n\n// Java / Kotlin: public/protected class, interface, enum, record, @interface, fun, @RestController etc.\nconst JAVA_DECL_RE =\n /^(?:[ \\t]*)(?:@\\w+\\s+)*(?:public|protected|private|internal)?\\s*(?:static\\s+|final\\s+|abstract\\s+|open\\s+|data\\s+|sealed\\s+)*(?:(class|interface|enum|record|@interface|object)\\s+([A-Z][A-Za-z0-9_$]*)|(fun|def|func|function)\\s+([a-z_][A-Za-z0-9_$]*))/gm;\n\n// Python: def / class at module level (not indented)\nconst PYTHON_DECL_RE = /^(def|class)\\s+([A-Za-z_][A-Za-z0-9_]*)/gm;\n\n// Go: func declarations\nconst GO_DECL_RE = /^func\\s+(?:\\(\\w+\\s+\\*?[A-Za-z_][\\w]*\\)\\s+)?([A-Za-z_][A-Za-z0-9_]*)/gm;\n\n// Rust: pub fn / pub struct / pub enum / pub trait\nconst RUST_DECL_RE =\n /^pub(?:\\([^)]*\\))?\\s+(fn|struct|enum|trait|type|const|impl|mod)\\s+([A-Za-z_][A-Za-z0-9_]*)/gm;\n\nfunction parseFile(source: string, ext: string): CodeFileEntry {\n if (ext === \".java\" || ext === \".kt\") return parseJvmFile(source);\n if (ext === \".py\") return parsePythonFile(source);\n if (ext === \".go\") return parseGoFile(source);\n if (ext === \".rs\") return parseRustFile(source);\n return parseJsFile(source);\n}\n\nfunction parseJsFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n\n let m: RegExpExecArray | null;\n EXPORT_RE.lastIndex = 0;\n while ((m = EXPORT_RE.exec(source))) {\n const kindRaw = m[2] ?? \"\";\n const name = m[4] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"function\" ? \"function\" :\n kindRaw === \"class\" ? \"class\" :\n kindRaw === \"interface\" ? \"interface\" :\n kindRaw === \"type\" ? \"type\" :\n kindRaw === \"enum\" ? \"enum\" : \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n\n NAMED_REEXPORT_RE.lastIndex = 0;\n while ((m = NAMED_REEXPORT_RE.exec(source))) {\n const inside = m[1] ?? \"\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n for (const part of inside.split(\",\")) {\n const cleaned = part.trim().split(/\\s+as\\s+/).pop()?.trim() ?? \"\";\n if (!cleaned || cleaned.startsWith(\"type \")) continue;\n if (exports.some((e) => e.name === cleaned)) continue;\n exports.push({ name: cleaned, kind: \"const\", line: lineIdx + 1 });\n }\n }\n\n const summary = extractFileSummary(source);\n return { ...(summary ? { summary } : {}), exports, loc: source.split(\"\\n\").length };\n}\n\nfunction parseJvmFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n JAVA_DECL_RE.lastIndex = 0;\n while ((m = JAVA_DECL_RE.exec(source))) {\n const kindRaw = m[1] ?? m[3] ?? \"\";\n const name = m[2] ?? m[4] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"class\" || kindRaw === \"record\" || kindRaw === \"object\" ? \"class\" :\n kindRaw === \"interface\" || kindRaw === \"@interface\" ? \"interface\" :\n kindRaw === \"enum\" ? \"enum\" :\n kindRaw === \"fun\" || kindRaw === \"def\" || kindRaw === \"func\" || kindRaw === \"function\" ? \"function\" :\n \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n const summary = extractJavaSummary(source);\n return { ...(summary ? { summary } : {}), exports, loc: lines.length };\n}\n\nfunction parsePythonFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n PYTHON_DECL_RE.lastIndex = 0;\n while ((m = PYTHON_DECL_RE.exec(source))) {\n const keyword = m[1] ?? \"\";\n const name = m[2] ?? \"\";\n if (!name || name.startsWith(\"_\")) continue;\n const kind: CodeExportKind = keyword === \"class\" ? \"class\" : \"function\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractPythonDocstring(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n const summary = extractPythonModuleDocstring(source);\n return { ...(summary ? { summary } : {}), exports, loc: lines.length };\n}\n\nfunction parseGoFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n GO_DECL_RE.lastIndex = 0;\n while ((m = GO_DECL_RE.exec(source))) {\n const name = m[1] ?? \"\";\n if (!name || !/^[A-Z]/.test(name)) continue; // Only exported (uppercase) in Go\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind: \"function\", ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n return { exports, loc: lines.length };\n}\n\nfunction parseRustFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n RUST_DECL_RE.lastIndex = 0;\n while ((m = RUST_DECL_RE.exec(source))) {\n const kindRaw = m[1] ?? \"\";\n const name = m[2] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"struct\" || kindRaw === \"impl\" ? \"class\" :\n kindRaw === \"enum\" ? \"enum\" :\n kindRaw === \"trait\" ? \"interface\" :\n kindRaw === \"fn\" ? \"function\" :\n kindRaw === \"type\" ? \"type\" : \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n return { exports, loc: lines.length };\n}\n\nfunction extractJavaSummary(source: string): string | undefined {\n // Java/Kotlin: file-level Javadoc before first class/interface\n const m = source.match(/^\\/\\*\\*([\\s\\S]*?)\\*\\//);\n if (!m) return undefined;\n const block = (m[1] ?? \"\")\n .split(\"\\n\")\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter((l) => l && !l.startsWith(\"@\"))\n .join(\" \");\n return block ? firstSentence(block) : undefined;\n}\n\nfunction extractPythonDocstring(lines: string[], defLine: number): string | undefined {\n const next = lines[defLine + 1] ?? \"\";\n const stripped = next.trim();\n if (stripped.startsWith('\"\"\"') || stripped.startsWith(\"'''\")) {\n const inner = stripped.replace(/^[\"']{3}/, \"\").replace(/[\"']{3}.*$/, \"\").trim();\n return inner || undefined;\n }\n return undefined;\n}\n\nfunction extractPythonModuleDocstring(source: string): string | undefined {\n const m = source.match(/^[\"']{3}([\\s\\S]*?)[\"']{3}/);\n if (!m) return undefined;\n return firstSentence((m[1] ?? \"\").trim());\n}\n\nfunction computeLineOffsets(source: string): number[] {\n const out: number[] = [0];\n for (let i = 0; i < source.length; i++) {\n if (source[i] === \"\\n\") out.push(i + 1);\n }\n return out;\n}\n\nfunction byteToLine(byte: number, offsets: number[]): number {\n let lo = 0;\n let hi = offsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n const off = offsets[mid] ?? 0;\n if (off <= byte) lo = mid;\n else hi = mid - 1;\n }\n return lo;\n}\n\nfunction extractJSDocAbove(lines: string[], exportLine: number): string | undefined {\n let i = exportLine - 1;\n // Skip blank lines between JSDoc and export\n while (i >= 0 && (lines[i] ?? \"\").trim() === \"\") i--;\n if (i < 0) return undefined;\n const line = (lines[i] ?? \"\").trim();\n\n if (line.startsWith(\"//\")) {\n return line.replace(/^\\/\\/\\s*/, \"\").trim() || undefined;\n }\n\n // Single-line JSDoc: /** Adds two numbers. */\n const singleLine = line.match(/^\\/\\*\\*\\s*(.*?)\\s*\\*\\/\\s*$/);\n if (singleLine && singleLine[1]) {\n return firstSentence(singleLine[1]);\n }\n\n if (line.endsWith(\"*/\")) {\n // Walk up until /**\n const collected: string[] = [];\n // First piece: content of the line before */\n const firstPiece = line.replace(/\\*\\/\\s*$/, \"\").replace(/^\\*\\s?/, \"\").trim();\n if (firstPiece) collected.unshift(firstPiece);\n let j = i - 1;\n while (j >= 0) {\n const l = (lines[j] ?? \"\").trim();\n if (l.startsWith(\"/**\")) {\n const inner = l.replace(/^\\/\\*\\*/, \"\").trim();\n if (inner) collected.unshift(inner);\n break;\n }\n collected.unshift(l.replace(/^\\*\\s?/, \"\").trim());\n j--;\n }\n const joined = collected.join(\" \").trim();\n if (!joined) return undefined;\n return firstSentence(joined);\n }\n return undefined;\n}\n\nfunction firstSentence(text: string): string | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n return trimmed.split(/(?<=\\.)\\s+/)[0]?.trim();\n}\n\nfunction extractFileSummary(source: string): string | undefined {\n const m = source.match(FILE_HEADER_COMMENT_RE);\n if (!m) return undefined;\n const block = (m[1] ?? \"\")\n .split(\"\\n\")\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter(Boolean)\n .join(\" \");\n if (!block) return undefined;\n const sentence = block.split(/(?<=\\.)\\s+/)[0]?.trim();\n return sentence;\n}\n\nexport interface CodeMapQueryOptions {\n file?: string;\n symbol?: string;\n}\n\nexport function queryCodeMap(map: CodeMap, options: CodeMapQueryOptions): {\n files: Array<{ path: string; entry: CodeFileEntry }>;\n} {\n const files: Array<{ path: string; entry: CodeFileEntry }> = [];\n for (const [filePath, entry] of Object.entries(map.files)) {\n if (options.file) {\n if (!filePath.includes(options.file)) continue;\n }\n if (options.symbol) {\n const sym = options.symbol.toLowerCase();\n if (!entry.exports.some((e) => e.name.toLowerCase().includes(sym))) continue;\n }\n files.push({ path: filePath, entry });\n }\n return { files };\n}\n","/**\n * hAIve project configuration — .ai/haive.config.json\n *\n * In autopilot mode, hAIve operates with zero human intervention:\n * - Memories go directly to `validated` (no approval cycle)\n * - `haive sync` auto-approves proposed memories after the delay\n * - The MCP server saves a session recap automatically on exit\n * - `get_briefing` auto-generates a minimal project context if none exists\n * - `haive sync` applies safe self-maintenance repairs (context version, headings,\n * needs_anchor tags, code-map refresh) without human intervention\n *\n * Multi-repo support:\n * - crossRepoSources: pull shared memories from other repos on haive sync\n * - contractFiles: watch API contract files for breaking changes\n * - hubPath: local path to a shared team-knowledge hub repo\n */\nimport { existsSync } from \"node:fs\";\nimport { readFileSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const CONFIG_FILE = \"haive.config.json\";\n\n/** A remote or local repo to pull shared memories from. */\nexport interface CrossRepoSource {\n /** Human-readable name for this source (used in imported memory tags). */\n name: string;\n /** Local filesystem path to the other project's root (relative or absolute). */\n path?: string;\n /** Git URL — clone/fetch performed automatically. */\n git?: string;\n /** Only import memories matching all of these filters. */\n filter?: {\n /** Only import memories with these tags. */\n tags?: string[];\n /** Only import memories of these types. */\n types?: string[];\n };\n}\n\n/** An API contract file to snapshot and monitor for breaking changes. */\nexport interface ContractFile {\n /** Human-readable name for this contract. */\n name: string;\n /** Path to the contract file, relative to the project root. */\n path: string;\n /** Format of the contract file. */\n format: \"openapi\" | \"graphql\" | \"proto\" | \"typescript\" | \"json-schema\";\n}\n\nexport interface HaiveConfig {\n /** Autopilot mode: maximum autonomy, minimum human intervention. Default: false. */\n autopilot?: boolean;\n\n /**\n * Adaptive briefing: when get_briefing finds no team-specific (unguessable) memory for the\n * task/files, trim the auto-generated project context so the call stays near-zero-cost.\n * A capable model needs nothing extra in that case. Curated context is never trimmed.\n * Default: true.\n */\n adaptiveBriefing?: boolean;\n\n /** Default scope for new memories. Default: \"personal\". Autopilot sets \"team\". */\n defaultScope?: \"personal\" | \"team\";\n\n /**\n * Default status for new memories saved via mem_save.\n * Autopilot sets \"validated\" — skips the approval cycle entirely.\n * Default: \"draft\".\n */\n defaultStatus?: \"draft\" | \"validated\";\n\n /** Auto-approve proposed memories after N hours without rejection. Default: null (disabled). */\n autoApproveDelayHours?: number | null;\n\n /**\n * Auto-promote proposed→validated after N reads (overrides DEFAULT_AUTO_PROMOTE_RULE).\n * Autopilot sets 1 (immediate on first use).\n */\n autoPromoteMinReads?: number;\n\n /** Auto-save session recap on MCP server exit. Default: true in autopilot, false otherwise. */\n autoSessionEnd?: boolean;\n\n /**\n * Auto-generate a minimal project context from code-map when project-context.md is still\n * the template. Default: true in autopilot, false otherwise.\n */\n autoContext?: boolean;\n\n /**\n * Safe self-maintenance performed automatically in autopilot mode.\n * These repairs are intentionally conservative: no guessed anchor is applied\n * without strong evidence, but headings/tags/indexes/context metadata can be\n * kept fresh by the tool itself.\n */\n autoRepair?: {\n /** Keep .ai/project-context.md version metadata aligned with package.json. */\n context?: boolean;\n /** Apply safe memory lint fixes: headings and `needs_anchor` tags. */\n corpus?: boolean;\n /** Refresh .ai/code-map.json during sync when needed. */\n codeMap?: boolean;\n /** Best-effort build of code-search embeddings when @hiveai/embeddings is available. */\n codeSearch?: boolean;\n };\n\n // ── Multi-repo support ──────────────────────────────────────────────────\n\n /**\n * Other repos to pull `shared`-scoped memories from during `haive sync`.\n * Each source must have either `path` (local) or `git` (remote URL).\n *\n * Example:\n * { \"name\": \"backend\", \"path\": \"../repo-backend\", \"filter\": { \"tags\": [\"api-contract\"] } }\n */\n crossRepoSources?: CrossRepoSource[];\n\n /**\n * API contract files to snapshot and watch for breaking changes.\n * `haive sync` compares the current file against `.ai/contracts/<name>.lock`\n * and creates a `gotcha` memory if a breaking change is detected.\n *\n * Example:\n * { \"name\": \"payment-api\", \"path\": \"docs/openapi.yaml\", \"format\": \"openapi\" }\n */\n contractFiles?: ContractFile[];\n\n /**\n * Local path to a shared team-knowledge hub repo.\n * Used by `haive hub pull` and `haive hub push`.\n * Can be relative (resolved from project root) or absolute.\n */\n hubPath?: string;\n\n /**\n * Lock file paths to watch for dependency version changes.\n * Auto-detected if not specified (package.json, pom.xml, go.mod, etc.).\n * Set to [] to disable dependency tracking entirely.\n */\n dependencyFiles?: string[];\n\n /**\n * Agent-enforcement settings. Enabled by default so initialized projects\n * treat hAIve as infrastructure, not an optional convention.\n */\n enforcement?: {\n /** Enforcement posture: advisory reports only, warn in hooks, or block workflow gates. */\n mode?: \"off\" | \"advisory\" | \"strict\";\n /** Require get_briefing / mem_relevant_to before state-changing MCP tools. */\n requireBriefingFirst?: boolean;\n /** Require a session recap before pre-push / CI gates pass. */\n requireSessionRecap?: boolean;\n /** Require memory anchor verification before pre-commit / CI gates pass. */\n requireMemoryVerify?: boolean;\n /** Block changes when anchored decisions/gotchas have become stale. */\n blockStaleDecisionChanges?: boolean;\n /** Require changed files to be covered by relevant surfaced decisions/policies. */\n requireDecisionCoverage?: boolean;\n /**\n * How hard the pre-commit anti-pattern gate blocks a matching attempt/gotcha:\n * - off: never block on anti-patterns (report only)\n * - review: block only on a very strong semantic match (score ≥ 0.75) — soft, legacy default\n * - anchored: ALSO block when a high-confidence anti-pattern is anchored to a touched file\n * and corroborated by the diff (literal token or semantic ≥ 0.45). High precision.\n * - strict: block on any high-confidence anti-pattern match (anchor, literal, or semantic)\n * Config/docs-only commits are always downgraded regardless of this setting.\n * Default: \"anchored\" — makes \"known bad approaches are blocked\" true for the precise case.\n */\n antiPatternGate?: \"off\" | \"review\" | \"anchored\" | \"strict\";\n /**\n * Default unread-age window (in days) for `haive memory archive` corpus decay.\n * A noisy or stale corpus is actively harmful — it makes the agent follow outdated policy.\n * Default: 180.\n */\n decayAfterDays?: number;\n /** Minimum score required for strict enforcement gates. */\n scoreThreshold?: number;\n /** Remove generated hAIve runtime/cache files during cleanup gates. */\n cleanupGeneratedArtifacts?: boolean;\n /**\n * MCP tool surface:\n * - enforcement: compact default harness for coding agents\n * - maintenance: corpus/admin tools for humans and team stewards\n * - experimental: research/diagnostic tools that are not core product surface\n * - full: legacy alias for experimental\n */\n toolProfile?: \"enforcement\" | \"maintenance\" | \"experimental\" | \"full\";\n /** Named memory/policy families enabled for this project. */\n policyPacks?: string[];\n };\n}\n\nexport const DEFAULT_CONFIG: HaiveConfig = {\n autopilot: false,\n defaultScope: \"personal\",\n defaultStatus: \"draft\",\n autoApproveDelayHours: null,\n autoPromoteMinReads: 5,\n autoSessionEnd: false,\n autoContext: false,\n autoRepair: {\n context: false,\n corpus: false,\n codeMap: false,\n codeSearch: false,\n },\n enforcement: {\n mode: \"strict\",\n requireBriefingFirst: true,\n requireSessionRecap: true,\n requireMemoryVerify: true,\n blockStaleDecisionChanges: true,\n requireDecisionCoverage: true,\n antiPatternGate: \"anchored\",\n scoreThreshold: 80,\n cleanupGeneratedArtifacts: true,\n toolProfile: \"enforcement\",\n policyPacks: [\"architecture\", \"gotchas\", \"security\", \"domain\", \"release\"],\n },\n};\n\nexport const AUTOPILOT_DEFAULTS: HaiveConfig = {\n autopilot: true,\n defaultScope: \"team\",\n defaultStatus: \"validated\",\n autoApproveDelayHours: 72,\n autoPromoteMinReads: 1,\n autoSessionEnd: true,\n autoContext: true,\n autoRepair: {\n context: true,\n corpus: true,\n codeMap: true,\n codeSearch: true,\n },\n enforcement: {\n mode: \"strict\",\n requireBriefingFirst: true,\n requireSessionRecap: true,\n requireMemoryVerify: true,\n blockStaleDecisionChanges: true,\n requireDecisionCoverage: true,\n antiPatternGate: \"anchored\",\n scoreThreshold: 85,\n cleanupGeneratedArtifacts: true,\n toolProfile: \"enforcement\",\n policyPacks: [\"architecture\", \"gotchas\", \"security\", \"domain\", \"release\"],\n },\n};\n\n/** The pre-commit anti-pattern gate hardness levels. */\nexport type AntiPatternGate = \"off\" | \"review\" | \"anchored\" | \"strict\";\n\n/**\n * Single source of truth mapping a configured `antiPatternGate` to the\n * `pre_commit_check` parameters that implement it. Both the git-hook path\n * (`haive enforce check`) and the standalone `haive precommit` command derive\n * their behavior from this so the two surfaces can never drift apart.\n */\nexport function antiPatternGateParams(\n gate: AntiPatternGate,\n): { block_on: \"any\" | \"high-confidence\" | \"never\"; anchored_blocks: boolean } {\n switch (gate) {\n case \"off\":\n return { block_on: \"never\", anchored_blocks: false };\n case \"review\":\n return { block_on: \"high-confidence\", anchored_blocks: false };\n case \"strict\":\n return { block_on: \"any\", anchored_blocks: true };\n case \"anchored\":\n default:\n return { block_on: \"high-confidence\", anchored_blocks: true };\n }\n}\n\nexport function configPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, CONFIG_FILE);\n}\n\nexport async function loadConfig(paths: HaivePaths): Promise<HaiveConfig> {\n const file = configPath(paths);\n if (!existsSync(file)) return { ...DEFAULT_CONFIG };\n try {\n const raw = await readFile(file, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<HaiveConfig>;\n const merged = mergeConfig(DEFAULT_CONFIG, parsed);\n // In autopilot mode, apply autopilot defaults for any field not explicitly set\n if (merged.autopilot) {\n return mergeConfig(AUTOPILOT_DEFAULTS, parsed);\n }\n return merged;\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function loadConfigSync(paths: HaivePaths): HaiveConfig {\n const file = configPath(paths);\n if (!existsSync(file)) return { ...DEFAULT_CONFIG };\n try {\n const parsed = JSON.parse(readFileSync(file, \"utf8\")) as Partial<HaiveConfig>;\n const merged = mergeConfig(DEFAULT_CONFIG, parsed);\n return merged.autopilot\n ? mergeConfig(AUTOPILOT_DEFAULTS, parsed)\n : merged;\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(paths: HaivePaths, config: HaiveConfig): Promise<void> {\n await writeFile(configPath(paths), JSON.stringify(config, null, 2) + \"\\n\", \"utf8\");\n}\n\nfunction mergeConfig(base: HaiveConfig, override: Partial<HaiveConfig>): HaiveConfig {\n return {\n ...base,\n ...override,\n autoRepair: {\n ...base.autoRepair,\n ...override.autoRepair,\n },\n enforcement: {\n ...base.enforcement,\n ...override.enforcement,\n },\n };\n}\n","/**\n * Cross-repo memory import — pulls `shared`-scoped memories from other projects.\n *\n * Strategy:\n * 1. For each CrossRepoSource in haive.config.json, resolve the source root.\n * 2. Load memories from <source>/.ai/memories/ where scope=shared (+ optional filter).\n * 3. Track imports via .ai/.cache/cross-repo/<name>/import-map.json\n * (sourceId → localFilePath).\n * 4. Write new/updated memories to .ai/memories/shared/<source-name>/.\n * 5. Return a report: { imported, updated, skipped, errors }.\n *\n * Imported memories are tagged with `cross-repo:<source-name>` so they are\n * identifiable and excluded from cross-repo-push to prevent echo loops.\n */\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport {\n buildFrontmatter,\n loadMemoriesFromDir,\n resolveHaivePaths,\n serializeMemory,\n} from \"./index.js\";\nimport type { CrossRepoSource, HaiveConfig } from \"./config.js\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport interface CrossRepoReport {\n source: string;\n imported: string[];\n updated: string[];\n skipped: string[];\n errors: string[];\n}\n\ntype ImportMap = Record<string, string>; // sourceId → local absolute filePath\n\nasync function loadImportMap(cacheDir: string): Promise<ImportMap> {\n const mapPath = path.join(cacheDir, \"import-map.json\");\n if (!existsSync(mapPath)) return {};\n try {\n return JSON.parse(await readFile(mapPath, \"utf8\")) as ImportMap;\n } catch {\n return {};\n }\n}\n\nasync function saveImportMap(cacheDir: string, map: ImportMap): Promise<void> {\n await writeFile(path.join(cacheDir, \"import-map.json\"), JSON.stringify(map, null, 2) + \"\\n\", \"utf8\");\n}\n\n/**\n * Pull shared memories from all configured cross-repo sources.\n * Returns one report per source.\n */\nexport async function pullCrossRepoSources(\n paths: HaivePaths,\n config: HaiveConfig,\n projectRoot: string,\n): Promise<CrossRepoReport[]> {\n const sources = config.crossRepoSources ?? [];\n if (sources.length === 0) return [];\n\n const reports: CrossRepoReport[] = [];\n for (const source of sources) {\n reports.push(await pullFromSource(paths, source, projectRoot));\n }\n return reports;\n}\n\nasync function pullFromSource(\n paths: HaivePaths,\n source: CrossRepoSource,\n projectRoot: string,\n): Promise<CrossRepoReport> {\n const report: CrossRepoReport = {\n source: source.name,\n imported: [],\n updated: [],\n skipped: [],\n errors: [],\n };\n\n // Resolve source root\n let sourceRoot: string | null = null;\n if (source.path) {\n const resolved = path.resolve(projectRoot, source.path);\n if (!existsSync(resolved)) {\n report.errors.push(`Path not found: ${resolved}`);\n return report;\n }\n sourceRoot = resolved;\n } else if (source.git) {\n sourceRoot = await cloneOrFetchGitSource(source, paths, report);\n if (!sourceRoot) return report;\n } else {\n report.errors.push(`Source \"${source.name}\" has neither path nor git — skipping.`);\n return report;\n }\n\n const sourcePaths = resolveHaivePaths(sourceRoot);\n if (!existsSync(sourcePaths.memoriesDir)) {\n report.errors.push(`No .ai/memories/ found at ${sourceRoot}`);\n return report;\n }\n\n // Load source memories filtered to scope=shared\n const sourceMemories = (await loadMemoriesFromDir(sourcePaths.memoriesDir)).filter(\n ({ memory }) => {\n const fm = memory.frontmatter;\n if (fm.scope !== \"shared\") return false;\n if (fm.status === \"rejected\" || fm.status === \"deprecated\") return false;\n if (source.filter?.tags && source.filter.tags.length > 0) {\n const hasTag = source.filter.tags.some((t) => fm.tags.includes(t));\n if (!hasTag) return false;\n }\n if (source.filter?.types && source.filter.types.length > 0) {\n if (!source.filter.types.includes(fm.type)) return false;\n }\n return true;\n },\n );\n\n if (sourceMemories.length === 0) {\n report.skipped.push(\"no shared memories found in source\");\n return report;\n }\n\n // Destination: .ai/memories/shared/<source-name>/\n const destDir = path.join(paths.memoriesDir, \"shared\", source.name);\n await mkdir(destDir, { recursive: true });\n\n // Cache dir for import tracking\n const cacheDir = path.join(paths.haiveDir, \".cache\", \"cross-repo\", source.name);\n await mkdir(cacheDir, { recursive: true });\n const importMap = await loadImportMap(cacheDir);\n const mapDirty = false;\n let dirty = mapDirty;\n\n for (const { memory } of sourceMemories) {\n const fm = memory.frontmatter;\n const sourceId = fm.id;\n const importTag = `cross-repo:${source.name}`;\n const tags = [...new Set([...fm.tags, importTag])];\n\n const importedBodyPrefix =\n `> **Imported from \\`${source.name}\\`** (original id: \\`${sourceId}\\`) \\n` +\n `> Imported at: ${new Date().toISOString()}\\n\\n`;\n\n const existingLocalPath = importMap[sourceId];\n\n if (existingLocalPath && existsSync(existingLocalPath)) {\n // Already imported — check if body changed in source\n const existingFiles = await loadMemoriesFromDir(destDir);\n const existingEntry = existingFiles.find(({ filePath }) => filePath === existingLocalPath);\n const sourceBodyStripped = memory.body.trim();\n const existingBodyStripped = (existingEntry?.memory.body ?? \"\")\n .replace(/^>.*\\n>.*\\n\\n/m, \"\")\n .trim();\n\n if (existingBodyStripped === sourceBodyStripped) {\n report.skipped.push(sourceId);\n continue;\n }\n\n // Body changed — update\n const updatedBody = importedBodyPrefix + memory.body;\n if (existingEntry) {\n await writeFile(\n existingLocalPath,\n serializeMemory({ frontmatter: existingEntry.memory.frontmatter, body: updatedBody }),\n \"utf8\",\n );\n }\n report.updated.push(sourceId);\n } else {\n // New import\n const slug = `${source.name}-${fm.id.slice(0, 40)}`;\n const newFm = buildFrontmatter({\n type: fm.type,\n slug,\n scope: \"team\" as const,\n module: undefined,\n status: \"validated\",\n tags,\n domain: fm.domain,\n author: fm.author,\n paths: fm.anchor.paths,\n symbols: fm.anchor.symbols,\n commit: fm.anchor.commit,\n topic: fm.topic ? `${source.name}:${fm.topic}` : undefined,\n });\n\n const body = importedBodyPrefix + memory.body;\n const destPath = path.join(destDir, `${newFm.id}.md`);\n await writeFile(destPath, serializeMemory({ frontmatter: newFm, body }), \"utf8\");\n importMap[sourceId] = destPath;\n dirty = true;\n report.imported.push(sourceId);\n }\n }\n\n if (dirty) await saveImportMap(cacheDir, importMap);\n return report;\n}\n\n/**\n * Clone or fetch a git source into .ai/.cache/cross-repo/<name>/.\n * Returns the resolved local path, or null on error.\n */\nasync function cloneOrFetchGitSource(\n source: CrossRepoSource,\n paths: HaivePaths,\n report: CrossRepoReport,\n): Promise<string | null> {\n const cacheDir = path.join(paths.haiveDir, \".cache\", \"cross-repo\", source.name);\n await mkdir(cacheDir, { recursive: true });\n\n if (existsSync(path.join(cacheDir, \".git\"))) {\n const result = spawnSync(\"git\", [\"fetch\", \"--depth=1\", \"origin\"], {\n cwd: cacheDir,\n encoding: \"utf8\",\n });\n if (result.status !== 0) {\n report.errors.push(`git fetch failed for ${source.name}: ${result.stderr}`);\n return null;\n }\n spawnSync(\"git\", [\"reset\", \"--hard\", \"FETCH_HEAD\"], { cwd: cacheDir });\n } else {\n const result = spawnSync(\n \"git\",\n [\"clone\", \"--depth=1\", source.git!, \".\"],\n { cwd: cacheDir, encoding: \"utf8\" },\n );\n if (result.status !== 0) {\n report.errors.push(`git clone failed for ${source.name}: ${result.stderr}`);\n return null;\n }\n }\n\n return cacheDir;\n}\n","/**\n * Dependency version tracker.\n *\n * During `haive sync`, parse the project's dependency manifest files\n * (package.json, pom.xml, go.mod, Cargo.toml, requirements.txt, etc.),\n * compare against a snapshot stored at `.ai/contracts/deps-<name>.lock`,\n * and return memories that should be marked stale because a dependency\n * they reference has changed version (major bump = breaking change risk).\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport interface DependencySnapshot {\n file: string;\n format: string;\n captured_at: string;\n deps: Record<string, string>; // name → version\n}\n\nexport interface DepChange {\n name: string;\n from: string;\n to: string;\n /** true if the major version number changed */\n isMajorBump: boolean;\n}\n\nexport interface DepTrackResult {\n file: string;\n changes: DepChange[];\n}\n\n// ── Manifest parsers ───────────────────────────────────────────────────────\n\n/** Parse package.json (npm/pnpm/yarn) — returns name→version map */\nfunction parsePackageJson(content: string): Record<string, string> {\n try {\n const pkg = JSON.parse(content) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n };\n return {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n } catch {\n return {};\n }\n}\n\n/** Parse go.mod — returns module→version map */\nfunction parseGoMod(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split(\"\\n\")) {\n const m = line.trim().match(/^(\\S+)\\s+(v[\\d.]+)/);\n if (m?.[1] && m[2]) result[m[1]] = m[2];\n }\n return result;\n}\n\n/** Parse requirements.txt (Python) — returns package→version map */\nfunction parseRequirementsTxt(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split(\"\\n\")) {\n const clean = (line.split(\"#\")[0] ?? \"\").trim();\n const m = clean.match(/^([A-Za-z0-9_.-]+)[=><~!]+(.+)$/);\n if (m?.[1] && m[2]) result[m[1].toLowerCase()] = m[2].trim();\n }\n return result;\n}\n\n/** Parse Cargo.toml (Rust) — returns crate→version map */\nfunction parseCargotoml(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n let inDeps = false;\n for (const line of content.split(\"\\n\")) {\n if (/^\\[(dependencies|dev-dependencies|build-dependencies)\\]/.test(line.trim())) {\n inDeps = true;\n continue;\n }\n if (line.startsWith(\"[\") && !line.includes(\"dependencies\")) {\n inDeps = false;\n continue;\n }\n if (!inDeps) continue;\n const simple = line.match(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/);\n if (simple?.[1] && simple[2]) { result[simple[1]] = simple[2]; continue; }\n const table = line.match(/^(\\w[\\w-]*)\\s*=\\s*\\{[^}]*version\\s*=\\s*\"([^\"]+)\"/);\n if (table?.[1] && table[2]) result[table[1]] = table[2];\n }\n return result;\n}\n\n/** Parse pom.xml (Maven) — returns groupId:artifactId→version map */\nfunction parsePomXml(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n const depRe = /<dependency>[\\s\\S]*?<groupId>([^<]+)<\\/groupId>[\\s\\S]*?<artifactId>([^<]+)<\\/artifactId>[\\s\\S]*?<version>([^<]+)<\\/version>[\\s\\S]*?<\\/dependency>/g;\n let m: RegExpExecArray | null;\n while ((m = depRe.exec(content)) !== null) {\n if (m[1] && m[2] && m[3]) {\n result[`${m[1].trim()}:${m[2].trim()}`] = m[3].trim();\n }\n }\n return result;\n}\n\n// ── Auto-detection of manifest files ──────────────────────────────────────\n\nconst KNOWN_MANIFESTS: Array<{ name: string; parser: (c: string) => Record<string, string> }> = [\n { name: \"package.json\", parser: parsePackageJson },\n { name: \"go.mod\", parser: parseGoMod },\n { name: \"requirements.txt\", parser: parseRequirementsTxt },\n { name: \"Cargo.toml\", parser: parseCargotoml },\n { name: \"pom.xml\", parser: parsePomXml },\n];\n\nfunction getParser(file: string): ((c: string) => Record<string, string>) | null {\n const base = path.basename(file);\n return KNOWN_MANIFESTS.find((m) => m.name === base)?.parser ?? null;\n}\n\n// ── Version comparison ─────────────────────────────────────────────────────\n\nfunction extractMajor(version: string): number | null {\n const clean = version.replace(/^[^0-9]*/, \"\"); // strip ^, ~, >=, v, etc.\n const firstPart = clean.split(\".\")[0];\n if (!firstPart) return null;\n const n = parseInt(firstPart, 10);\n return isNaN(n) ? null : n;\n}\n\nfunction isMajorBump(from: string, to: string): boolean {\n const fromMajor = extractMajor(from);\n const toMajor = extractMajor(to);\n if (fromMajor === null || toMajor === null) return false;\n return toMajor > fromMajor;\n}\n\n// ── Public API ─────────────────────────────────────────────────────────────\n\n/**\n * Resolve which manifest files to track.\n * Uses config.dependencyFiles if set, otherwise auto-detects from KNOWN_MANIFESTS.\n */\nexport function resolveManifestFiles(\n projectRoot: string,\n configuredFiles?: string[],\n): string[] {\n if (configuredFiles !== undefined) {\n // Explicitly configured (can be [] to disable)\n return configuredFiles.map((f) => path.resolve(projectRoot, f)).filter(existsSync);\n }\n return KNOWN_MANIFESTS\n .map(({ name }) => path.join(projectRoot, name))\n .filter(existsSync);\n}\n\n/**\n * Check all manifest files for version changes since last snapshot.\n * Returns one result per file that has changes.\n */\nexport async function trackDependencies(\n projectRoot: string,\n haiveDir: string,\n manifestFiles: string[],\n): Promise<DepTrackResult[]> {\n const contractsDir = path.join(haiveDir, \"contracts\");\n await mkdir(contractsDir, { recursive: true });\n\n const results: DepTrackResult[] = [];\n\n for (const manifestPath of manifestFiles) {\n const parser = getParser(manifestPath);\n if (!parser) continue;\n\n const content = await readFile(manifestPath, \"utf8\");\n const currentDeps = parser(content);\n const lockName = `deps-${path.basename(manifestPath)}.lock`;\n const lockPath = path.join(contractsDir, lockName);\n\n if (!existsSync(lockPath)) {\n // First run — save snapshot, no changes to report\n const snapshot: DependencySnapshot = {\n file: path.relative(projectRoot, manifestPath),\n format: path.basename(manifestPath),\n captured_at: new Date().toISOString(),\n deps: currentDeps,\n };\n await writeFile(lockPath, JSON.stringify(snapshot, null, 2) + \"\\n\", \"utf8\");\n continue;\n }\n\n const snapshot = JSON.parse(await readFile(lockPath, \"utf8\")) as DependencySnapshot;\n const changes: DepChange[] = [];\n\n for (const [name, currentVer] of Object.entries(currentDeps)) {\n const prevVer = snapshot.deps[name];\n if (prevVer && prevVer !== currentVer) {\n changes.push({\n name,\n from: prevVer,\n to: currentVer,\n isMajorBump: isMajorBump(prevVer, currentVer),\n });\n }\n }\n\n if (changes.length > 0) {\n results.push({ file: path.relative(projectRoot, manifestPath), changes });\n // Update snapshot\n const updated: DependencySnapshot = {\n ...snapshot,\n captured_at: new Date().toISOString(),\n deps: currentDeps,\n };\n await writeFile(lockPath, JSON.stringify(updated, null, 2) + \"\\n\", \"utf8\");\n }\n }\n\n return results;\n}\n","/**\n * Contract snapshot and diff watcher.\n *\n * Supports:\n * - OpenAPI/Swagger (JSON or YAML)\n * - GraphQL schema\n * - Protocol Buffers (.proto)\n * - TypeScript declaration files (.d.ts)\n * - JSON Schema\n *\n * `haive snapshot --contract <file>` saves a snapshot to .ai/contracts/<name>.lock\n * `haive sync` compares current file against snapshot and returns BreakingChange[].\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport type { ContractFile } from \"./config.js\";\n\nexport interface ContractSnapshot {\n name: string;\n path: string;\n format: string;\n captured_at: string;\n hash: string; // SHA-256 of file content\n endpoints?: string[]; // OpenAPI: list of \"METHOD /path\"\n types?: string[]; // GraphQL/TS: list of type/interface/message names\n fields?: Record<string, string[]>; // type → list of field names\n raw_lines?: string[]; // fallback: full file lines for line-by-line diff\n}\n\nexport interface BreakingChange {\n kind:\n | \"endpoint_removed\"\n | \"endpoint_added\"\n | \"type_removed\"\n | \"type_added\"\n | \"field_removed\"\n | \"field_added\"\n | \"content_changed\";\n description: string;\n severity: \"breaking\" | \"additive\" | \"unknown\";\n}\n\nexport interface ContractDiffResult {\n contract: string;\n file: string;\n changes: BreakingChange[];\n unchanged: boolean;\n}\n\n// ── Parsers ────────────────────────────────────────────────────────────────\n\nfunction sha256(content: string): string {\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n/** Parse OpenAPI/Swagger — extract endpoint list and schemas */\nfunction parseOpenApi(content: string, file: string): Partial<ContractSnapshot> {\n try {\n let doc: Record<string, unknown>;\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\n // Simple YAML line-based extraction (no full YAML parser dep)\n doc = parseYamlPaths(content);\n } else {\n doc = JSON.parse(content) as Record<string, unknown>;\n }\n const paths = (doc.paths ?? {}) as Record<string, Record<string, unknown>>;\n const endpoints: string[] = [];\n for (const [routePath, methods] of Object.entries(paths)) {\n for (const method of Object.keys(methods)) {\n if ([\"get\",\"post\",\"put\",\"patch\",\"delete\",\"head\",\"options\"].includes(method)) {\n endpoints.push(`${method.toUpperCase()} ${routePath}`);\n }\n }\n }\n // Extract schema/component names\n const schemas = (\n (doc.components as Record<string, unknown> | undefined)?.schemas ??\n (doc.definitions as Record<string, unknown> | undefined) ??\n {}\n ) as Record<string, Record<string, unknown>>;\n const types = Object.keys(schemas);\n const fields: Record<string, string[]> = {};\n for (const [typeName, schema] of Object.entries(schemas)) {\n const props = (schema.properties ?? {}) as Record<string, unknown>;\n fields[typeName] = Object.keys(props);\n }\n return { endpoints, types, fields };\n } catch {\n return {};\n }\n}\n\n/** Naive YAML paths extractor — avoids needing js-yaml dep */\nfunction parseYamlPaths(content: string): Record<string, unknown> {\n const result: Record<string, Record<string, boolean>> = {};\n let currentPath = \"\";\n for (const line of content.split(\"\\n\")) {\n const pathMatch = line.match(/^ (\\/[^\\s:]+):/);\n if (pathMatch?.[1]) {\n currentPath = pathMatch[1];\n result[currentPath] = {};\n continue;\n }\n if (currentPath) {\n const methodMatch = line.match(/^ (get|post|put|patch|delete|head|options):/);\n if (methodMatch?.[1]) (result[currentPath] ??= {})[methodMatch[1]] = true;\n }\n }\n return { paths: result };\n}\n\n/** Parse GraphQL schema — extract type/interface/union/enum names */\nfunction parseGraphQL(content: string): Partial<ContractSnapshot> {\n const types: string[] = [];\n const fields: Record<string, string[]> = {};\n let currentType = \"\";\n\n for (const line of content.split(\"\\n\")) {\n const typeMatch = line.match(/^(?:type|interface|union|enum|input)\\s+(\\w+)/);\n if (typeMatch?.[1]) {\n currentType = typeMatch[1];\n types.push(currentType);\n fields[currentType] = [];\n continue;\n }\n if (currentType && line.trim().startsWith(\"}\")) {\n currentType = \"\";\n continue;\n }\n if (currentType) {\n const fieldMatch = line.match(/^\\s+(\\w+)\\s*[:(]/);\n if (fieldMatch?.[1]) (fields[currentType] ??= []).push(fieldMatch[1]);\n }\n }\n return { types, fields };\n}\n\n/** Parse .proto (Protocol Buffers) — extract message/service names */\nfunction parseProto(content: string): Partial<ContractSnapshot> {\n const types: string[] = [];\n const fields: Record<string, string[]> = {};\n let currentMsg = \"\";\n\n for (const line of content.split(\"\\n\")) {\n const msgMatch = line.match(/^(?:message|service|enum)\\s+(\\w+)/);\n if (msgMatch?.[1]) {\n currentMsg = msgMatch[1];\n types.push(currentMsg);\n fields[currentMsg] = [];\n continue;\n }\n if (currentMsg && line.trim() === \"}\") {\n currentMsg = \"\";\n continue;\n }\n if (currentMsg) {\n const fieldMatch = line.match(/^\\s+(?:optional|required|repeated)?\\s*\\w+\\s+(\\w+)\\s*=/);\n if (fieldMatch?.[1]) (fields[currentMsg] ??= []).push(fieldMatch[1]);\n const rpcMatch = line.match(/^\\s+rpc\\s+(\\w+)/);\n if (rpcMatch?.[1]) (fields[currentMsg] ??= []).push(`rpc:${rpcMatch[1]}`);\n }\n }\n return { types, fields };\n}\n\n/** Parse TypeScript .d.ts — extract exported interface/class/type names */\nfunction parseTypescript(content: string): Partial<ContractSnapshot> {\n const types: string[] = [];\n const fields: Record<string, string[]> = {};\n let currentType = \"\";\n let braceDepth = 0;\n\n for (const line of content.split(\"\\n\")) {\n const exportMatch = line.match(/^export\\s+(?:declare\\s+)?(?:interface|class|type|enum)\\s+(\\w+)/);\n if (exportMatch?.[1]) {\n currentType = exportMatch[1];\n types.push(currentType);\n fields[currentType] = [];\n }\n if (currentType) {\n braceDepth += (line.match(/{/g) ?? []).length;\n braceDepth -= (line.match(/}/g) ?? []).length;\n if (braceDepth <= 0 && line.includes(\"}\")) { currentType = \"\"; braceDepth = 0; continue; }\n const memberMatch = line.match(/^\\s+(?:readonly\\s+)?(\\w+)\\s*[?:(!]/);\n if (memberMatch?.[1] && currentType) (fields[currentType] ??= []).push(memberMatch[1]);\n }\n }\n return { types, fields };\n}\n\nfunction parseByFormat(\n content: string,\n format: ContractFile[\"format\"],\n filePath: string,\n): Partial<ContractSnapshot> {\n switch (format) {\n case \"openapi\": return parseOpenApi(content, filePath);\n case \"graphql\": return parseGraphQL(content);\n case \"proto\": return parseProto(content);\n case \"typescript\": return parseTypescript(content);\n case \"json-schema\": {\n try {\n const schema = JSON.parse(content) as Record<string, Record<string, unknown>>;\n const types = Object.keys((schema.definitions ?? schema.properties ?? {}) as Record<string, unknown>);\n return { types };\n } catch { return {}; }\n }\n default: return {};\n }\n}\n\n// ── Diff logic ─────────────────────────────────────────────────────────────\n\nfunction diffLists(before: string[], after: string[], kind: string): BreakingChange[] {\n const changes: BreakingChange[] = [];\n const beforeSet = new Set(before);\n const afterSet = new Set(after);\n for (const item of beforeSet) {\n if (!afterSet.has(item)) {\n const isBreaking = kind === \"endpoint\" || kind === \"field\" || kind === \"type\";\n changes.push({\n kind: `${kind}_removed` as BreakingChange[\"kind\"],\n description: `${kind} removed: ${item}`,\n severity: isBreaking ? \"breaking\" : \"unknown\",\n });\n }\n }\n for (const item of afterSet) {\n if (!beforeSet.has(item)) {\n changes.push({\n kind: `${kind}_added` as BreakingChange[\"kind\"],\n description: `${kind} added: ${item}`,\n severity: \"additive\",\n });\n }\n }\n return changes;\n}\n\nfunction diffSnapshots(before: ContractSnapshot, after: ContractSnapshot): BreakingChange[] {\n if (before.hash === after.hash) return [];\n\n const changes: BreakingChange[] = [];\n\n // Endpoint diff (OpenAPI)\n if (before.endpoints && after.endpoints) {\n changes.push(...diffLists(before.endpoints, after.endpoints, \"endpoint\"));\n }\n\n // Type diff (all formats)\n if (before.types && after.types) {\n changes.push(...diffLists(before.types, after.types, \"type\"));\n }\n\n // Field diff per type\n if (before.fields && after.fields) {\n const allTypes = new Set([...Object.keys(before.fields), ...Object.keys(after.fields)]);\n for (const typeName of allTypes) {\n const beforeFields = before.fields[typeName] ?? [];\n const afterFields = after.fields[typeName] ?? [];\n const fieldChanges = diffLists(beforeFields, afterFields, \"field\");\n for (const fc of fieldChanges) {\n changes.push({ ...fc, description: `${typeName}.${fc.description}` });\n }\n }\n }\n\n // Fallback: file changed but no structured diff\n if (changes.length === 0) {\n changes.push({\n kind: \"content_changed\",\n description: \"Contract file content changed (no structured diff available)\",\n severity: \"unknown\",\n });\n }\n\n return changes;\n}\n\n// ── Public API ─────────────────────────────────────────────────────────────\n\nexport function contractLockPath(haiveDir: string, name: string): string {\n return path.join(haiveDir, \"contracts\", `${name}.lock`);\n}\n\n/**\n * Take a snapshot of a contract file and save it to .ai/contracts/<name>.lock.\n * Returns the snapshot.\n */\nexport async function snapshotContract(\n projectRoot: string,\n haiveDir: string,\n contract: ContractFile,\n): Promise<ContractSnapshot> {\n const filePath = path.resolve(projectRoot, contract.path);\n if (!existsSync(filePath)) {\n throw new Error(`Contract file not found: ${filePath}`);\n }\n const content = await readFile(filePath, \"utf8\");\n const parsed = parseByFormat(content, contract.format, filePath);\n const snapshot: ContractSnapshot = {\n name: contract.name,\n path: contract.path,\n format: contract.format,\n captured_at: new Date().toISOString(),\n hash: sha256(content),\n ...parsed,\n };\n const contractsDir = path.join(haiveDir, \"contracts\");\n await mkdir(contractsDir, { recursive: true });\n await writeFile(contractLockPath(haiveDir, contract.name), JSON.stringify(snapshot, null, 2) + \"\\n\", \"utf8\");\n return snapshot;\n}\n\n/**\n * Compare a contract file against its stored snapshot.\n * Returns the diff result. If no snapshot exists, creates one and returns unchanged.\n */\nexport async function diffContract(\n projectRoot: string,\n haiveDir: string,\n contract: ContractFile,\n): Promise<ContractDiffResult> {\n const filePath = path.resolve(projectRoot, contract.path);\n if (!existsSync(filePath)) {\n return { contract: contract.name, file: contract.path, changes: [], unchanged: true };\n }\n\n const lockPath = contractLockPath(haiveDir, contract.name);\n\n if (!existsSync(lockPath)) {\n // First time — save snapshot\n await snapshotContract(projectRoot, haiveDir, contract);\n return { contract: contract.name, file: contract.path, changes: [], unchanged: true };\n }\n\n const content = await readFile(filePath, \"utf8\");\n const beforeSnapshot = JSON.parse(await readFile(lockPath, \"utf8\")) as ContractSnapshot;\n const afterParsed = parseByFormat(content, contract.format, filePath);\n const afterSnapshot: ContractSnapshot = {\n ...beforeSnapshot,\n hash: sha256(content),\n captured_at: new Date().toISOString(),\n ...afterParsed,\n };\n\n const changes = diffSnapshots(beforeSnapshot, afterSnapshot);\n\n if (changes.length > 0) {\n // Update snapshot to current state\n await writeFile(lockPath, JSON.stringify(afterSnapshot, null, 2) + \"\\n\", \"utf8\");\n }\n\n return {\n contract: contract.name,\n file: contract.path,\n changes,\n unchanged: changes.length === 0,\n };\n}\n\n/**\n * Check all configured contract files for changes.\n */\nexport async function watchContracts(\n projectRoot: string,\n haiveDir: string,\n contractFiles: ContractFile[],\n): Promise<ContractDiffResult[]> {\n const results: ContractDiffResult[] = [];\n for (const contract of contractFiles) {\n results.push(await diffContract(projectRoot, haiveDir, contract));\n }\n return results.filter((r) => !r.unchanged);\n}\n","import { appendFile, mkdir, readFile, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const USAGE_LOG_FILE = \"tool-usage.jsonl\";\nexport const USAGE_LOG_DIR = \".usage\";\n\nexport interface UsageEvent {\n /** ISO timestamp */\n at: string;\n /** Tool name (MCP tool or CLI command) */\n tool: string;\n /** Truncated, non-sensitive snapshot of the input */\n summary?: string;\n}\n\nexport function usageLogPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, USAGE_LOG_DIR, USAGE_LOG_FILE);\n}\n\n/**\n * Append a single usage event to the rolling log. Best-effort: failures are\n * swallowed since logging must never block tool execution.\n */\nexport async function appendUsageEvent(paths: HaivePaths, event: UsageEvent): Promise<void> {\n try {\n const file = usageLogPath(paths);\n const dir = path.dirname(file);\n if (!existsSync(dir)) await mkdir(dir, { recursive: true });\n await appendFile(file, JSON.stringify(event) + \"\\n\", \"utf8\");\n } catch {\n // Logging is best-effort.\n }\n}\n\n/**\n * Read all usage events from disk. Skips malformed lines silently.\n * For very large logs (>50k lines), prefer `streamUsageEvents` (not implemented yet).\n */\nexport async function readUsageEvents(paths: HaivePaths): Promise<UsageEvent[]> {\n const file = usageLogPath(paths);\n if (!existsSync(file)) return [];\n const raw = await readFile(file, \"utf8\");\n const out: UsageEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line) continue;\n try {\n const parsed = JSON.parse(line) as UsageEvent;\n if (parsed.tool && parsed.at) out.push(parsed);\n } catch {\n // skip malformed lines\n }\n }\n return out;\n}\n\nexport interface UsageAggregate {\n total: number;\n by_tool: Array<{ tool: string; count: number; last_used: string }>;\n /** Most-frequently called tools first */\n top: Array<{ tool: string; count: number }>;\n window_start: string | null;\n window_end: string | null;\n}\n\n/**\n * Bucket events by tool, optionally filtered by a since cutoff (ISO date or relative like '7d').\n */\nexport function aggregateUsage(events: UsageEvent[], since?: Date): UsageAggregate {\n const cutoff = since ? since.getTime() : 0;\n const filtered = cutoff > 0\n ? events.filter((e) => Date.parse(e.at) >= cutoff)\n : events;\n\n const counts = new Map<string, { count: number; last: string }>();\n for (const e of filtered) {\n const prior = counts.get(e.tool);\n if (!prior) counts.set(e.tool, { count: 1, last: e.at });\n else {\n prior.count++;\n if (e.at > prior.last) prior.last = e.at;\n }\n }\n\n const by_tool = [...counts.entries()]\n .map(([tool, { count, last }]) => ({ tool, count, last_used: last }))\n .sort((a, b) => b.count - a.count);\n\n const sorted = filtered.slice().sort((a, b) => a.at.localeCompare(b.at));\n\n return {\n total: filtered.length,\n by_tool,\n top: by_tool.slice(0, 10).map(({ tool, count }) => ({ tool, count })),\n window_start: sorted[0]?.at ?? null,\n window_end: sorted[sorted.length - 1]?.at ?? null,\n };\n}\n\n/**\n * Parse a since string: ISO date, or relative like '7d', '24h', '30m'.\n * Returns null when input is empty/undefined.\n */\nexport function parseSince(input: string | undefined): Date | null {\n if (!input) return null;\n const m = input.match(/^(\\d+)([dhm])$/);\n if (m) {\n const n = parseInt(m[1] ?? \"0\", 10);\n const unit = m[2] ?? \"d\";\n const ms = unit === \"d\" ? n * 86400_000 : unit === \"h\" ? n * 3600_000 : n * 60_000;\n return new Date(Date.now() - ms);\n }\n const parsed = new Date(input);\n if (Number.isNaN(parsed.getTime())) return null;\n return parsed;\n}\n\nexport async function usageLogSize(paths: HaivePaths): Promise<{ exists: boolean; size_bytes: number; lines: number }> {\n const file = usageLogPath(paths);\n if (!existsSync(file)) return { exists: false, size_bytes: 0, lines: 0 };\n const st = await stat(file);\n const raw = await readFile(file, \"utf8\");\n return { exists: true, size_bytes: st.size, lines: raw.split(\"\\n\").filter((l) => l).length };\n}\n","/**\n * Named budgets for get_briefing so agents choose quality vs token cost intentionally.\n */\n\nexport type BriefingBudgetPreset = \"quick\" | \"balanced\" | \"deep\";\n\nexport interface BriefingBudgetNumbers {\n max_tokens: number;\n max_memories: number;\n include_module_contexts: boolean;\n}\n\nexport const BRIEFING_PRESET_DEFAULTS: Record<BriefingBudgetPreset, BriefingBudgetNumbers> = {\n /** Fast session start — minimal tokens, skip module CONTEXT.md slices */\n quick: { max_tokens: 2500, max_memories: 5, include_module_contexts: false },\n /** Historical defaults for get_briefing */\n balanced: { max_tokens: 8000, max_memories: 8, include_module_contexts: true },\n /** Deep refactor / onboarding — richer memory surface */\n deep: { max_tokens: 16_000, max_memories: 14, include_module_contexts: true },\n};\n\n/**\n * Merge preset-derived numbers with caller overrides when no preset was selected.\n */\nexport function resolveBriefingBudget(\n preset: BriefingBudgetPreset | undefined,\n overrides: BriefingBudgetNumbers,\n): BriefingBudgetNumbers {\n if (!preset) return { ...overrides };\n const p = BRIEFING_PRESET_DEFAULTS[preset];\n return {\n max_tokens: p.max_tokens,\n max_memories: p.max_memories,\n include_module_contexts: p.include_module_contexts,\n };\n}\n","/**\n * Strip memory markdown down to actionable bullet lines — cheaper for briefing payloads.\n */\n\nconst MAX_DEFAULT_CHARS = 1200;\n\n/**\n * Prefer markdown list lines; fall back to the first substantive paragraph block.\n */\nexport function extractActionsBriefBody(markdown: string, maxChars = MAX_DEFAULT_CHARS): string {\n const stripped = markdown.replace(/\\r/g, \"\").trim();\n if (!stripped) return \"\";\n\n const lines = stripped.split(\"\\n\");\n const bullets: string[] = [];\n for (const line of lines) {\n const m = line.match(/^\\s*[-*+]\\s+(.+)/);\n if (m?.[1]) {\n bullets.push(`- ${m[1].trim()}`);\n if (bullets.join(\"\\n\").length >= maxChars) break;\n }\n }\n if (bullets.length >= 2) {\n let text = bullets.join(\"\\n\");\n if (text.length > maxChars) text = text.slice(0, maxChars).trimEnd() + \"…\";\n return text;\n }\n\n // Single bullet or none — take contiguous non-empty paragraphs (skip headings)\n const paragraphs: string[] = [];\n let buf: string[] = [];\n for (const line of lines) {\n const t = line.trim();\n if (!t) {\n if (buf.length) {\n paragraphs.push(buf.join(\" \").trim());\n buf = [];\n }\n continue;\n }\n if (t.startsWith(\"#\") || t.startsWith(\"```\")) {\n if (buf.length) {\n paragraphs.push(buf.join(\" \").trim());\n buf = [];\n }\n continue;\n }\n buf.push(t);\n }\n if (buf.length) paragraphs.push(buf.join(\" \").trim());\n\n let out = paragraphs[0] ?? stripped.slice(0, maxChars);\n if (!out.trim()) out = stripped.slice(0, maxChars);\n if (out.length > maxChars) out = out.slice(0, maxChars).trimEnd() + \"…\";\n return out;\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { findProjectRoot, resolveHaivePaths } from \"./paths.js\";\n\nconst ROOT_MARKERS = [\".ai\", \".git\", \"package.json\"] as const;\n\nexport interface ResolveProjectInfo {\n cwd: string;\n resolved_root: string;\n haive_project_root_env: string | null;\n explicit_root: boolean;\n haive_dir_exists: boolean;\n memories_dir_exists: boolean;\n runtime_dir: string;\n /** Which of `.ai`, `.git`, `package.json` exist at `resolved_root`. */\n markers_found: string[];\n}\n\nfunction markersAtRoot(root: string): string[] {\n const found: string[] = [];\n for (const m of ROOT_MARKERS) {\n if (existsSync(path.join(root, m))) found.push(m);\n }\n return found;\n}\n\n/**\n * Resolve the hAIve project root for diagnostics (MCP / CLI). Never throws.\n */\nexport function resolveProjectInfo(opts: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n} = {}): ResolveProjectInfo {\n const env = opts.env ?? process.env;\n const cwd = path.resolve(opts.cwd ?? process.cwd());\n const raw = env.HAIVE_PROJECT_ROOT;\n const explicit =\n raw !== undefined && raw !== \"\" ? path.resolve(raw) : null;\n const resolvedRoot = explicit ?? findProjectRoot(cwd);\n const paths = resolveHaivePaths(resolvedRoot);\n return {\n cwd,\n resolved_root: resolvedRoot,\n haive_project_root_env: explicit,\n explicit_root: explicit != null,\n haive_dir_exists: existsSync(paths.haiveDir),\n memories_dir_exists: existsSync(paths.memoriesDir),\n runtime_dir: paths.runtimeDir,\n markers_found: markersAtRoot(resolvedRoot),\n };\n}\n","import type { MemoryType } from \"./types.js\";\n\nconst TYPE_TO_FAMILY: Partial<Record<MemoryType, string>> = {\n architecture: \"architecture\",\n convention: \"pattern\",\n decision: \"decision\",\n gotcha: \"bug\",\n attempt: \"bug\",\n glossary: \"discovery\",\n skill: \"skill\",\n session_recap: \"session\",\n};\n\nfunction slugifyTitle(title: string): string {\n const s = title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return s.length > 0 ? s.slice(0, 60) : \"untitled\";\n}\n\n/**\n * Suggest a stable `topic` frontmatter key (topic-upsert) from type + title.\n */\nexport function suggestTopicKey(\n type: string,\n titleOrPhrase: string,\n): { topic_key: string; family: string } {\n const family = TYPE_TO_FAMILY[type as MemoryType] ?? \"discovery\";\n const slug = slugifyTitle(titleOrPhrase);\n return { topic_key: `${family}/${slug}`, family };\n}\n","import type { LoadedMemory } from \"./loader.js\";\n\nfunction tokenizeDoc(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9_]+/)\n .map((w) => w.trim())\n .filter((w) => w.length >= 2);\n}\n\nfunction memorySearchText(loaded: LoadedMemory): string {\n const fm = loaded.memory.frontmatter;\n return [\n fm.id,\n fm.type,\n fm.tags.join(\" \"),\n loaded.memory.body,\n fm.module ?? \"\",\n fm.topic ?? \"\",\n ...fm.anchor.paths,\n ...fm.anchor.symbols,\n ].join(\" \");\n}\n\nexport interface LexicalRankResult {\n ranked: LoadedMemory[];\n scores: number[];\n}\n\n/**\n * Okapi-BM25–style ranking over a small in-memory corpus (no extra index file).\n */\nexport function rankMemoriesLexical(\n loadedMemories: LoadedMemory[],\n query: string,\n limit: number,\n): LexicalRankResult {\n const qTokens = tokenizeDoc(query);\n if (qTokens.length === 0 || loadedMemories.length === 0) {\n return { ranked: [], scores: [] };\n }\n\n const docs = loadedMemories.map((loaded) => ({\n loaded,\n tokens: tokenizeDoc(memorySearchText(loaded)),\n }));\n\n const N = docs.length;\n const df = new Map<string, number>();\n for (const { tokens } of docs) {\n const seen = new Set(tokens);\n for (const t of seen) {\n df.set(t, (df.get(t) ?? 0) + 1);\n }\n }\n\n const avgdl =\n docs.reduce((s, d) => s + d.tokens.length, 0) / Math.max(N, 1);\n const k1 = 1.2;\n const b = 0.75;\n\n function scoreDoc(tokens: string[]): number {\n if (tokens.length === 0) return 0;\n let score = 0;\n const len = tokens.length;\n const tfCounts = new Map<string, number>();\n for (const t of tokens) {\n tfCounts.set(t, (tfCounts.get(t) ?? 0) + 1);\n }\n\n for (const qt of qTokens) {\n const tf = tfCounts.get(qt) ?? 0;\n if (tf === 0) continue;\n const dfi = df.get(qt) ?? 0;\n const idf = Math.log(1 + (N - dfi + 0.5) / (dfi + 0.5));\n const denom = tf + k1 * (1 - b + (b * len) / avgdl);\n const okapiTf = (tf * (k1 + 1)) / denom;\n score += idf * okapiTf;\n }\n return score;\n }\n\n const scored = docs\n .map(({ loaded, tokens }) => ({ loaded, score: scoreDoc(tokens) }))\n .filter((x) => x.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n\n return {\n ranked: scored.map((x) => x.loaded),\n scores: scored.map((x) => x.score),\n };\n}\n","import type { LoadedMemory } from \"./loader.js\";\nimport { pathsOverlap } from \"./relevance.js\";\n\nfunction anchorPathsOverlap(\n fmA: LoadedMemory[\"memory\"][\"frontmatter\"],\n fmB: LoadedMemory[\"memory\"][\"frontmatter\"],\n): boolean {\n for (const a of fmA.anchor.paths) {\n for (const b of fmB.anchor.paths) {\n if (pathsOverlap(a, b)) return true;\n }\n }\n return false;\n}\n\nexport function firstMemoryOneLine(body: string): string {\n const heading = body.match(/^\\s*#\\s+(.+)$/m)?.[1]?.trim();\n const line =\n heading ??\n body\n .split(\"\\n\")\n .map((l) => l.trim())\n .find((l) => l.length > 0);\n return (line ?? \"\").slice(0, 280);\n}\n\nexport interface TimelineEntry {\n id: string;\n type: string;\n scope: string;\n created_at: string;\n one_line: string;\n topic?: string;\n}\n\nexport interface CollectTimelineOpts {\n memoryId?: string;\n topic?: string;\n limit: number;\n}\n\n/**\n * Memories related by id seed (related_ids, shared topic, anchor overlap) or by topic alone.\n */\nexport function collectTimelineEntries(\n all: LoadedMemory[],\n opts: CollectTimelineOpts,\n): { entries: TimelineEntry[]; notice?: string } {\n if (!opts.memoryId && !opts.topic) {\n return { entries: [], notice: \"Provide memory_id and/or topic\" };\n }\n\n const byId = new Map(all.map((l) => [l.memory.frontmatter.id, l]));\n\n if (opts.topic && !opts.memoryId) {\n const matches = all.filter((l) => l.memory.frontmatter.topic === opts.topic);\n matches.sort((a, b) =>\n a.memory.frontmatter.created_at.localeCompare(b.memory.frontmatter.created_at),\n );\n return {\n entries: matches.slice(0, opts.limit).map((l) => toEntry(l)),\n };\n }\n\n const seed = byId.get(opts.memoryId!);\n if (!seed) {\n return { entries: [], notice: `No memory with id \"${opts.memoryId}\"` };\n }\n\n const collected = new Set<string>();\n const add = (id: string) => {\n if (byId.has(id)) collected.add(id);\n };\n\n add(seed.memory.frontmatter.id);\n for (const rid of seed.memory.frontmatter.related_ids) add(rid);\n\n const seedTopic = seed.memory.frontmatter.topic;\n if (seedTopic) {\n for (const l of all) {\n if (l.memory.frontmatter.topic === seedTopic) add(l.memory.frontmatter.id);\n }\n }\n\n for (const l of all) {\n if (anchorPathsOverlap(seed.memory.frontmatter, l.memory.frontmatter)) {\n add(l.memory.frontmatter.id);\n }\n }\n\n const firstHop = [...collected];\n for (const id of firstHop) {\n const m = byId.get(id);\n if (!m) continue;\n for (const rid of m.memory.frontmatter.related_ids) add(rid);\n }\n\n let sorted = [...collected]\n .map((id) => byId.get(id)!)\n .filter(Boolean)\n .sort((a, b) =>\n a.memory.frontmatter.created_at.localeCompare(b.memory.frontmatter.created_at),\n );\n\n if (opts.topic) {\n sorted = sorted.filter((l) => l.memory.frontmatter.topic === opts.topic);\n }\n\n return {\n entries: sorted.slice(0, opts.limit).map((l) => toEntry(l)),\n };\n}\n\nfunction toEntry(l: LoadedMemory): TimelineEntry {\n const fm = l.memory.frontmatter;\n const base: TimelineEntry = {\n id: fm.id,\n type: fm.type,\n scope: fm.scope,\n created_at: fm.created_at,\n one_line: firstMemoryOneLine(l.memory.body),\n };\n if (fm.topic !== undefined && fm.topic !== \"\") {\n return { ...base, topic: fm.topic };\n }\n return base;\n}\n","import type { LoadedMemory } from \"./loader.js\";\n\nfunction tokenSetForConflict(loaded: LoadedMemory): Set<string> {\n const fm = loaded.memory.frontmatter;\n const heading = loaded.memory.body.match(/^\\s*#\\s+(.+)$/m)?.[1] ?? \"\";\n const blob = `${fm.id} ${heading} ${loaded.memory.body.slice(0, 2000)}`;\n const tokens = blob\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .map((w) => w.trim())\n .filter((w) => w.length >= 3);\n return new Set(tokens);\n}\n\nfunction jaccard(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 || b.size === 0) return 0;\n let inter = 0;\n for (const x of a) {\n if (b.has(x)) inter++;\n }\n const uni = a.size + b.size - inter;\n return uni === 0 ? 0 : inter / uni;\n}\n\nexport interface ConflictCandidatesOpts {\n sinceDays: number;\n types: string[];\n minJaccard: number;\n maxPairs: number;\n /** Hard cap on memories considered ( avoids O(n²) explosions). */\n maxScan: number;\n}\n\nexport interface ConflictCandidatePair {\n id_a: string;\n id_b: string;\n jaccard: number;\n}\n\nexport interface TopicStatusPair {\n id_a: string;\n id_b: string;\n topic: string;\n status_a: string;\n status_b: string;\n}\n\n/**\n * Same `topic` key with opposed trust (validated vs rejected) — advisory; use `mem_conflicts_with` per id next.\n */\nexport function findTopicStatusConflictPairs(\n memories: LoadedMemory[],\n maxPairs: number,\n): TopicStatusPair[] {\n const byTopic = new Map<string, LoadedMemory[]>();\n for (const l of memories) {\n const topic = l.memory.frontmatter.topic;\n if (!topic || topic.trim() === \"\") continue;\n const g = byTopic.get(topic);\n if (g) g.push(l);\n else byTopic.set(topic, [l]);\n }\n const out: TopicStatusPair[] = [];\n for (const [topic, group] of byTopic) {\n if (group.length < 2) continue;\n for (let i = 0; i < group.length && out.length < maxPairs; i++) {\n for (let j = i + 1; j < group.length && out.length < maxPairs; j++) {\n const sa = group[i]!.memory.frontmatter.status;\n const sb = group[j]!.memory.frontmatter.status;\n if (\n (sa === \"validated\" && sb === \"rejected\") ||\n (sa === \"rejected\" && sb === \"validated\")\n ) {\n out.push({\n id_a: group[i]!.memory.frontmatter.id,\n id_b: group[j]!.memory.frontmatter.id,\n topic,\n status_a: sa,\n status_b: sb,\n });\n }\n }\n }\n }\n return out;\n}\n\n/**\n * Bulk heuristic: lexical similarity pairs for human review → often followed by `mem_conflicts_with`.\n */\nexport function findLexicalConflictPairs(\n memories: LoadedMemory[],\n opts: ConflictCandidatesOpts,\n): { pairs: ConflictCandidatePair[]; scanned: number; truncated: boolean } {\n const cutoff = Date.now() - opts.sinceDays * 86_400_000;\n let pool = memories.filter((l) => {\n const fm = l.memory.frontmatter;\n if (!opts.types.includes(fm.type)) return false;\n const t = Date.parse(fm.created_at);\n return !Number.isNaN(t) && t >= cutoff;\n });\n pool.sort((a, b) =>\n b.memory.frontmatter.created_at.localeCompare(a.memory.frontmatter.created_at),\n );\n let truncated = false;\n if (pool.length > opts.maxScan) {\n pool = pool.slice(0, opts.maxScan);\n truncated = true;\n }\n const sets = pool.map((l) => ({\n id: l.memory.frontmatter.id,\n set: tokenSetForConflict(l),\n }));\n\n const pairs: ConflictCandidatePair[] = [];\n for (let i = 0; i < sets.length; i++) {\n for (let j = i + 1; j < sets.length; j++) {\n const jac = jaccard(sets[i]!.set, sets[j]!.set);\n if (jac >= opts.minJaccard) {\n pairs.push({ id_a: sets[i]!.id, id_b: sets[j]!.id, jaccard: jac });\n }\n }\n }\n pairs.sort((a, b) => b.jaccard - a.jaccard);\n return {\n pairs: pairs.slice(0, opts.maxPairs),\n scanned: pool.length,\n truncated,\n };\n}\n","import { mkdir, readFile, appendFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const RUNTIME_JOURNAL_FILENAME = \"session-journal.ndjson\";\n\nexport interface RuntimeJournalEntry {\n ts: string;\n kind: \"note\" | \"session_end\" | \"mcp\";\n /** Short human or agent message */\n message: string;\n /** Optional MCP tool name for kind=mcp */\n tool?: string;\n /** Arbitrary JSON-serializable metadata */\n meta?: Record<string, unknown>;\n}\n\nexport function runtimeJournalPath(paths: HaivePaths): string {\n return path.join(paths.runtimeDir, RUNTIME_JOURNAL_FILENAME);\n}\n\n/**\n * Append one NDJSON line under `.ai/.runtime/` (untracked by default).\n * Never throws to callers of shutdown hooks — wraps internally.\n */\nexport async function appendRuntimeJournalEntry(\n paths: HaivePaths,\n entry: Omit<RuntimeJournalEntry, \"ts\"> & { ts?: string },\n): Promise<void> {\n try {\n await mkdir(paths.runtimeDir, { recursive: true });\n const line: RuntimeJournalEntry = {\n ts: entry.ts ?? new Date().toISOString(),\n kind: entry.kind,\n message: entry.message,\n ...(entry.tool !== undefined ? { tool: entry.tool } : {}),\n ...(entry.meta !== undefined ? { meta: entry.meta } : {}),\n };\n await appendFile(\n runtimeJournalPath(paths),\n JSON.stringify(line) + \"\\n\",\n \"utf8\",\n );\n } catch {\n // non-fatal — runtime layer must not break tools\n }\n}\n\n/** Read last N valid JSON lines (oldest-first in returned array). */\nexport async function readRuntimeJournalTail(\n paths: HaivePaths,\n limit: number,\n): Promise<RuntimeJournalEntry[]> {\n const file = runtimeJournalPath(paths);\n if (!existsSync(file) || limit <= 0) return [];\n try {\n const raw = await readFile(file, \"utf8\");\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n const parsed: RuntimeJournalEntry[] = [];\n for (const line of lines.slice(-limit)) {\n try {\n parsed.push(JSON.parse(line) as RuntimeJournalEntry);\n } catch {\n /* skip corrupt line */\n }\n }\n return parsed;\n } catch {\n return [];\n }\n}\n","import { mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const BRIEFING_MARKER_TTL_MS = 12 * 60 * 60 * 1000;\nexport const SESSION_RECAP_TTL_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport interface BriefingMarker {\n session_id: string;\n task?: string;\n source: string;\n created_at: string;\n root: string;\n memory_ids?: string[];\n files?: string[];\n}\n\nexport function enforcementDir(paths: HaivePaths): string {\n return path.join(paths.runtimeDir, \"enforcement\");\n}\n\nexport function briefingMarkersDir(paths: HaivePaths): string {\n return path.join(enforcementDir(paths), \"briefings\");\n}\n\nexport function normalizeSessionId(sessionId?: string): string {\n return (sessionId?.trim() || \"default\").replace(/[^a-zA-Z0-9_.-]+/g, \"-\").slice(0, 120);\n}\n\nexport function briefingMarkerPath(paths: HaivePaths, sessionId?: string): string {\n return path.join(briefingMarkersDir(paths), `${normalizeSessionId(sessionId)}.json`);\n}\n\nexport async function writeBriefingMarker(\n paths: HaivePaths,\n input: { sessionId?: string; task?: string; source: string; memoryIds?: string[]; files?: string[] },\n): Promise<BriefingMarker> {\n const marker: BriefingMarker = {\n session_id: normalizeSessionId(input.sessionId),\n ...(input.task?.trim() ? { task: input.task.trim() } : {}),\n ...(input.memoryIds && input.memoryIds.length > 0 ? { memory_ids: [...new Set(input.memoryIds)] } : {}),\n ...(input.files && input.files.length > 0 ? { files: [...new Set(input.files)] } : {}),\n source: input.source,\n created_at: new Date().toISOString(),\n root: paths.root,\n };\n await mkdir(briefingMarkersDir(paths), { recursive: true });\n await writeFile(\n briefingMarkerPath(paths, marker.session_id),\n JSON.stringify(marker, null, 2) + \"\\n\",\n \"utf8\",\n );\n return marker;\n}\n\nexport async function hasRecentBriefingMarker(\n paths: HaivePaths,\n sessionId?: string,\n ttlMs = BRIEFING_MARKER_TTL_MS,\n): Promise<boolean> {\n const now = Date.now();\n const candidates: string[] = [];\n const exact = briefingMarkerPath(paths, sessionId);\n if (existsSync(exact)) candidates.push(exact);\n try {\n const dir = briefingMarkersDir(paths);\n const files = await readdir(dir);\n for (const file of files) {\n if (file.endsWith(\".json\")) candidates.push(path.join(dir, file));\n }\n } catch {\n // no marker directory yet\n }\n\n for (const file of new Set(candidates)) {\n try {\n const marker = JSON.parse(await readFile(file, \"utf8\")) as BriefingMarker;\n const created = Date.parse(marker.created_at);\n if (Number.isFinite(created) && now - created <= ttlMs) return true;\n } catch {\n // ignore corrupt markers\n }\n }\n return false;\n}\n\nexport async function readRecentBriefingMarker(\n paths: HaivePaths,\n sessionId?: string,\n ttlMs = BRIEFING_MARKER_TTL_MS,\n): Promise<BriefingMarker | null> {\n const now = Date.now();\n const candidates: string[] = [];\n const exact = briefingMarkerPath(paths, sessionId);\n if (existsSync(exact)) candidates.push(exact);\n try {\n const dir = briefingMarkersDir(paths);\n const files = await readdir(dir);\n for (const file of files) {\n if (file.endsWith(\".json\")) candidates.push(path.join(dir, file));\n }\n } catch {\n // no marker directory yet\n }\n\n let freshest: BriefingMarker | null = null;\n let freshestTs = 0;\n for (const file of new Set(candidates)) {\n try {\n const marker = JSON.parse(await readFile(file, \"utf8\")) as BriefingMarker;\n const created = Date.parse(marker.created_at);\n if (!Number.isFinite(created) || now - created > ttlMs) continue;\n if (created > freshestTs) {\n freshest = marker;\n freshestTs = created;\n }\n } catch {\n // ignore corrupt markers\n }\n }\n return freshest;\n}\n\nexport function isFreshIsoDate(value: string | Date, ttlMs: number, now = Date.now()): boolean {\n const ts = value instanceof Date ? value.getTime() : Date.parse(value);\n return Number.isFinite(ts) && now - ts <= ttlMs;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\n\nexport interface RetirementSignal {\n retired: boolean;\n reason?: string;\n}\n\nconst RETIRED_TAGS = new Set([\"superseded\", \"obsolete\", \"archived\"]);\n\nconst RETIRED_BODY_PATTERNS: Array<{ re: RegExp; reason: string }> = [\n { re: /\\bfixed\\s+in\\b[\\s\\S]{0,160}\\b(audit|history|historical|obsolete|no longer applies)\\b/i, reason: \"body says this fixed record is audit/history only\" },\n { re: /\\bresolved\\s+in\\b/i, reason: \"body says this was resolved\" },\n { re: /\\bsuperseded\\s+by\\b/i, reason: \"body says this was superseded\" },\n { re: /\\bno\\s+longer\\s+(applies|true|valid)\\b/i, reason: \"body says this no longer applies\" },\n { re: /\\bobsolete\\b/i, reason: \"body says this is obsolete\" },\n];\n\n/**\n * Explicit lifecycle gate for records that should not be fed back to agents as active policy.\n *\n * `status=deprecated/rejected/stale` is already the hard lifecycle signal. This helper covers\n * softer signals that teams naturally write while curating a corpus: an `expires_when` date,\n * a `superseded`/`obsolete` tag, or a short body note saying the attempt is now obsolete.\n *\n * Note: a plain `fixed` tag is intentionally NOT retired by itself. Many teams keep fixed\n * gotchas active as regression guards. To retire one, mark it deprecated, set expires_when,\n * use `obsolete`/`superseded`, or write that the fixed record is kept for audit/history only.\n */\nexport function retirementSignal(\n fm: MemoryFrontmatter,\n body = \"\",\n now: Date = new Date(),\n): RetirementSignal {\n if (fm.status === \"deprecated\" || fm.status === \"rejected\" || fm.status === \"stale\") {\n return { retired: true, reason: `status=${fm.status}` };\n }\n\n if (fm.expires_when) {\n const expiresAt = Date.parse(fm.expires_when);\n if (Number.isFinite(expiresAt) && expiresAt <= now.getTime()) {\n return { retired: true, reason: `expired on ${fm.expires_when.slice(0, 10)}` };\n }\n }\n\n const retiredTag = fm.tags.find((tag) => RETIRED_TAGS.has(tag.toLowerCase()));\n if (retiredTag) {\n return { retired: true, reason: `tagged ${retiredTag}` };\n }\n\n for (const pattern of RETIRED_BODY_PATTERNS) {\n if (pattern.re.test(body)) return { retired: true, reason: pattern.reason };\n }\n\n return { retired: false };\n}\n\nexport function isRetiredMemory(\n fm: MemoryFrontmatter,\n body = \"\",\n now: Date = new Date(),\n): boolean {\n return retirementSignal(fm, body, now).retired;\n}\n","import type { Memory, Sensor } from \"./types.js\";\n\n/**\n * Sensors — the feedback *computational* layer of the harness.\n *\n * A memory's `sensor` turns a documented lesson (gotcha/attempt) into a deterministic\n * check. Unlike semantic anti-pattern matching (probabilistic, warmup-sensitive), a\n * regex sensor fires the same way every time, so a known mistake becomes a permanent\n * guardrail. Phase 1 supports `kind: \"regex\"` only — pure, no I/O. `shell`/`test`\n * sensors are recognized but not executed here (they must run from the CLI).\n */\n\nexport interface SensorHit {\n /** The memory id whose sensor matched. */\n memory_id: string;\n /** The sensor that matched. */\n sensor: Sensor;\n /** Project-relative file the match was found in (when known). */\n file?: string;\n /** The matched line (trimmed, capped) — useful for review output. */\n matched_line?: string;\n /** LLM-facing self-correction message carried from the sensor. */\n message: string;\n severity: Sensor[\"severity\"];\n}\n\n/** A unit of code to scan: a file path plus the text to match against. */\nexport interface SensorTarget {\n /** Project-relative path (used for path scoping and reporting). */\n path: string;\n /**\n * Text to scan. For a diff, pass only the added lines (callers should pre-filter)\n * so a sensor fires on \"you introduced the bad pattern\", not \"you touched a file\n * that merely mentions it\".\n */\n content: string;\n}\n\nfunction normalizeProjectPath(value: string): string {\n return value\n .replace(/\\\\/g, \"/\")\n .replace(/^\\.\\//, \"\")\n .replace(/^[ab]\\//, \"\")\n .replace(/\\/+$/g, \"\");\n}\n\n/**\n * Does this sensor apply to `path`? A sensor with no explicit `paths` (and whose\n * memory has no anchor paths) applies everywhere. Otherwise it applies only to the\n * exact file or directory prefix. Use an explicit directory path (`src/foo/`) when a\n * sensor should cover a whole subtree.\n */\nexport function sensorAppliesToPath(\n sensor: Sensor,\n anchorPaths: string[],\n path: string,\n): boolean {\n const scopes = sensor.paths.length > 0 ? sensor.paths : anchorPaths;\n if (scopes.length === 0) return true;\n const target = normalizeProjectPath(path);\n return scopes.some((rawScope) => {\n const scope = normalizeProjectPath(rawScope);\n if (!scope) return false;\n return target === scope || target.startsWith(`${scope}/`);\n });\n}\n\n/**\n * Compile a regex sensor. Returns null when the sensor is not a runnable regex\n * (wrong kind, missing/invalid pattern) so callers can skip it safely.\n */\nexport function compileRegexSensor(sensor: Sensor): RegExp | null {\n if (sensor.kind !== \"regex\" || !sensor.pattern) return null;\n try {\n // Always multiline so `^`/`$` work per added line; merge with caller flags.\n const flags = new Set([\"m\", ...(sensor.flags ?? \"\").split(\"\")].filter(Boolean));\n return new RegExp(sensor.pattern, [...flags].join(\"\"));\n } catch {\n return null;\n }\n}\n\n/**\n * Run a single regex sensor over one target. Returns the first matching line as a hit,\n * or null. Deterministic and side-effect-free.\n */\nexport function runRegexSensor(\n memoryId: string,\n sensor: Sensor,\n target: SensorTarget,\n): SensorHit | null {\n const re = compileRegexSensor(sensor);\n if (!re) return null;\n for (const rawLine of target.content.split(\"\\n\")) {\n // Fresh lastIndex each line (no global flag is forced, but be defensive).\n re.lastIndex = 0;\n if (re.test(rawLine)) {\n return {\n memory_id: memoryId,\n sensor,\n file: target.path,\n matched_line: rawLine.trim().slice(0, 200),\n message: sensor.message,\n severity: sensor.severity,\n };\n }\n }\n return null;\n}\n\n/**\n * Run every memory's regex sensor against every applicable target.\n *\n * Memories without a sensor, or with a non-regex sensor, are skipped (non-regex kinds\n * are the CLI's responsibility). At most one hit per (memory, file) pair is returned.\n */\nexport function runSensors(\n memories: Memory[],\n targets: SensorTarget[],\n): SensorHit[] {\n const hits: SensorHit[] = [];\n for (const memory of memories) {\n const sensor = memory.frontmatter.sensor;\n if (!sensor || sensor.kind !== \"regex\") continue;\n const anchorPaths = memory.frontmatter.anchor.paths;\n for (const target of targets) {\n if (!sensorAppliesToPath(sensor, anchorPaths, target.path)) continue;\n const hit = runRegexSensor(memory.frontmatter.id, sensor, target);\n if (hit) hits.push(hit);\n }\n }\n return hits;\n}\n\n/** Split a unified diff into per-file targets containing only added lines. */\nexport function sensorTargetsFromDiff(diff: string): SensorTarget[] {\n const targets: SensorTarget[] = [];\n let currentPath: string | null = null;\n let added: string[] = [];\n\n const flush = (): void => {\n if (!currentPath || added.length === 0) return;\n targets.push({ path: currentPath, content: added.join(\"\\n\") });\n added = [];\n };\n\n for (const line of diff.split(\"\\n\")) {\n if (line.startsWith(\"diff --git \")) {\n flush();\n currentPath = null;\n continue;\n }\n\n if (line.startsWith(\"+++ \")) {\n flush();\n const raw = line.slice(4).trim();\n currentPath = raw === \"/dev/null\" ? null : normalizeProjectPath(raw);\n continue;\n }\n\n if (line.startsWith(\"+\") && !line.startsWith(\"+++\")) {\n if (!currentPath) currentPath = \"\";\n added.push(line.slice(1));\n }\n }\n flush();\n return targets;\n}\n\n/**\n * Extract the added lines from a unified diff (lines starting with a single `+`,\n * excluding the `+++` file header). Mirrors the diff-handling already used by the\n * anti-pattern tokenizer so sensors fire on introductions, not mere mentions.\n */\nexport function addedLinesFromDiff(diff: string): string {\n const targets = sensorTargetsFromDiff(diff);\n if (targets.length > 0) return targets.map((target) => target.content).join(\"\\n\");\n return diff\n .split(\"\\n\")\n .filter((l) => l.startsWith(\"+\") && !l.startsWith(\"+++\"))\n .map((l) => l.slice(1))\n .join(\"\\n\");\n}\n","import type { Sensor } from \"./types.js\";\n\nconst CODE_TOKEN_RE = /`([^`\\n]{3,80})`|[\"']([A-Za-z0-9_.:-]{3,80})[\"']|\\b([A-Za-z][A-Za-z0-9_.:-]{2,79})\\b/g;\n\nconst SENSOR_STOPWORDS = new Set([\n \"about\", \"after\", \"again\", \"agent\", \"always\", \"anchor\", \"approach\", \"because\",\n \"before\", \"break\", \"broken\", \"cannot\", \"change\", \"code\", \"commit\", \"correct\",\n \"could\", \"default\", \"detect\", \"direct\", \"directory\", \"does\", \"error\", \"failed\",\n \"fails\", \"file\", \"files\", \"future\", \"instead\", \"memory\", \"never\", \"project\",\n \"recorded\", \"repo\", \"return\", \"should\", \"source\", \"string\", \"this\",\n \"tried\", \"true\", \"type\", \"undefined\", \"value\", \"when\", \"where\", \"which\", \"with\",\n \"without\",\n]);\n\nexport interface SensorSuggestionOptions {\n /** Extra paths to put on the sensor. Defaults to the memory anchor paths. */\n paths?: string[];\n}\n\n/**\n * Conservatively suggest a regex sensor from a gotcha/attempt body.\n *\n * This helper intentionally returns null more often than it guesses. Autogenerated\n * sensors start as `warn`, never `block`; humans can promote them after seeing them fire.\n */\nexport function suggestSensorFromMemory(\n body: string,\n anchorPaths: string[],\n options: SensorSuggestionOptions = {},\n): Sensor | null {\n const paths = options.paths ?? anchorPaths;\n if (paths.length === 0) return null;\n\n const negativeText = body.split(/\\*\\*Instead,\\s*use:\\*\\*|^##\\s+Instead\\b/im)[0] ?? body;\n const assignment = pickAssignmentPattern(negativeText);\n const lowercaseValue = assignment ? null : pickLowercaseValuePattern(negativeText);\n const token = assignment?.label ?? lowercaseValue?.label ?? pickDistinctiveToken(negativeText);\n if (!token) return null;\n\n return {\n kind: \"regex\",\n pattern: assignment?.pattern ?? lowercaseValue?.pattern ?? escapeRegExp(token),\n paths,\n message: sensorMessageFromBody(body, token),\n severity: \"warn\",\n autogen: true,\n last_fired: null,\n };\n}\n\nfunction pickLowercaseValuePattern(text: string): { label: string; pattern: string; score: number } | null {\n const candidates: Array<{ label: string; pattern: string; score: number }> = [];\n for (const match of text.matchAll(/\\blowercase\\s+([A-Za-z][A-Za-z0-9_.:-]{2,79})\\s+([a-z][a-z0-9_.:-]{1,40})\\b/g)) {\n const key = match[1] ?? \"\";\n const value = match[2] ?? \"\";\n if (!isDistinctiveToken(key, true) || isBoringValue(value)) continue;\n candidates.push({\n label: `${key}=${value}`,\n pattern: `${escapeRegExp(key)}\\\\s*[:=]\\\\s*[\"']?${escapeRegExp(value)}[\"']?`,\n score: key.length + value.length + 35,\n });\n }\n return candidates.sort((a, b) => b.score - a.score)[0] ?? null;\n}\n\nfunction pickAssignmentPattern(text: string): { label: string; pattern: string; score: number } | null {\n const candidates: Array<{ label: string; pattern: string; score: number }> = [];\n for (const source of assignmentSources(text)) {\n for (const match of source.matchAll(/\\b([A-Za-z][A-Za-z0-9_.:-]{2,79})\\b\\s*(=|:)\\s*[\"']?([A-Za-z0-9_.:-]{2,80})[\"']?/g)) {\n const key = match[1] ?? \"\";\n const operator = match[2] ?? \"\";\n const value = match[3] ?? \"\";\n if (!isDistinctiveToken(key, true) || isBoringValue(value)) continue;\n const label = `${key}${operator}${value}`;\n candidates.push({\n label,\n pattern: `${escapeRegExp(key)}\\\\s*${escapeRegExp(operator)}\\\\s*[\"']?${escapeRegExp(value)}[\"']?`,\n score: label.length + assignmentContextScore(source, match.index ?? 0, match[0].length),\n });\n }\n }\n return candidates.sort((a, b) => b.score - a.score)[0] ?? null;\n}\n\nfunction assignmentContextScore(source: string, index: number, length: number): number {\n const before = source.slice(Math.max(0, index - 50), index).toLowerCase();\n const after = source.slice(index + length, Math.min(source.length, index + length + 50)).toLowerCase();\n const window = `${before} ${after}`;\n let score = 0;\n if (/\\b(bad|failed|fails|broke|broken|wrong|avoid|forbid|forbidden|leaks?)\\b/.test(after)) score += 50;\n if (/do\\s+not|don't|never|should\\s+not|must\\s+not/.test(window)) score += 40;\n if (/\\b(keep|instead|correct|right|use|prefer|allowed)\\b/.test(before)) score -= 60;\n if (/\\b(keep|instead|correct|right|use|prefer|allowed)\\b/.test(after)) score -= 25;\n return score;\n}\n\nfunction assignmentSources(text: string): string[] {\n return [text];\n}\n\nfunction pickDistinctiveToken(text: string): string | null {\n const candidates = new Map<string, { raw: string; score: number }>();\n for (const match of text.matchAll(CODE_TOKEN_RE)) {\n const raw = (match[1] ?? match[2] ?? match[3] ?? \"\").trim();\n const token = raw.replace(/^[^\\w.-]+|[^\\w.-]+$/g, \"\");\n const isCodeLike = Boolean(match[1] ?? match[2]);\n if (!isDistinctiveToken(token, isCodeLike)) continue;\n const key = token.toLowerCase();\n const codeSpanBonus = match[1] ? 20 : match[2] ? 8 : 0;\n const shapeBonus =\n /[-_.:]/.test(token) ? 3 :\n /[A-Z]/.test(token.slice(1)) ? 2 :\n /\\d/.test(token) ? 1 : 0;\n const score = token.length + codeSpanBonus + shapeBonus;\n const existing = candidates.get(key);\n if (!existing || score > existing.score) candidates.set(key, { raw: token, score });\n }\n const best = [...candidates.values()].sort((a, b) => b.score - a.score)[0];\n return best?.raw ?? null;\n}\n\nfunction isDistinctiveToken(token: string, isCodeLike: boolean): boolean {\n if (token.length < 4 || token.length > 80) return false;\n if (/^https?:\\/\\//i.test(token)) return false;\n if (/^\\d+$/.test(token)) return false;\n const lower = token.toLowerCase();\n if (SENSOR_STOPWORDS.has(lower)) return false;\n if (!/[A-Za-z]/.test(token)) return false;\n const shaped = /[-_.:\\d]/.test(token) || /[A-Z]/.test(token.slice(1));\n return shaped || isCodeLike;\n}\n\nfunction isBoringValue(value: string): boolean {\n if (!value || value.length > 80) return true;\n const lower = value.toLowerCase();\n if (lower === \"true\" || lower === \"false\") return false;\n return SENSOR_STOPWORDS.has(lower);\n}\n\nfunction sensorMessageFromBody(body: string, token: string): string {\n const instead = body.match(/\\*\\*Instead,\\s*use:\\*\\*\\s*([^\\n]+)/i)?.[1]?.trim();\n if (instead) return `Avoid ${token}; ${instead}`;\n const firstGuidance = body\n .split(\"\\n\")\n .map((line) => line.replace(/^#+\\s*/, \"\").trim())\n .find((line) => line.length > 0 && !line.startsWith(\"---\"));\n return firstGuidance?.slice(0, 180) || `Avoid ${token}; this matched an autogenerated hAIve sensor.`;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":["path","path","readFile","readdir","existsSync","path","path","path","existsSync","readFile","readdir","readFile","existsSync","path","round3","MS_PER_DAY","mkdir","readFile","readdir","writeFile","existsSync","path","existsSync","readFile","writeFile","path","existsSync","mkdir","readFile","writeFile","path","spawnSync","path","existsSync","readFile","writeFile","mkdir","spawnSync","existsSync","readFile","writeFile","mkdir","path","snapshot","existsSync","readFile","writeFile","mkdir","path","mkdir","readFile","stat","existsSync","path","existsSync","path","ROOT_MARKERS","existsSync","path","b","mkdir","readFile","appendFile","existsSync","path","mkdir","readdir","readFile","writeFile","existsSync","path","path","isDistinctiveToken"]}