@orquentra/codebuddy 2.6.0 → 2.6.2
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/CLAUDE_CODEX.md +6 -4
- package/WORKFLOW.md +5 -5
- package/dist/{chunk-UN57FKQX.js → chunk-2XDPKFUW.js} +111 -847
- package/dist/chunk-2XDPKFUW.js.map +1 -0
- package/dist/{chunk-QDBDYCM2.js → chunk-5FW3PMNP.js} +2 -2
- package/dist/{chunk-776EQXDV.js → chunk-5KZY6OTG.js} +82 -5
- package/dist/chunk-5KZY6OTG.js.map +1 -0
- package/dist/{chunk-UFZD3JAA.js → chunk-5MQOE4J6.js} +3 -3
- package/dist/chunk-5UH3BEQR.js +32 -0
- package/dist/chunk-5UH3BEQR.js.map +1 -0
- package/dist/{chunk-N34XHWBA.js → chunk-B6CO63SQ.js} +8 -7
- package/dist/chunk-B6CO63SQ.js.map +1 -0
- package/dist/chunk-CSRD5OQA.js +79 -0
- package/dist/chunk-CSRD5OQA.js.map +1 -0
- package/dist/{chunk-PYLH4MH5.js → chunk-FJOTP632.js} +1 -1
- package/dist/{chunk-U4HAJLIB.js → chunk-IBLJOHJL.js} +15 -2
- package/dist/chunk-IBLJOHJL.js.map +1 -0
- package/dist/chunk-IMFUYEZA.js +1607 -0
- package/dist/chunk-IMFUYEZA.js.map +1 -0
- package/dist/{chunk-SYWJG5NA.js → chunk-J2EAZ4MA.js} +20 -7
- package/dist/chunk-J2EAZ4MA.js.map +1 -0
- package/dist/{chunk-L5AYZC3F.js → chunk-NERKZSSE.js} +7 -7
- package/dist/{chunk-PCE4STAY.js → chunk-OWWCDRXW.js} +5 -5
- package/dist/{chunk-WHZSVY2L.js → chunk-QBDJXGG5.js} +2 -2
- package/dist/{chunk-VAKBJV26.js → chunk-R7CD6EXS.js} +307 -1822
- package/dist/chunk-R7CD6EXS.js.map +1 -0
- package/dist/{chunk-6MKEIDX5.js → chunk-RAJJSCIP.js} +2 -2
- package/dist/chunk-S6VEG4S2.js +991 -0
- package/dist/chunk-S6VEG4S2.js.map +1 -0
- package/dist/cli/index.js +14 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/{codebuddy-DM-i0Fu5.d.ts → codebuddy-B_pCaQrV.d.ts} +22 -2
- package/dist/{config-KFEHLV6W.js → config-DEVHUDIU.js} +3 -3
- package/dist/docker-autostart-KDME7TVC.js +12 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +19 -15
- package/dist/langgraph/index.d.ts +1 -1
- package/dist/lean-command-HTQCPH76.js +15 -0
- package/dist/{local-OTOY56B4.js → local-5MZURLCZ.js} +6 -2
- package/dist/{main-HFHLGID4.js → main-MTBQZGJV.js} +139 -171
- package/dist/main-MTBQZGJV.js.map +1 -0
- package/dist/{memory-4RGVLPKG.js → memory-KIC5FJVW.js} +4 -4
- package/dist/{operations-LOBAQRLO.js → operations-POCHY3WR.js} +5 -4
- package/dist/postgres-docker-QQZQ2ABK.js +16 -0
- package/dist/{pretool-command-MQQ2UNQM.js → pretool-command-AX6JXP25.js} +3 -3
- package/dist/{rerank-3P3C2UHN.js → rerank-5QZ3PNUW.js} +4 -4
- package/dist/runtime-CUBOOPZO.js +43 -0
- package/dist/runtime-CUBOOPZO.js.map +1 -0
- package/dist/stdio-HOV4P3DQ.js +12 -0
- package/dist/stdio-HOV4P3DQ.js.map +1 -0
- package/dist/{summaries-ZBV5IN7Y.js → summaries-SB5L2TSW.js} +6 -6
- package/dist/summaries-SB5L2TSW.js.map +1 -0
- package/dist/{zvec-MAPSJQSR.js → zvec-MSRKT7IV.js} +3 -3
- package/dist/zvec-MSRKT7IV.js.map +1 -0
- package/package.json +7 -10
- package/dist/chunk-776EQXDV.js.map +0 -1
- package/dist/chunk-N34XHWBA.js.map +0 -1
- package/dist/chunk-SYWJG5NA.js.map +0 -1
- package/dist/chunk-U4HAJLIB.js.map +0 -1
- package/dist/chunk-UN57FKQX.js.map +0 -1
- package/dist/chunk-VAKBJV26.js.map +0 -1
- package/dist/lean-command-C5YPFKHP.js +0 -15
- package/dist/main-HFHLGID4.js.map +0 -1
- /package/dist/{chunk-QDBDYCM2.js.map → chunk-5FW3PMNP.js.map} +0 -0
- /package/dist/{chunk-UFZD3JAA.js.map → chunk-5MQOE4J6.js.map} +0 -0
- /package/dist/{chunk-PYLH4MH5.js.map → chunk-FJOTP632.js.map} +0 -0
- /package/dist/{chunk-L5AYZC3F.js.map → chunk-NERKZSSE.js.map} +0 -0
- /package/dist/{chunk-PCE4STAY.js.map → chunk-OWWCDRXW.js.map} +0 -0
- /package/dist/{chunk-WHZSVY2L.js.map → chunk-QBDJXGG5.js.map} +0 -0
- /package/dist/{chunk-6MKEIDX5.js.map → chunk-RAJJSCIP.js.map} +0 -0
- /package/dist/{config-KFEHLV6W.js.map → config-DEVHUDIU.js.map} +0 -0
- /package/dist/{lean-command-C5YPFKHP.js.map → docker-autostart-KDME7TVC.js.map} +0 -0
- /package/dist/{local-OTOY56B4.js.map → lean-command-HTQCPH76.js.map} +0 -0
- /package/dist/{operations-LOBAQRLO.js.map → local-5MZURLCZ.js.map} +0 -0
- /package/dist/{memory-4RGVLPKG.js.map → memory-KIC5FJVW.js.map} +0 -0
- /package/dist/{pretool-command-MQQ2UNQM.js.map → operations-POCHY3WR.js.map} +0 -0
- /package/dist/{summaries-ZBV5IN7Y.js.map → postgres-docker-QQZQ2ABK.js.map} +0 -0
- /package/dist/{zvec-MAPSJQSR.js.map → pretool-command-AX6JXP25.js.map} +0 -0
- /package/dist/{rerank-3P3C2UHN.js.map → rerank-5QZ3PNUW.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/runtime.ts","../src/context/engine.ts","../src/core/plan-file-store.ts","../src/core/plan-lifecycle.ts","../src/risk/service.ts","../src/risk/assessor.ts","../src/risk/signals/churn.ts","../src/risk/signals/incident.ts","../src/risk/signals/policy.ts","../src/worklog/store.ts","../src/context/budget.ts","../src/memory-extract/engine.ts","../src/memory-extract/deterministic.ts","../src/memory-extract/llm.ts","../src/memory-extract/resolution.ts","../src/memory-extract/review-store.ts","../src/memory-extract/rules.ts","../src/tracing/log.ts","../src/hooks/semantic.ts","../src/hooks/staging.ts"],"sourcesContent":["import { mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport pTimeout from \"p-timeout\";\nimport { buildBeforeEditContext, buildBootstrapContext } from \"../context/engine.js\";\nimport { type ContextCapsule, SessionCapsuleLedger } from \"../context/session-ledger.js\";\nimport type { BeforeEditContext, BootstrapContext } from \"../context/types.js\";\nimport type { ReindexResult } from \"../core/codebuddy.js\";\nimport { loadRuntimeConfig, readConfigFile } from \"../core/config-file.js\";\nimport { captureAfterTurn } from \"../memory-extract/engine.js\";\nimport { extractUserRules } from \"../memory-extract/rules.js\";\nimport { redactSensitive } from \"../memory-extract/sensitive.js\";\nimport type { AfterTurnResult } from \"../memory-extract/types.js\";\nimport { estimateTokens } from \"../savings/tokens.js\";\nimport { recordTrace, type TraceEvent } from \"../tracing/log.js\";\nimport { hookRoot } from \"./root.js\";\nimport { openHookSemantics } from \"./semantic.js\";\nimport { HookStagingStore } from \"./staging.js\";\n\n/**\n * The runtime side of `codebuddy hooks`. Each function is the deterministic\n * action a Claude Code hook triggers, independent of whether the model chose to\n * call anything:\n * - context: recall — compact project context, injected at prompt submit.\n * - stage: record the files an edit tool just changed.\n * - capture: at turn end, capture durable memory from the real change set.\n *\n * All are best-effort: a hook must never break the user's turn, so callers wrap\n * these and always exit 0.\n */\n\n/** The subset of a Claude Code hook payload CodeBuddy reads. */\nexport type HookInput = {\n session_id?: string;\n transcript_path?: string;\n cwd?: string;\n hook_event_name?: string;\n prompt?: string;\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n /** SessionStart only: startup | resume | clear | compact. */\n source?: string;\n /** Turn end, for hosts without a transcript file (OpenCode): the last assistant text. */\n last_assistant_message?: string;\n /** Turn end, for hosts without a transcript file: shell commands run this turn. */\n shell_commands?: Array<{ command: string; exit_code: number | null }>;\n /**\n * The host injects the block into this turn only and never keeps it in the\n * conversation (Hermes pre_llm_call), so nothing may be skipped as already sent.\n */\n ephemeral_context?: boolean;\n};\n\nconst CONTEXT_BLOCK_MAX_CHARS = 1800;\n/** Facts recalled per prompt: few and precise beats many and noisy. */\nconst PROMPT_FACTS = 3;\n\n/**\n * A block built later than this is dropped instead of emitted. Every bridge\n * kills the hook later (OpenCode and Hermes after 20s from spawn, Claude Code\n * after 60s), so a block is marked delivered only when it was written with\n * seconds to spare, never just before a host timeout throws the output away.\n */\nexport const CONTEXT_HOOK_BUDGET_MS = 15_000;\n\nasync function resolveNamespace(repositoryRoot: string): Promise<string> {\n if (process.env.CODEBUDDY_NAMESPACE) return process.env.CODEBUDDY_NAMESPACE;\n const file = await readConfigFile(repositoryRoot);\n return file.namespace ?? basename(repositoryRoot);\n}\n\n/**\n * UserPromptSubmit → a compact, injectable context block (recall).\n *\n * `emit` writes the block to the client. Capsules are recorded as delivered\n * only after it resolves, so a failed write leaves the session ledger untouched.\n */\nexport async function runContextHook(\n input: HookInput,\n emit?: (block: string) => Promise<void>,\n budgetMs = CONTEXT_HOOK_BUDGET_MS,\n): Promise<string> {\n const started = Date.now();\n const repositoryRoot = hookRoot(input.cwd);\n const namespace = await resolveNamespace(repositoryRoot);\n\n const bootstrap = await buildBootstrapContext({ repositoryRoot, namespace });\n let beforeEdit: BeforeEditContext | null = null;\n const semantics = input.prompt ? await openHookSemantics(repositoryRoot) : null;\n try {\n beforeEdit = await buildBeforeEditContext({\n repositoryRoot,\n namespace,\n useGit: true,\n ...(input.prompt ? { task: input.prompt } : {}),\n ...(semantics?.semanticRanker ? { semanticRanker: semantics.semanticRanker } : {}),\n ...(semantics?.reranker ? { reranker: semantics.reranker } : {}),\n });\n } catch {\n beforeEdit = null;\n } finally {\n await semantics?.close();\n }\n const ledger = new SessionCapsuleLedger(repositoryRoot);\n const sessionId = input.session_id ?? \"default\";\n // Earlier blocks are gone from the model's view. No host event says when\n // MCP results are compacted away either, so the whole session starts over.\n if (input.ephemeral_context) await ledger.reset(sessionId);\n const { text, emitted } = await renderContextBlock(\n bootstrap,\n beforeEdit,\n ledger,\n sessionId,\n input.session_id !== undefined,\n );\n // Too late: the host may already have given up on this hook. Nothing is\n // marked, so the next prompt delivers the block.\n const late = Date.now() - started >= budgetMs;\n await recordTrace(\n repositoryRoot,\n recallTrace(input, beforeEdit, emitted, late ? \"\" : text, started, late),\n );\n if (late) return \"\";\n if (text.trim()) await emit?.(text);\n await ledger.markSent(sessionId, emitted);\n return text;\n}\n\n/** What one prompt recalled, for `codebuddy dashboard` (prompt redacted and cut to 120 chars). */\nfunction recallTrace(\n input: HookInput,\n beforeEdit: BeforeEditContext | null,\n emitted: ContextCapsule[],\n text: string,\n started: number,\n late: boolean,\n): Omit<TraceEvent, \"ts\"> {\n const shown = new Set(\n emitted.filter((c) => c.key.startsWith(\"fact:\")).map((c) => c.key.slice(5)),\n );\n const facts = (beforeEdit?.facts ?? []).filter((fact) => shown.has(fact.id));\n const prompt = redactSensitive(input.prompt ?? \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n return {\n kind: \"recall\",\n name: \"context\",\n ms: Date.now() - started,\n ok: !late,\n tokensIn: estimateTokens(input.prompt ?? \"\"),\n tokensOut: estimateTokens(text),\n ...(input.session_id ? { session: input.session_id } : {}),\n detail: {\n prompt: prompt.length > 120 ? `${prompt.slice(0, 119)}…` : prompt,\n facts: facts.map((fact) => fact.summary.slice(0, 100)),\n dense: facts.filter((fact) => fact.reason.includes(\"semantic\")).length,\n lexical: facts.filter((fact) => /task term|target path/.test(fact.reason)).length,\n files: (beforeEdit?.targetPaths ?? []).slice(0, 3),\n sections: emitted.length,\n ...(late ? { dropped: \"built after the hook budget\" } : {}),\n },\n };\n}\n\n/** PostToolUse(edit) → stage the changed paths for capture. */\nexport async function runStageHook(input: HookInput): Promise<string[]> {\n const repositoryRoot = hookRoot(input.cwd);\n const paths = extractEditedPaths(input.tool_input)\n .map((path) => toRepoRelative(repositoryRoot, path))\n .filter((path): path is string => path !== null);\n await new HookStagingStore(repositoryRoot).add(input.session_id ?? \"default\", paths);\n return paths;\n}\n\nexport type CaptureHookResult = {\n changedFiles: string[];\n result: AfterTurnResult | null;\n};\n\n/** BYOK memory extraction options (empty when the layer or its memory feature is off). */\nexport async function llmMemoryOptions(\n repositoryRoot: string,\n): Promise<Awaited<ReturnType<typeof import(\"../llm/memory.js\").llmCaptureOptions>>> {\n try {\n return await (await import(\"../llm/memory.js\")).llmCaptureOptions(repositoryRoot);\n } catch {\n return {};\n }\n}\n\n/** A turn with no edits still leaves a handoff when the assistant reported at least this much. */\nconst INVESTIGATION_MIN_CHARS = 200;\n/** A handoff must point at code: a file path with an extension, or a backticked identifier. */\nconst NAMES_CODE =\n /[\\w.-]+\\/[\\w./-]*\\.\\w{1,5}\\b|\\b[\\w-]+\\.(?:ts|tsx|js|jsx|mjs|py|go|rs|java|rb|php|cs|c|cpp|h|swift|kt)\\b|`[^`\\s]+`/;\n\n/**\n * Stop → capture durable memory from the staged change set + transcript. A\n * turn without edits is still captured when the user stated or withdrew a\n * rule, or when the assistant reported findings (an investigation handoff).\n */\nexport async function runCaptureHook(input: HookInput): Promise<CaptureHookResult> {\n const captureStarted = Date.now();\n const repositoryRoot = hookRoot(input.cwd);\n const staging = new HookStagingStore(repositoryRoot);\n const sessionId = input.session_id ?? \"default\";\n // null: another capture holds this session's lock and handles the turn.\n const claimed = await staging.claim(sessionId);\n if (claimed === null) return { changedFiles: [], result: null };\n const changedFiles = claimed;\n try {\n const prompts = input.transcript_path ? await turnUserPrompts(input.transcript_path) : [];\n const { rules, revocations } = extractUserRules(prompts);\n let investigation = false;\n if (changedFiles.length === 0) {\n const assistant = input.transcript_path\n ? await lastAssistantMessage(input.transcript_path)\n : (input.last_assistant_message?.trim() ?? \"\");\n investigation = assistant.length >= INVESTIGATION_MIN_CHARS && NAMES_CODE.test(assistant);\n if (!investigation && rules.length === 0 && revocations.length === 0) {\n await staging.acknowledge(sessionId);\n return { changedFiles, result: null };\n }\n }\n const namespace = await resolveNamespace(repositoryRoot);\n const summary = await deriveSummary(\n input.transcript_path,\n changedFiles,\n input.last_assistant_message,\n );\n const verification = input.transcript_path\n ? await turnVerification(input.transcript_path)\n : verificationLines(\n (input.shell_commands ?? []).map(({ command, exit_code }) => ({\n command,\n ok: typeof exit_code === \"number\" ? exit_code === 0 : undefined,\n })),\n );\n const result = await captureAfterTurn(\n {\n summary,\n changedFiles,\n namespace,\n sessionId,\n ...(verification.length > 0 ? { verification } : {}),\n ...(rules.length > 0 ? { userRules: rules } : {}),\n ...(revocations.length > 0 ? { revokedRules: revocations } : {}),\n ...(investigation ? { investigation } : {}),\n // Without edits, only the user's own rules and a handoff are kept: an\n // explanation is not evidence of a decision or an incident.\n ...(changedFiles.length === 0 ? { extract: false } : {}),\n },\n {\n repositoryRoot,\n ...(changedFiles.length > 0 ? await llmMemoryOptions(repositoryRoot) : {}),\n },\n );\n await staging.acknowledge(sessionId);\n await recordTrace(repositoryRoot, {\n kind: \"capture\",\n name: \"capture\",\n ms: Date.now() - captureStarted,\n ok: true,\n session: sessionId,\n detail: {\n changedFiles: changedFiles.length,\n saved: result.saved.length,\n queued: result.queuedForReview.length,\n ignored: result.ignored.length,\n },\n });\n return { changedFiles, result };\n } catch (error) {\n await staging.rollback(sessionId);\n throw error;\n }\n}\n\n/** Long enough for the first run to download the model (~90 MB) on a slow link. */\nconst SYNC_BUDGET_MS = 5 * 60_000;\n\nexport type SyncHookResult = { reindex: ReindexResult; drained: boolean } | null;\n\n/**\n * Background, after capture: Markdown (the source of truth) → PostgreSQL\n * (reindex) → local embeddings for every new or re-spaced row, so the next\n * prompt's dense recall already sees this turn's memory (and the first run\n * downloads the local model). null when no database is configured.\n */\nexport async function runSyncHook(\n repositoryRoot: string,\n options: { respace?: boolean } = {},\n): Promise<SyncHookResult> {\n const config = await loadRuntimeConfig(repositoryRoot, { requireDatabase: false });\n if (!config.postgresUrl) return null;\n // One sync per project at a time: a burst of captured turns would otherwise\n // start one process (a DB pool and a loaded model) per turn. A sync that\n // finds the lock held leaves a marker; the holder runs once more for it.\n const lock = join(repositoryRoot, \".codebuddy\", \"cache\", \"sync.lock\");\n const dirty = join(repositoryRoot, \".codebuddy\", \"cache\", \"sync.dirty\");\n await mkdir(dirname(lock), { recursive: true });\n if (!(await takeLock(lock))) {\n await writeFile(dirty, \"\").catch(() => undefined);\n return null;\n }\n const { createRuntime } = await import(\"../core/operations.js\");\n const runtime = await createRuntime(config, { repositoryRoot }).catch(async (error) => {\n await rm(lock, { recursive: true, force: true });\n throw error;\n });\n try {\n let result: NonNullable<SyncHookResult>;\n let round = 0;\n do {\n await rm(dirty, { force: true });\n const started = Date.now();\n const reindex = await runtime.memory.reindexMemory(options.respace ? {} : { respace: false });\n const drained = await pTimeout(runtime.memory.getWorker().drain(), {\n milliseconds: SYNC_BUDGET_MS,\n }).then(\n () => true,\n () => false,\n );\n await recordTrace(repositoryRoot, {\n kind: \"sync\",\n name: \"sync\",\n ms: Date.now() - started,\n ok: drained,\n detail: {\n imported: reindex.facts.imported,\n updated: reindex.facts.updated,\n reembedding: reindex.reembedding ?? 0,\n failures: reindex.failures.length,\n },\n });\n result = { reindex, drained };\n round += 1;\n } while (\n round < 3 &&\n (await stat(dirty).then(\n () => true,\n () => false,\n ))\n );\n return result;\n } finally {\n await runtime.close();\n await rm(lock, { recursive: true, force: true });\n }\n}\n\n/** A sync longer than this crashed or hung; its lock may be taken over. */\nconst SYNC_LOCK_STALE_MS = SYNC_BUDGET_MS + 60_000;\n\nasync function takeLock(path: string): Promise<boolean> {\n try {\n await mkdir(path);\n return true;\n } catch {\n const age = await stat(path).then(\n (info) => Date.now() - info.mtimeMs,\n () => 0,\n );\n if (age < SYNC_LOCK_STALE_MS) return false;\n await rm(path, { recursive: true, force: true });\n return mkdir(path).then(\n () => true,\n () => false,\n );\n }\n}\n\n/** SessionStart(compact|clear) → resend all context on the next prompt. */\nexport async function runResetHook(input: HookInput): Promise<void> {\n const repositoryRoot = hookRoot(input.cwd);\n await new SessionCapsuleLedger(repositoryRoot).reset(input.session_id ?? \"default\");\n}\n\n// ── helpers ─────────────────────────────────────────────────────────\n\n/**\n * Pull edited paths out of a tool input: Claude Edit/Write (`file_path`),\n * MultiEdit (`edits[]`), OpenCode edit/write (`filePath`) and apply_patch/patch\n * (`patchText` file headers, including move targets), Hermes write_file and\n * patch replace mode (`path`) and patch mode (V4A headers in `patch`).\n */\nexport function extractEditedPaths(toolInput: Record<string, unknown> | undefined): string[] {\n if (!toolInput) return [];\n const paths: string[] = [];\n const push = (value: unknown) => {\n if (typeof value === \"string\" && value.trim()) paths.push(value);\n };\n push(toolInput.file_path);\n push(toolInput.filePath);\n push(toolInput.path);\n for (const patch of [toolInput.patchText, toolInput.patch]) {\n if (typeof patch !== \"string\") continue;\n for (const match of patch.matchAll(\n /^\\*\\*\\*\\s+(?:(?:Add|Update|Delete)\\s+File|Move\\s+to):\\s*(.+)$/gm,\n )) {\n push(match[1]?.trim());\n }\n }\n if (Array.isArray(toolInput.edits)) {\n for (const edit of toolInput.edits) {\n if (edit && typeof edit === \"object\") push((edit as Record<string, unknown>).file_path);\n }\n }\n return [...new Set(paths)];\n}\n\nfunction toRepoRelative(repositoryRoot: string, path: string): string | null {\n const absolute = isAbsolute(path) ? resolve(path) : resolve(repositoryRoot, path);\n const rel = relative(repositoryRoot, absolute);\n if (rel === \"\" || rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) return null;\n return rel.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\n/**\n * Build a capture summary from the turn transcript (the last assistant message)\n * plus the change set. If the transcript can't be read, fall back to a plain\n * file list — which the conservative extractor will simply not turn into durable\n * facts, exactly the safe outcome.\n */\nexport async function deriveSummary(\n transcriptPath: string | undefined,\n changedFiles: string[],\n /** Used when there is no transcript (OpenCode passes the last assistant text). */\n lastAssistantText?: string,\n): Promise<string> {\n const fileList = changedFiles.length > 0 ? `Changed files: ${changedFiles.join(\", \")}.` : \"\";\n const assistantText = transcriptPath\n ? await lastAssistantMessage(transcriptPath)\n : (lastAssistantText?.trim().slice(0, 2000) ?? \"\");\n return [assistantText, fileList].filter(Boolean).join(\"\\n\\n\");\n}\n\n/**\n * A shell segment counts as verification when a known runner invokes a\n * test/lint/typecheck/build step (`rm -rf build` does not count).\n */\nconst VERIFICATION_SEGMENT =\n /^\\s*(?:\\w+=\\S*\\s+)*(?:npm|pnpm|yarn|bun|npx|cargo|go|make|mvn|gradle|\\.\\/gradlew|tsc|vitest|jest|pytest|python3? -m pytest|ruff|mypy|eslint|biome)\\b.*\\b(?:test|tests|lint|typecheck|tsc|build|check|vet|clippy|vitest|jest|pytest|ruff|mypy|eslint|biome)\\b/;\n\nfunction isVerificationCommand(command: string): boolean {\n return command.split(/&&|\\|\\||;/).some((segment) => VERIFICATION_SEGMENT.test(segment));\n}\n\n/**\n * Verification evidence for the current turn: test/lint/typecheck/build shell\n * commands run since the user's last prompt, with pass/fail from the tool\n * result. Only commands and outcomes are kept, never their output.\n */\nexport async function turnVerification(transcriptPath: string): Promise<string[]> {\n let raw: string;\n try {\n raw = await readFile(transcriptPath, \"utf8\");\n } catch {\n return [];\n }\n let commands = new Map<string, string>();\n const outcomes = new Map<string, boolean>();\n for (const line of raw.split(\"\\n\")) {\n let entry: Record<string, unknown>;\n try {\n entry = JSON.parse(line) as Record<string, unknown>;\n } catch {\n continue;\n }\n const message = (entry.message ?? {}) as Record<string, unknown>;\n const content = message.content;\n if (message.role === \"user\") {\n // A real prompt (not just tool results) starts a new turn.\n const isPrompt =\n typeof content === \"string\" ||\n (Array.isArray(content) && content.some((block) => block?.type === \"text\"));\n if (isPrompt) {\n commands = new Map();\n outcomes.clear();\n }\n for (const block of Array.isArray(content) ? content : []) {\n if (block?.type === \"tool_result\" && typeof block.tool_use_id === \"string\") {\n outcomes.set(block.tool_use_id, block.is_error !== true);\n }\n }\n continue;\n }\n for (const block of Array.isArray(content) ? content : []) {\n const command = block?.input?.command;\n if (block?.type !== \"tool_use\" || block.name !== \"Bash\" || typeof command !== \"string\") {\n continue;\n }\n if (isVerificationCommand(command)) commands.set(block.id, command);\n }\n }\n return verificationLines(\n [...commands].map(([id, command]) => ({ command, ok: outcomes.get(id) })),\n );\n}\n\n/** Format verification runs (non-checks dropped); `ok` undefined = no result. */\nexport function verificationLines(\n runs: Array<{ command: string; ok: boolean | undefined }>,\n): string[] {\n const lines = runs\n .filter((run) => isVerificationCommand(run.command))\n .map(({ command, ok }) => {\n const label = ok === undefined ? \"no result\" : ok ? \"passed\" : \"failed\";\n return `${command.replace(/\\s+/g, \" \").trim().slice(0, 120)}: ${label}`;\n });\n // Keep the latest runs; a re-run after a fix is the one that matters.\n return lines.slice(-10);\n}\n\n/** Prompts longer than this are pasted material, not instructions to remember. */\nconst MAX_RULE_PROMPT_CHARS = 1500;\n/** Harness-inserted markup (reminders, slash-command echoes) inside user content. */\nconst TAGGED_BLOCK = /<([a-z][\\w-]*)[^>]*>[\\s\\S]*?<\\/\\1>/gi;\n\n/**\n * The user's own prompt text for the current turn (since the last assistant\n * reply): tool results, harness-inserted meta messages (skill bodies, command\n * output) and tagged blocks are excluded, so only what the user typed can\n * become a rule.\n */\nexport async function turnUserPrompts(transcriptPath: string): Promise<string[]> {\n let raw: string;\n try {\n raw = await readFile(transcriptPath, \"utf8\");\n } catch {\n return [];\n }\n let prompts: string[] = [];\n let answered = false;\n for (const line of raw.split(\"\\n\")) {\n let entry: Record<string, unknown>;\n try {\n entry = JSON.parse(line) as Record<string, unknown>;\n } catch {\n continue;\n }\n const message = (entry.message ?? {}) as Record<string, unknown>;\n if (message.role === \"assistant\") {\n answered = true;\n continue;\n }\n if (message.role !== \"user\" || entry.isMeta === true) continue;\n const text = extractText(message.content).replace(TAGGED_BLOCK, \" \").trim();\n if (!text) continue;\n if (answered) {\n prompts = [];\n answered = false;\n }\n if (text.length <= MAX_RULE_PROMPT_CHARS) prompts.push(text);\n }\n return prompts;\n}\n\nexport async function lastAssistantMessage(transcriptPath: string): Promise<string> {\n try {\n const raw = await readFile(transcriptPath, \"utf8\");\n let latest = \"\";\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const entry = JSON.parse(trimmed) as Record<string, unknown>;\n const message = (entry.message ?? entry) as Record<string, unknown>;\n const role = message.role ?? entry.type;\n if (role !== \"assistant\") continue;\n const text = extractText(message.content);\n if (text) latest = text;\n } catch {\n // Skip malformed lines; transcripts are best-effort input.\n }\n }\n return latest.slice(0, 2000);\n } catch {\n return \"\";\n }\n}\n\nfunction extractText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((block) =>\n block && typeof block === \"object\" && (block as Record<string, unknown>).type === \"text\"\n ? String((block as Record<string, unknown>).text ?? \"\")\n : \"\",\n )\n .join(\" \")\n .trim();\n}\n\n/** Below this a risk score (0–100) is one routine signal, e.g. a few commits. */\nconst RISK_LINE_MIN_SCORE = 50;\n\n/** A rendered line; lower `priority` is packed first. */\ntype BlockItem = { priority: number; text: string; capsule?: ContextCapsule };\n\n/** Capsule text is bounded so one huge subject can never become undeliverable. */\nfunction bound(text: string, max = 300): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\n/**\n * Pack whole lines into the block by priority (current-task risk, relevant\n * facts, then broad bootstrap evidence) and return only the capsules whose\n * full text made it in. Lines are never cut; omitted capsules stay unseen.\n */\nexport async function renderContextBlock(\n bootstrap: BootstrapContext,\n beforeEdit: BeforeEditContext | null,\n ledger: SessionCapsuleLedger,\n sessionId: string,\n announceSession = false,\n): Promise<{ text: string; emitted: ContextCapsule[] }> {\n const capsules: Array<{ priority: number; capsule: ContextCapsule }> = [\n // Sent once per session (and again after a reset): MCP context calls that\n // pass it as `sessionId` share this ledger, so compaction resets both paths.\n ...(announceSession\n ? [\n {\n priority: 1,\n capsule: {\n key: \"session\",\n text: `session: ${sessionId} (pass as sessionId to CodeBuddy tools)`,\n },\n },\n ]\n : []),\n { priority: 4, capsule: { key: \"project\", text: `project: ${bootstrap.project.namespace}` } },\n {\n priority: 4,\n capsule: {\n key: \"plan\",\n text: `plan: ${bootstrap.plan ? `${bootstrap.plan.title} (${bootstrap.plan.status})` : \"none\"}`,\n },\n },\n { priority: 4, capsule: { key: \"plan-policy\", text: `plan policy: ${bootstrap.policy}` } },\n ];\n // Only rules that match this prompt's target files; the full rule list is\n // the same on every prompt and rarely relevant.\n const policyRules = beforeEdit?.policyRules ?? [];\n if (policyRules.length > 0) {\n capsules.push({\n priority: 4,\n capsule: {\n key: \"policies\",\n text: `policies: ${policyRules.map((r) => `${r.id}(${r.weight})`).join(\", \")}`,\n },\n });\n }\n for (const incident of bootstrap.incidents) {\n capsules.push({\n priority: 5,\n capsule: {\n key: `incident:${incident.id}`,\n text: `incident: ${bound(incident.subject)} [${incident.severity}]`,\n },\n });\n }\n for (const rule of bootstrap.rules ?? []) {\n const procedure = rule.subject === \"procedure\";\n capsules.push({\n priority: 2,\n capsule: {\n key: `${procedure ? \"procedure\" : \"rule\"}:${rule.id}`,\n text: bound(`${procedure ? \"verify\" : \"rule\"}: ${rule.summary}`),\n },\n });\n }\n // With a prompt, memory is what the prompt retrieved (hybrid-ranked; none\n // = abstain), never the most recent facts; those are only for a bare start.\n const ranked = Boolean(beforeEdit?.task);\n const facts = ranked ? (beforeEdit?.facts ?? []) : bootstrap.facts;\n for (const fact of facts) {\n capsules.push({\n priority: ranked ? 2 : 6,\n capsule: { key: `fact:${fact.id}`, text: bound(`fact: ${fact.summary}`) },\n });\n }\n for (const handoff of bootstrap.handoffs) {\n const drift = [\n handoff.changedSince.length > 0 ? `${handoff.changedSince.length} file(s) changed since` : \"\",\n handoff.missing.length > 0 ? `${handoff.missing.length} missing` : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n capsules.push({\n priority: 7,\n capsule: {\n key: `handoff:${handoff.id}`,\n text: `prior work (${handoff.ageDays}d ago${drift ? `; ${drift}` : \"\"}): ${handoff.summary\n .replace(/\\s+/g, \" \")\n .slice(0, 160)}`,\n },\n });\n }\n if (beforeEdit?.testCommand) {\n capsules.push({\n priority: 3,\n capsule: { key: \"test-command\", text: `test command: ${beforeEdit.testCommand}` },\n });\n }\n capsules.push({\n priority: 8,\n capsule: {\n key: \"architecture\",\n text: `architecture: ${bootstrap.architecture.moduleCount} modules, ${bootstrap.architecture.edgeCount} edges`,\n },\n });\n\n const seen = await ledger.seen(\n sessionId,\n capsules.map((entry) => entry.capsule),\n );\n const items: BlockItem[] = [\n { priority: 0, text: \"## CodeBuddy project context (auto-recalled)\" },\n ];\n const unchanged: ContextCapsule[] = [];\n // Facts already in the conversation do not use up this prompt's fact slots.\n let newFacts = 0;\n for (const { priority, capsule } of capsules) {\n if (seen.has(capsule.key)) unchanged.push(capsule);\n else if (ranked && capsule.key.startsWith(\"fact:\") && ++newFacts > PROMPT_FACTS) continue;\n else items.push({ priority, text: capsule.text, capsule });\n }\n if (unchanged.length > 0) {\n const avoided = unchanged.reduce((sum, capsule) => sum + estimateTokens(capsule.text), 0);\n items.push({\n priority: 10,\n text: `unchanged since earlier in this session (not resent, ~${avoided} tokens): ${describeKeys(unchanged.map((c) => c.key))}`,\n });\n }\n\n if (beforeEdit && beforeEdit.targetPaths.length > 0) {\n // Only git-derived targets are edits in progress; task/plan/explicit paths are not.\n const targetLabel = beforeEdit.pathSource === \"git\" ? \"current changes\" : \"task files\";\n const tests = (beforeEdit.tests ?? []).map((entry) => entry.test);\n items.push({\n priority: 3,\n text: bound(\n `${targetLabel}: ${beforeEdit.targetPaths.slice(0, 8).join(\", \")}` +\n (tests.length > 0 ? `; tests: ${tests.join(\", \")}` : \"\"),\n 500,\n ),\n });\n // Risk for the listed files only (task discovery also assesses unrelated\n // git changes), and only when the score means something.\n const targets = new Set(beforeEdit.targetPaths);\n const risks = beforeEdit.risks.items.filter(\n (item) => targets.has(item.path) && item.score >= RISK_LINE_MIN_SCORE,\n );\n if (risks.length > 0) {\n items.push({\n priority: 1,\n text: bound(\n `risk: ${risks\n .slice(0, 3)\n .map((item) => `${item.path}=${item.score}`)\n .join(\", \")}`,\n 500,\n ),\n });\n }\n }\n\n // Greedy by priority; a line that does not fit is skipped whole, a smaller one may still fit.\n const chosen = new Set<BlockItem>();\n let used = -1; // joining \"\\n\" is only paid between lines\n const byPriority = items\n .map((item, index) => ({ item, index }))\n .sort((a, b) => a.item.priority - b.item.priority || a.index - b.index);\n for (const { item } of byPriority) {\n const cost = item.text.length + 1;\n if (used + cost > CONTEXT_BLOCK_MAX_CHARS) continue;\n used += cost;\n chosen.add(item);\n }\n const packed = items.filter((item) => chosen.has(item));\n return {\n text: packed.map((item) => item.text).join(\"\\n\"),\n emitted: packed.flatMap((item) => (item.capsule ? [item.capsule] : [])),\n };\n}\n\n/** \"project, plan, 3 fact, 1 incident\" — readable names instead of opaque hashes. */\nfunction describeKeys(keys: string[]): string {\n const counts = new Map<string, number>();\n for (const key of keys) {\n const kind = key.includes(\":\") ? key.slice(0, key.indexOf(\":\")) : key;\n counts.set(kind, (counts.get(kind) ?? 0) + 1);\n }\n return [...counts]\n .map(([kind, count]) => (count > 1 || kinds.has(kind) ? `${count} ${kind}` : kind))\n .join(\", \");\n}\n\nconst kinds = new Set([\"fact\", \"incident\", \"handoff\", \"rule\", \"procedure\"]);\n","import { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { loadPlanPolicy } from \"../core/config-file.js\";\nimport {\n type FactFile,\n type IncidentFactFile,\n MemoryFileStore,\n} from \"../core/memory-file-store.js\";\nimport { isEligibleMemory } from \"../core/memory-lifecycle.js\";\nimport { lexicalTerms, termOverlap } from \"../core/memory-search.js\";\nimport { PlanFileStore, type PlanSpec } from \"../core/plan-file-store.js\";\nimport { PlanLifecycle } from \"../core/plan-lifecycle.js\";\nimport { loadFreshIndex } from \"../indexer/engine.js\";\nimport { extractSymbolTable, type SymbolSpan, supportsSymbols } from \"../indexer/symbols.js\";\nimport type { ArchitectureMap } from \"../map/types.js\";\nimport type { RetrievalHit } from \"../retrieval/zvec.js\";\nimport { assessRisk, resolveRiskPaths } from \"../risk/service.js\";\nimport { matchesPolicyGlob, type PolicyRule, readPolicyFile } from \"../risk/signals/policy.js\";\nimport { estimateTokens } from \"../savings/tokens.js\";\nimport { type HandoffSummary, WorklogStore } from \"../worklog/store.js\";\nimport { enforceContextBudget } from \"./budget.js\";\nimport {\n countTerms,\n discoverTaskPaths,\n identifierTokens,\n loadProjectArchitectureMap,\n namedSegments,\n readBoundedSource,\n TASK_PATH_LIMIT,\n taskTerms,\n} from \"./discovery.js\";\nimport { detectTestCommand, findCoveringTest } from \"./tests.js\";\nimport type {\n ArchitectureSummary,\n BeforeEditContext,\n BootstrapContext,\n ContextSpan,\n DiffHunk,\n FileSymbols,\n IncidentSummary,\n ModuleNeighbours,\n PathSource,\n PlanSummary,\n PolicyRuleSummary,\n RelevantFactSummary,\n TokenStats,\n} from \"./types.js\";\n\n/**\n * Bounds. These keep both tool outputs compact regardless of repository size —\n * a bootstrap or before-edit payload should orient the agent, not dump the\n * whole project. Tune here rather than at each call site.\n */\nconst LIMITS = {\n bootstrapIncidents: 5,\n beforeEditIncidents: 8,\n policyRules: 5,\n hotspots: 5,\n neighbourPaths: 10,\n neighbourEdges: 10,\n incidentSummaryChars: 140,\n symbolFiles: TASK_PATH_LIMIT,\n symbolsPerFile: 12,\n spanFiles: 3,\n excerptLines: 6,\n excerptCharsPerSpan: 400,\n excerptChars: 1_200,\n relevantFacts: 5,\n} as const;\n\nconst DEFAULT_TOKEN_BUDGET = 4_000;\nconst MAX_DIFF_FILES = 8;\nconst MAX_DIFF_CHARS_PER_FILE = 2_400;\nconst execFileAsync = promisify(execFile);\n\nexport type BootstrapInput = {\n repositoryRoot?: string;\n namespace: string;\n tokenBudget?: number;\n};\n\nexport type BeforeEditInput = {\n repositoryRoot?: string;\n namespace: string;\n task?: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n tokenBudget?: number;\n semanticRanker?: SemanticRelevanceRanker;\n /** Optional (`rerank.provider`): orders the fused facts, never admits one. */\n reranker?: ContextReranker;\n evidence?: \"overview\" | \"source\";\n};\n\n/** Cross-encoder scores for (task, document) pairs, in input order (higher = more relevant). */\nexport type ContextReranker = (task: string, documents: string[]) => Promise<number[]>;\n\n/** Dense evidence: cosine per fact id, only for facts at or above the model's floor. */\nexport type SemanticRelevanceRanker = (\n task: string,\n candidates: Array<{ id: string; text: string }>,\n) => Promise<Record<string, number>>;\n\n/**\n * Assemble compact project awareness for the start of a turn: identity, the\n * active plan and policy, top policy rules, incident hotspots, and a\n * lightweight architecture summary. No edit target is required.\n */\nexport async function buildBootstrapContext(input: BootstrapInput): Promise<BootstrapContext> {\n const repositoryRoot = resolve(input.repositoryRoot ?? process.cwd());\n const namespace = input.namespace;\n\n const planStore = new PlanFileStore(repositoryRoot);\n const memoryStore = new MemoryFileStore(repositoryRoot);\n const freshPromise = loadFreshIndex(repositoryRoot);\n const manifestPromise = freshPromise.then((fresh) => fresh.manifest);\n const mapPromise = loadProjectArchitectureMap(repositoryRoot, manifestPromise);\n\n const [activePlan, policy, policyFile, incidents, facts, fresh, map, handoffs] =\n await Promise.all([\n new PlanLifecycle(planStore).current(namespace),\n loadPlanPolicy(repositoryRoot),\n readPolicyFile(join(repositoryRoot, \".codebuddy\", \"policies.yaml\")),\n memoryStore.listIncidentFacts({ namespace }),\n memoryStore.listFacts(),\n freshPromise,\n mapPromise,\n recallHandoffs(repositoryRoot, { namespace }),\n ]);\n\n const explain: string[] = [fresh.explain];\n const plan = summarizePlan(activePlan);\n explain.push(plan ? `plan: active plan ${plan.id} (${plan.status})` : \"plan: no active plan\");\n explain.push(`policy: plan policy is \"${policy}\"`);\n\n const policyRules = summarizePolicyRules(policyFile.rules);\n if (policyRules.length > 0) explain.push(`policyRules: ${policyRules.length} rule(s) by weight`);\n\n const incidentSummaries = sortIncidents(incidents)\n .slice(0, LIMITS.bootstrapIncidents)\n .map(summarizeIncident);\n if (incidentSummaries.length > 0) {\n explain.push(`incidents: ${incidentSummaries.length} unresolved incident hotspot(s)`);\n }\n\n const architecture = summarizeArchitecture(map);\n explain.push(\n `architecture: ${architecture.moduleCount} module(s), ${architecture.edgeCount} edge(s)` +\n (map.source ? ` (${map.source})` : \"\"),\n );\n\n const rules = selectRules(facts, namespace);\n if (rules.length > 0) {\n const procedures = rules.filter((rule) => rule.subject === \"procedure\").length;\n explain.push(`rules: ${rules.length - procedures} rule(s), ${procedures} procedure(s)`);\n }\n const bootstrapFacts = await rankRelevantFacts(\n facts.filter((fact) => !STANDING_PREDICATES.has(fact.predicate)),\n namespace,\n \"\",\n [],\n );\n explainHandoffs(explain, handoffs);\n const assembled = {\n project: { namespace, root: repositoryRoot },\n plan,\n policy,\n policyRules,\n incidents: incidentSummaries,\n facts: bootstrapFacts,\n rules,\n handoffs,\n architecture,\n explain,\n };\n const tokens = buildTokenStats(assembled, input.tokenBudget);\n return enforceContextBudget({ ...assembled, tokens });\n}\n\n/**\n * Assemble the most relevant context before an edit: resolve the target files\n * (explicit paths, a plan, or git), then attach the relevant plan, policy\n * rules, incident memory for those files, an evidence-backed risk assessment,\n * and the import neighbours of each target.\n */\nexport async function buildBeforeEditContext(input: BeforeEditInput): Promise<BeforeEditContext> {\n const repositoryRoot = resolve(input.repositoryRoot ?? process.cwd());\n const namespace = input.namespace;\n\n const hasExplicitTargets = (input.paths?.length ?? 0) > 0 || input.planId !== undefined;\n // Validate the index against current source before any indexed symbol,\n // summary or import is trusted (issue #34).\n const fresh = await loadFreshIndex(repositoryRoot);\n const manifest = fresh.manifest;\n const resolvedPaths = await resolveRiskPaths({\n repositoryRoot,\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(hasExplicitTargets\n ? { useGit: false }\n : input.useGit !== undefined\n ? { useGit: input.useGit }\n : {}),\n });\n const mapPromise = loadProjectArchitectureMap(repositoryRoot, manifest);\n const discovery =\n !hasExplicitTargets && input.task\n ? await discoverTaskPaths(repositoryRoot, input.task, manifest, mapPromise)\n : { paths: [], hits: [], explain: [] };\n const taskPaths = discovery.paths;\n const targetPaths = hasExplicitTargets\n ? resolvedPaths\n : taskPaths.length > 0\n ? taskPaths\n : resolvedPaths;\n const discoveredFromTask = taskPaths.length > 0;\n const pathSource = classifyPathSource(input, targetPaths.length, discoveredFromTask);\n\n const planStore = new PlanFileStore(repositoryRoot);\n const memoryStore = new MemoryFileStore(repositoryRoot);\n\n const [referencedPlan, policy, policyFile, incidents, facts, risks, map, diffs, handoffs] =\n await Promise.all([\n resolveRelevantPlan(planStore, namespace, input.planId),\n loadPlanPolicy(repositoryRoot),\n readPolicyFile(join(repositoryRoot, \".codebuddy\", \"policies.yaml\")),\n memoryStore.findIncidentFactsForPaths({ namespace, paths: targetPaths }),\n memoryStore.listFacts(),\n assessRisk({\n repositoryRoot,\n namespace,\n ...(targetPaths.length > 0 ? { paths: targetPaths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n useGit: !hasExplicitTargets && input.useGit !== false,\n }),\n mapPromise,\n input.useGit === false\n ? Promise.resolve([] as DiffHunk[])\n : readGitDiffs(repositoryRoot, targetPaths),\n recallHandoffs(repositoryRoot, {\n namespace,\n paths: targetPaths,\n ...(input.task !== undefined ? { task: input.task } : {}),\n }),\n ]);\n\n const explain: string[] = [];\n explain.push(`paths: ${targetPaths.length} target(s) resolved from ${pathSource}`);\n explain.push(fresh.explain);\n if (discoveredFromTask && resolvedPaths.length > 0) {\n explain.push(\n `git: ${resolvedPaths.length} observed changed path(s) assessed separately from task targets`,\n );\n }\n explain.push(...discovery.explain);\n\n const plan = summarizePlan(referencedPlan);\n if (plan) explain.push(`plan: ${plan.id} (${plan.status})`);\n\n const policyRules = summarizeMatchingPolicyRules(policyFile.rules, targetPaths);\n if (policyRules.length > 0) {\n explain.push(`policyRules: ${policyRules.length} rule(s) match target paths`);\n }\n\n const incidentSummaries = sortIncidents(incidents)\n .slice(0, LIMITS.beforeEditIncidents)\n .map(summarizeIncident);\n if (incidentSummaries.length > 0) {\n explain.push(`incidents: ${incidentSummaries.length} incident(s) touch target paths`);\n }\n\n if (risks.items.length > 0) explain.push(`risks: ${risks.items.length} scored path(s)`);\n\n const neighbours = computeNeighbours(map, targetPaths);\n if (neighbours.length > 0)\n explain.push(\n `neighbours: import graph for ${neighbours.length} file(s)` +\n (map.source ? ` (${map.source})` : \"\"),\n );\n\n const symbols = await computeTargetSymbols(\n repositoryRoot,\n targetPaths,\n input.task ?? \"\",\n discovery.hits,\n \"symbols\" in discovery ? (discovery.symbols ?? {}) : {},\n input.evidence ?? \"overview\",\n );\n if (symbols.length > 0) {\n const spans = symbols.reduce((total, file) => total + (file.spans?.length ?? 0), 0);\n explain.push(\n `symbols: signatures for ${symbols.length} target file(s) (in place of full source)` +\n (spans > 0 ? `; ${spans} task-ranked span(s) read from current source` : \"\"),\n );\n }\n\n const relevantFacts = await rankRelevantFacts(\n facts.filter((fact) => !STANDING_PREDICATES.has(fact.predicate)),\n namespace,\n input.task ?? \"\",\n targetPaths,\n input.semanticRanker,\n input.reranker,\n );\n if (relevantFacts.length > 0) {\n const semantic = relevantFacts.filter((fact) => fact.reason.includes(\"semantic\")).length;\n explain.push(\n `facts: ${relevantFacts.length} durable fact(s) by hybrid rank fusion` +\n (input.semanticRanker\n ? ` (${semantic} with dense evidence${relevantFacts[0]?.reason.endsWith(\"reranked\") ? \", reranked\" : \"\"})`\n : \" (lexical only; no semantic fact ranker configured)\"),\n );\n }\n explainHandoffs(explain, handoffs);\n\n const indexed = new Set(Object.keys(manifest.entries));\n const tests = targetPaths.flatMap((path) => {\n const test = findCoveringTest(path, indexed);\n return test ? [{ path, test }] : [];\n });\n const testCommand = targetPaths.length > 0 ? await detectTestCommand(repositoryRoot) : null;\n if (tests.length > 0 || testCommand) {\n explain.push(\n `tests: ${tests.length} covering test(s) by naming convention; command ${testCommand ?? \"unknown\"}`,\n );\n }\n\n const assembled = {\n project: { namespace, root: repositoryRoot },\n task: input.task ?? null,\n targetPaths,\n pathSource,\n plan,\n policy,\n policyRules,\n incidents: incidentSummaries,\n facts: relevantFacts,\n handoffs,\n risks,\n neighbours,\n symbols,\n tests,\n testCommand,\n diffs,\n explain,\n };\n const tokens = buildTokenStats(assembled, input.tokenBudget);\n return enforceContextBudget({ ...assembled, tokens });\n}\n\n// ── helpers ─────────────────────────────────────────────────────────\n\n/** Prior worklog handoffs. A broken worklog must never break context assembly. */\nasync function recallHandoffs(\n repositoryRoot: string,\n input: Parameters<WorklogStore[\"recall\"]>[0],\n): Promise<HandoffSummary[]> {\n try {\n return await new WorklogStore(repositoryRoot).recall(input);\n } catch {\n return [];\n }\n}\n\nfunction explainHandoffs(explain: string[], handoffs: HandoffSummary[]): void {\n if (handoffs.length === 0) return;\n const stale = handoffs.filter((h) => h.changedSince.length > 0 || h.missing.length > 0).length;\n explain.push(\n `handoffs: ${handoffs.length} prior worklog entr${handoffs.length === 1 ? \"y\" : \"ies\"}` +\n (stale > 0 ? ` (${stale} with files changed or missing since — verify before relying)` : \"\"),\n );\n}\n\nfunction summarizePlan(plan: PlanSpec | null): PlanSummary {\n if (!plan) return null;\n return {\n id: plan.id,\n title: plan.title,\n status: plan.status,\n brief: plan.brief,\n filesToTouch: plan.filesToTouch.map((file) => file.path),\n risks: plan.risks,\n };\n}\n\n/**\n * Prefer an explicitly referenced plan; fall back to the namespace's active\n * plan so before-edit context stays useful even when the caller passes only\n * paths.\n */\nasync function resolveRelevantPlan(\n store: PlanFileStore,\n namespace: string,\n planId?: string,\n): Promise<PlanSpec | null> {\n if (planId) {\n try {\n return await store.readPlan(planId);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n }\n return new PlanLifecycle(store).current(namespace);\n}\n\nfunction sortIncidents(incidents: IncidentFactFile[]): IncidentFactFile[] {\n const severity = { critical: 4, high: 3, medium: 2, low: 1 };\n return [...incidents].sort(\n (a, b) =>\n Number(a.resolvedBy !== null) - Number(b.resolvedBy !== null) ||\n severity[b.severity] - severity[a.severity],\n );\n}\n\nfunction summarizeIncident(fact: IncidentFactFile): IncidentSummary {\n return {\n id: fact.id,\n severity: fact.severity,\n subject: fact.subject,\n summary: truncate(fact.content || fact.object || fact.subject, LIMITS.incidentSummaryChars),\n paths: fact.paths,\n resolved: fact.resolvedBy !== null,\n createdAt: fact.createdAt,\n };\n}\n\nfunction summarizePolicyRules(rules: PolicyRule[]): PolicyRuleSummary[] {\n return [...rules]\n .sort((left, right) => right.weight - left.weight)\n .slice(0, LIMITS.policyRules)\n .map((rule) => ({\n id: rule.id,\n pattern: rule.pattern,\n message: rule.message ?? rule.reason ?? `Policy rule ${rule.id}.`,\n weight: rule.weight,\n }));\n}\n\nfunction summarizeMatchingPolicyRules(rules: PolicyRule[], paths: string[]): PolicyRuleSummary[] {\n const matching = rules.filter((rule) =>\n paths.some((path) => matchesPolicyGlob(path, rule.pattern)),\n );\n return summarizePolicyRules(matching);\n}\n\nfunction summarizeArchitecture(map: ArchitectureMap): ArchitectureSummary {\n const inbound = new Map<string, number>();\n const outbound = new Map<string, number>();\n for (const edge of map.edges) {\n outbound.set(edge.from, (outbound.get(edge.from) ?? 0) + 1);\n inbound.set(edge.to, (inbound.get(edge.to) ?? 0) + 1);\n }\n\n const hotspots = map.modules\n .map((module) => ({\n path: module.path,\n inbound: inbound.get(module.path) ?? 0,\n outbound: outbound.get(module.path) ?? 0,\n }))\n .filter((entry) => entry.inbound + entry.outbound > 0)\n .sort((left, right) => {\n const degree = right.inbound + right.outbound - (left.inbound + left.outbound);\n if (degree !== 0) return degree;\n return left.path.localeCompare(right.path);\n })\n .slice(0, LIMITS.hotspots);\n\n return { moduleCount: map.modules.length, edgeCount: map.edges.length, hotspots };\n}\n\nfunction computeNeighbours(map: ArchitectureMap, paths: string[]): ModuleNeighbours[] {\n const result: ModuleNeighbours[] = [];\n for (const path of paths.slice(0, LIMITS.neighbourPaths)) {\n // Dedupe BEFORE slicing: duplicate edges from a many-to-many import would\n // otherwise crowd unique neighbours out of the bounded payload.\n const dependsOn = [\n ...new Set(map.edges.filter((edge) => edge.from === path).map((edge) => edge.to)),\n ].slice(0, LIMITS.neighbourEdges);\n const dependedOnBy = [\n ...new Set(map.edges.filter((edge) => edge.to === path).map((edge) => edge.from)),\n ].slice(0, LIMITS.neighbourEdges);\n if (dependsOn.length === 0 && dependedOnBy.length === 0) continue;\n const usesSymbols: Record<string, string[]> = {};\n for (const dependency of dependsOn) {\n const symbols = map.edges.find(\n (edge) => edge.from === path && edge.to === dependency,\n )?.symbols;\n if (symbols?.length) usesSymbols[dependency] = symbols;\n }\n result.push({\n path,\n dependsOn,\n dependedOnBy,\n ...(Object.keys(usesSymbols).length > 0 ? { usesSymbols } : {}),\n });\n }\n return result;\n}\n\n/**\n * Read the target files' public API as compact signatures (Roadmap N.3), so the\n * agent can see what each file offers without the tool sending its full source.\n * The whole bounded symbol table is ranked by the task *before* it is limited,\n * so a relevant thirteenth declaration still wins (issue #35); declarations\n * overlapping a semantic hit are preferred. The best match comes back as a span\n * read from current source, with a short excerpt drawn from one global budget.\n * Bounded and best-effort: unreadable files are skipped.\n */\nasync function computeTargetSymbols(\n repositoryRoot: string,\n targetPaths: string[],\n task: string,\n hits: RetrievalHit[],\n /** Symbols the BYOK rerank named per file; they outrank term matches. */\n picked: Record<string, string[]> = {},\n evidence: \"overview\" | \"source\" = \"overview\",\n): Promise<FileSymbols[]> {\n const terms = taskTerms(task);\n const tokens = identifierTokens(task);\n const result: FileSymbols[] = [];\n let excerptBudget: number = evidence === \"source\" ? 5400 : LIMITS.excerptChars;\n let spanned = 0;\n for (const path of targetPaths.slice(0, LIMITS.symbolFiles)) {\n const source = await readBoundedSource(repositoryRoot, path);\n if (source === null) continue;\n const lines = source.split(/\\r?\\n/);\n // zg's index may be stale: only trust hit ranges that still fit the file.\n const fileHits = hits.filter((hit) => hit.path === path && hit.endLine <= lines.length);\n const table = supportsSymbols(path) ? extractSymbolTable(source) : [];\n // Each semantic hit credits only the narrowest declaration containing it,\n // so a method beats its enclosing class.\n const credited = new Map<SymbolSpan, RetrievalHit>();\n for (const hit of fileHits) {\n const owner = table\n .filter((symbol) => hit.startLine <= symbol.endLine && hit.endLine >= symbol.startLine)\n .sort(\n (left, right) => left.endLine - left.startLine - (right.endLine - right.startLine),\n )[0];\n if (owner && !credited.has(owner)) credited.set(owner, hit);\n }\n const ranked = table\n .map((symbol) => {\n const hit = credited.get(symbol);\n // A class body repeats its methods' words; let the narrower method win.\n const body =\n symbol.kind === \"class\"\n ? \"\"\n : lines.slice(symbol.startLine - 1, symbol.endLine).join(\" \");\n const score =\n (picked[path]?.includes(symbol.name) ? 1_000 : 0) +\n 100 * namedSegments(symbol.name, tokens) +\n (hit ? 10 : 0) +\n 3 * countTerms(lines[symbol.startLine - 1] ?? \"\", terms) +\n countTerms(body, terms);\n return { symbol, hit, score };\n })\n .sort(\n (left, right) => right.score - left.score || left.symbol.startLine - right.symbol.startLine,\n );\n // Methods only earn a signature line when the task points at them.\n const signatures = ranked\n .filter(({ symbol, score }) => symbol.kind !== \"method\" || score > 0)\n .slice(0, LIMITS.symbolsPerFile)\n .map(({ symbol }) => symbol.signature);\n // One grounded span per file: the best task match, else the top semantic\n // hit (unsupported languages, or no declaration matched). Only the first\n // few files get one, so the extra tokens stay bounded.\n const best = ranked[0]?.score ? ranked[0] : undefined;\n const hit = best ? best.hit : fileHits[0];\n const range = best?.symbol ?? hit;\n const spans: ContextSpan[] = [];\n if (range && spanned < LIMITS.spanFiles) {\n const span: ContextSpan = {\n ...(best ? { name: best.symbol.name } : {}),\n startLine: range.startLine,\n endLine: range.endLine,\n ...(hit\n ? { source: hit.source, rank: hit.rank, freshness: \"current-source\" }\n : { source: \"lexical\", freshness: \"current-source\" }),\n };\n if (excerptBudget > 0) {\n const headShown = best !== undefined && headInSignature(lines, best.symbol);\n span.excerpt = sourceExcerpt(\n lines,\n span,\n terms,\n hit?.startLine,\n hit?.endLine,\n excerptBudget,\n headShown,\n evidence,\n );\n excerptBudget -= span.excerpt.text.length;\n }\n spans.push(span);\n spanned++;\n }\n if (signatures.length > 0 || spans.length > 0) {\n result.push({ path, signatures, ...(spans.length > 0 ? { spans } : {}) });\n }\n }\n return result;\n}\n\n/**\n * A few lines of current source around the best task-term line (or the semantic\n * hit), so behavior and comments a signature can't show are still grounded.\n */\nfunction sourceExcerpt(\n lines: string[],\n span: ContextSpan,\n terms: string[],\n anchorLine: number | undefined,\n anchorEndLine: number | undefined,\n budget: number,\n headShown = false,\n evidence: \"overview\" | \"source\" = \"overview\",\n): NonNullable<ContextSpan[\"excerpt\"]> {\n let anchor = Math.max(span.startLine, anchorLine ?? span.startLine);\n let best = 0;\n if (anchorLine === undefined) {\n for (let line = span.startLine; line <= span.endLine; line++) {\n const score = countTerms(lines[line - 1] ?? \"\", terms);\n if (score > best) {\n best = score;\n anchor = line;\n }\n }\n }\n const detailed = evidence === \"source\";\n const windowStart =\n detailed && span.endLine - span.startLine < 40\n ? span.startLine\n : Math.max(span.startLine, anchor - 1);\n const endLine = Math.min(\n span.endLine,\n windowStart + (detailed ? 40 : LIMITS.excerptLines) - 1,\n detailed || anchorEndLine === undefined ? span.endLine : anchorEndLine + 1,\n );\n // The declaration line is already a listed signature; don't send it twice.\n const startLine =\n headShown && windowStart === span.startLine && endLine > windowStart\n ? windowStart + 1\n : windowStart;\n const raw = lines.slice(startLine - 1, endLine).join(\"\\n\");\n const text = raw.slice(0, Math.min(budget, detailed ? 1800 : LIMITS.excerptCharsPerSpan));\n return {\n startLine,\n endLine: startLine + text.split(\"\\n\").length - 1,\n text,\n truncated: windowStart > span.startLine || endLine < span.endLine || text.length < raw.length,\n };\n}\n\n/** True when the declaration line adds nothing beyond its (untruncated) signature. */\nfunction headInSignature(lines: string[], symbol: SymbolSpan): boolean {\n const head =\n symbol.kind === \"method\"\n ? symbol.signature.slice(symbol.signature.indexOf(\": \") + 2)\n : symbol.signature;\n const line = (lines[symbol.startLine - 1] ?? \"\").trim();\n return (\n !head.endsWith(\"…\") && line.startsWith(head) && /^[\\s{=>(]*$/.test(line.slice(head.length))\n );\n}\n\n/**\n * Read the current staged and unstaged hunks for target paths. The result is\n * bounded per file so a large change cannot crowd out plan and risk context.\n */\nasync function readGitDiffs(repositoryRoot: string, paths: string[]): Promise<DiffHunk[]> {\n if (paths.length === 0) return [];\n const sections: string[] = [];\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"diff\", \"HEAD\", \"--no-ext-diff\", \"--unified=3\", \"--\", ...paths],\n { cwd: repositoryRoot, maxBuffer: 2_000_000 },\n );\n sections.push(stdout);\n } catch {\n // Repositories without a first commit cannot use `git diff HEAD`. Their\n // staged and unstaged tracked changes are still useful independently.\n for (const args of [\n [\"diff\", \"--cached\", \"--no-ext-diff\", \"--unified=3\", \"--\", ...paths],\n [\"diff\", \"--no-ext-diff\", \"--unified=3\", \"--\", ...paths],\n ]) {\n try {\n const { stdout } = await execFileAsync(\"git\", args, {\n cwd: repositoryRoot,\n maxBuffer: 2_000_000,\n });\n sections.push(stdout);\n } catch {\n // Fall through to untracked-file handling.\n }\n }\n }\n\n const parsed = parseGitDiff(sections.join(\"\\n\"));\n const known = new Set(parsed.map((diff) => diff.path));\n const untracked = await listUntrackedPaths(repositoryRoot, paths);\n for (const path of untracked) {\n if (known.has(path)) continue;\n const patch = await buildUntrackedPatch(repositoryRoot, path);\n if (patch) parsed.push(patch);\n }\n return parsed.slice(0, MAX_DIFF_FILES);\n}\n\nfunction parseGitDiff(diff: string): DiffHunk[] {\n return diff\n .split(/(?=^diff --git )/m)\n .filter((section) => section.startsWith(\"diff --git \"))\n .flatMap((section) => {\n const header = section.match(/^diff --git a\\/(.+?) b\\/(.+?)\\n/m);\n if (!header?.[2]) return [];\n const rawPatch = section.trim();\n const patch = rawPatch.slice(0, MAX_DIFF_CHARS_PER_FILE).trim();\n return patch\n ? [\n {\n path: header[2],\n patch,\n ...(patch.length < rawPatch.length ? { truncated: true } : {}),\n },\n ]\n : [];\n });\n}\n\nasync function listUntrackedPaths(repositoryRoot: string, paths: string[]): Promise<string[]> {\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"ls-files\", \"--others\", \"--exclude-standard\", \"--\", ...paths],\n { cwd: repositoryRoot, maxBuffer: 1_000_000 },\n );\n return stdout\n .split(/\\r?\\n/)\n .map((path) => path.trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n\nasync function buildUntrackedPatch(repositoryRoot: string, path: string): Promise<DiffHunk | null> {\n try {\n const content = await readFile(join(repositoryRoot, path), \"utf8\");\n if (content.includes(\"\\0\")) return null;\n const lines = content.split(/\\r?\\n/);\n const body = lines.map((line) => `+${line}`).join(\"\\n\");\n const rawPatch = [\n `diff --git a/${path} b/${path}`,\n \"new file mode 100644\",\n \"--- /dev/null\",\n `+++ b/${path}`,\n `@@ -0,0 +1,${lines.length} @@`,\n body,\n ].join(\"\\n\");\n const patch = rawPatch.slice(0, MAX_DIFF_CHARS_PER_FILE).trim();\n return {\n path,\n patch,\n ...(patch.length < rawPatch.length ? { truncated: true } : {}),\n };\n } catch {\n return null;\n }\n}\n\n/** Facts delivered as standing guidance, not ranked against the task. */\nconst STANDING_PREDICATES = new Set([\"rule\", \"procedure\"]);\nconst STANDING_LIMITS = { rule: 5, procedure: 3, chars: 200 } as const;\n\n/** Live user rules (newest 5) then procedures (newest 3), regardless of task overlap. */\n/**\n * Standing rules and procedures reach every session, and fact files can arrive\n * through git, so neither may be steered by a planted file: one dated in the\n * future (to sort first forever) is not shown, and a procedure is shown only\n * when it is one plain command (no chaining, pipes, substitution or\n * redirection), since agents tend to run what `verify:` says.\n */\nconst SHELL_CONTROL = /[;&|`$<>\\n\\r]/;\n\nfunction selectRules(facts: FactFile[], namespace: string): RelevantFactSummary[] {\n // A day of clock-skew slack; anything later was not captured here.\n const latest = new Date(Date.now() + 86_400_000).toISOString();\n const newest = (predicate: \"rule\" | \"procedure\") =>\n facts\n .filter((fact) => fact.predicate === predicate && isEligibleMemory(fact, { namespace }))\n .filter((fact) => fact.createdAt <= latest)\n .filter((fact) => predicate !== \"procedure\" || !SHELL_CONTROL.test(fact.object))\n .sort((left, right) => right.createdAt.localeCompare(left.createdAt))\n .slice(0, STANDING_LIMITS[predicate]);\n return [...newest(\"rule\"), ...newest(\"procedure\")].map((fact) => ({\n id: fact.id,\n subject: fact.predicate,\n summary: truncate(fact.object, STANDING_LIMITS.chars),\n paths: fact.paths,\n confidence: fact.confidence,\n relevance: 0,\n reason:\n fact.predicate === \"rule\" ? \"standing user rule\" : \"verification that passed repeatedly\",\n createdAt: fact.createdAt,\n createdByAgent: fact.createdByAgent,\n }));\n}\n\n/** Reciprocal rank fusion constant (Cormack et al. 2009): damps the head so no one list dominates. */\nconst RRF_K = 60;\n/** At most this many fused facts go to the optional cross-encoder. */\nconst RERANK_POOL = 20;\n\n/**\n * Hybrid fact retrieval:\n * 1. gate: lexical (task words + target paths) or dense evidence (pgvector\n * cosine at or above the model's calibrated floor) admits a fact;\n * 2. rank: reciprocal rank fusion of the lexical and dense rankings,\n * score(f) = Σ_lists 1 / (RRF_K + rank_list(f));\n * 3. rerank: optional cross-encoder that orders the fused pool. Off by\n * default: on `npm run eval:semantic` none of eight local rerankers\n * beat the dense order. Its scores never admit a fact.\n * Every model step is optional and fail-soft.\n */\nasync function rankRelevantFacts(\n facts: FactFile[],\n namespace: string,\n task: string,\n targetPaths: string[],\n semanticRanker?: SemanticRelevanceRanker,\n reranker?: ContextReranker,\n): Promise<RelevantFactSummary[]> {\n // Eligibility runs before ranking and duplicate suppression, so only\n // same-namespace, live incidents can suppress a fact with identical text.\n const eligible = facts.filter((fact) => isEligibleMemory(fact, { namespace }));\n const incidentText = new Set(\n eligible\n .filter((fact) => fact.category === \"incident\")\n .map((fact) => normalizeText(fact.content || fact.object)),\n );\n const candidates = eligible\n .filter((fact) => fact.category !== \"incident\")\n .filter((fact) => !incidentText.has(normalizeText(fact.content || fact.object)))\n .map((fact) => {\n const text = `${fact.subject} ${fact.predicate} ${fact.object} ${fact.content}`;\n const taskScore = relevanceScore(text, task);\n // A path match is strong supporting evidence, but must not overwhelm a\n // clearly different task (for example database work near an auth file).\n const pathScore = fact.paths.some((path) => targetPaths.includes(path)) ? 5 : 0;\n return { fact, text, taskScore, pathScore, lexical: taskScore + pathScore };\n });\n const summarize = (fact: FactFile, relevance: number, reason: string): RelevantFactSummary => ({\n id: fact.id,\n subject: fact.subject,\n summary: truncate(fact.content || fact.object, LIMITS.incidentSummaryChars),\n paths: fact.paths,\n confidence: fact.confidence,\n relevance,\n reason,\n createdAt: fact.createdAt,\n createdByAgent: fact.createdByAgent,\n });\n\n if (!task.trim()) {\n return candidates\n .sort(\n (left, right) =>\n right.fact.confidence - left.fact.confidence ||\n right.fact.createdAt.localeCompare(left.fact.createdAt),\n )\n .slice(0, LIMITS.relevantFacts)\n .map(({ fact }) => summarize(fact, Math.round(fact.confidence * 5), \"recent project fact\"));\n }\n\n let dense: Record<string, number> = {};\n if (semanticRanker) {\n try {\n dense = await semanticRanker(\n task,\n candidates.map(({ fact, text }) => ({ id: fact.id, text })),\n );\n } catch {\n dense = {};\n }\n }\n const cosine = (id: string) => {\n const value = dense[id];\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n };\n const gated = candidates.filter(\n (candidate) => candidate.lexical > 0 || cosine(candidate.fact.id) !== undefined,\n );\n const rankOf = (ordered: Array<(typeof gated)[number]>) =>\n new Map(ordered.map((candidate, index) => [candidate.fact.id, index + 1]));\n const lexicalRank = rankOf(\n gated.filter(({ lexical }) => lexical > 0).sort((a, b) => b.lexical - a.lexical),\n );\n const denseRank = rankOf(\n gated\n .filter(({ fact }) => cosine(fact.id) !== undefined)\n .sort((a, b) => (cosine(b.fact.id) ?? 0) - (cosine(a.fact.id) ?? 0)),\n );\n const rrf = (rank: number | undefined) => (rank === undefined ? 0 : 1 / (RRF_K + rank));\n const fused = gated\n .map((candidate) => ({\n ...candidate,\n score: rrf(lexicalRank.get(candidate.fact.id)) + rrf(denseRank.get(candidate.fact.id)),\n }))\n .sort(\n (left, right) =>\n right.score - left.score ||\n right.fact.confidence - left.fact.confidence ||\n right.fact.createdAt.localeCompare(left.fact.createdAt),\n );\n\n let reranked = false;\n if (reranker && fused.length > 1) {\n const pool = fused.slice(0, RERANK_POOL);\n try {\n const scores = await reranker(\n task,\n pool.map(({ text }) => text),\n );\n if (scores.length === pool.length && scores.every((score) => !Number.isNaN(score))) {\n const scoreOf = new Map(pool.map((candidate, index) => [candidate, scores[index] ?? 0]));\n // Stable: equal scores keep their fused order; the rest of the list follows.\n pool.sort((left, right) => (scoreOf.get(right) ?? 0) - (scoreOf.get(left) ?? 0));\n fused.splice(0, pool.length, ...pool);\n reranked = true;\n }\n } catch {\n // Keep the fused order.\n }\n }\n\n // Diversity: a fact that restates one already selected adds no information\n // and would spend one of the few slots (maximal marginal relevance, lexically).\n const selected: typeof fused = [];\n for (const candidate of fused) {\n if (selected.length >= LIMITS.relevantFacts) break;\n const text = candidate.fact.content || candidate.fact.object;\n if (selected.some((kept) => termOverlap(text, kept.fact.content || kept.fact.object) >= 0.8)) {\n continue;\n }\n selected.push(candidate);\n }\n\n return selected.map(({ fact, taskScore, pathScore, score }) => {\n const evidence = [\n pathScore > 0 ? \"matches a target path\" : \"\",\n taskScore > 0 ? `shares ${taskScore / 3} task term(s)` : \"\",\n cosine(fact.id) !== undefined ? `semantic ${cosine(fact.id)?.toFixed(2)}` : \"\",\n ].filter(Boolean);\n return summarize(\n fact,\n // Fused score scaled to a readable integer (max = 2/61 · 1000 ≈ 33).\n Math.round(score * 1000),\n evidence.join(\"; \") + (reranked ? \"; reranked\" : \"\"),\n );\n });\n}\n\n/** 3 points per distinct task term (stopwords dropped) found as a whole word in `value`. */\nfunction relevanceScore(value: string, task: string): number {\n const terms = lexicalTerms(task).filter((term) => term.length > 2);\n if (terms.length === 0) return 0;\n const haystack = new Set(value.toLowerCase().match(/[\\p{L}\\p{N}_]+/gu) ?? []);\n return terms.filter((term) => haystack.has(term)).length * 3;\n}\n\nfunction normalizeText(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9_./-]+/g, \" \")\n .trim();\n}\n\nfunction classifyPathSource(\n input: BeforeEditInput,\n resolvedCount: number,\n discoveredFromTask: boolean,\n): PathSource {\n if (resolvedCount === 0) return \"none\";\n if (discoveredFromTask) return \"task\";\n if (input.paths && input.paths.length > 0) return \"paths\";\n if (input.planId) return \"plan\";\n return \"git\";\n}\n\n/** Estimate the payload's token footprint against its budget. */\nfunction buildTokenStats(payload: unknown, tokenBudget: number | undefined): TokenStats {\n return {\n budget: tokenBudget ?? DEFAULT_TOKEN_BUDGET,\n returnedEstimate: estimateTokens(payload ?? {}),\n status: \"within_budget\",\n countedSurface: \"compact_json\",\n essentialOmitted: 0,\n };\n}\n\nfunction truncate(value: string, max: number): string {\n const trimmed = value.trim();\n return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max - 1)}…`;\n}\n\nexport { rankTaskPaths, scoreTaskPaths } from \"./discovery.js\";\n","import { mkdir, open, readdir, readFile, rm, stat } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport {\n assertNoSymlinkBetween,\n composeMarkdown,\n parseFrontMatter,\n writeAtomic,\n} from \"./markdown-store-fs.js\";\n\n/**\n * Plans are durable Markdown artifacts under `.codebuddy/plans/`. Git is\n * the version history; PostgreSQL (when present) is a derived index, never\n * the source of truth. This store owns the on-disk representation:\n * schema, round-trip serialization, atomic writes, and the locks that keep\n * concurrent CLI/MCP clients from corrupting a plan or approving two active\n * plans in one namespace.\n */\n\nexport const PLAN_STATUSES = [\"draft\", \"approved\", \"executing\", \"complete\", \"abandoned\"] as const;\nexport type PlanStatus = (typeof PLAN_STATUSES)[number];\n\n/** A plan is \"active\" while approved or executing — at most one per namespace. */\nexport const ACTIVE_PLAN_STATUSES: readonly PlanStatus[] = [\"approved\", \"executing\"];\n\nconst plannedFileSchema = z.object({\n path: z.string().min(1),\n action: z.enum([\"create\", \"edit\", \"delete\"]),\n notes: z.string().default(\"\"),\n});\n\nconst plannedTestSchema = z.object({\n path: z.string().min(1),\n description: z.string().default(\"\"),\n});\n\nconst nullableDateTime = z\n .preprocess(\n (value) => (value instanceof Date ? value.toISOString() : value),\n z.string().datetime().nullable(),\n )\n .nullable();\n\nconst planFrontMatterSchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^pln_[a-z0-9]+$/),\n namespace: z.string().min(1),\n type: z.literal(\"plan\"),\n title: z.string().min(1),\n status: z.enum(PLAN_STATUSES),\n brief: z.string(),\n filesToTouch: z.array(plannedFileSchema).default([]),\n testsToAdd: z.array(plannedTestSchema).default([]),\n outOfScope: z.array(z.string()).default([]),\n risks: z.array(z.string()).default([]),\n createdAt: z.preprocess(\n (value) => (value instanceof Date ? value.toISOString() : value),\n z.string().datetime(),\n ),\n createdByAgent: z.string().nullable(),\n approvedAt: nullableDateTime,\n executingAt: nullableDateTime,\n completedAt: nullableDateTime,\n abandonedAt: nullableDateTime,\n commitSha: z.string().nullable(),\n abandonReason: z.string().nullable(),\n});\n\nexport type PlannedFile = z.infer<typeof plannedFileSchema>;\nexport type PlannedTest = z.infer<typeof plannedTestSchema>;\nexport type PlanFrontMatter = z.infer<typeof planFrontMatterSchema>;\n\n/** A fully materialized plan: front matter + Markdown body + on-disk path. */\nexport type PlanSpec = PlanFrontMatter & {\n body: string;\n path: string;\n};\n\n/** Shape accepted by `writePlan` — path/schemaVersion/type are managed here. */\nexport type PlanWrite = Omit<PlanFrontMatter, \"schemaVersion\" | \"type\"> & {\n body: string;\n};\n\nexport type PlanLockOptions = {\n /** Max time to wait for the lock before failing. */\n timeoutMs?: number;\n /** A lock older than this is considered abandoned and stolen. */\n staleMs?: number;\n /** Poll interval while waiting. */\n pollMs?: number;\n};\n\nexport class PlanLockError extends Error {\n constructor(resource: string) {\n super(\n `Could not acquire lock for ${resource} within the timeout. Another client may be holding it.`,\n );\n this.name = \"PlanLockError\";\n }\n}\n\nexport class PlanValidationError extends Error {\n constructor(path: string, issues: string[]) {\n super(`Invalid plan file ${path}:\\n${issues.map((issue) => ` - ${issue}`).join(\"\\n\")}`);\n this.name = \"PlanValidationError\";\n }\n}\n\nconst DEFAULT_LOCK: Required<PlanLockOptions> = {\n timeoutMs: 5_000,\n staleMs: 30_000,\n pollMs: 50,\n};\n\nexport class PlanFileStore {\n readonly repositoryRoot: string;\n readonly plansDirectory: string;\n readonly locksDirectory: string;\n\n constructor(repositoryRoot = process.cwd()) {\n this.repositoryRoot = resolve(repositoryRoot);\n this.plansDirectory = join(this.repositoryRoot, \".codebuddy\", \"plans\");\n this.locksDirectory = join(this.plansDirectory, \".locks\");\n }\n\n // ── Read / write ────────────────────────────────────────────────────\n\n async writePlan(input: PlanWrite): Promise<string> {\n const path = this.planPath(input.id);\n await this.prepareDirectory(this.plansDirectory);\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n\n const frontMatter = stringifyYaml({\n schemaVersion: 1,\n id: input.id,\n namespace: input.namespace,\n type: \"plan\",\n title: input.title,\n status: input.status,\n brief: input.brief,\n filesToTouch: input.filesToTouch,\n testsToAdd: input.testsToAdd,\n outOfScope: input.outOfScope,\n risks: input.risks,\n createdAt: input.createdAt,\n createdByAgent: input.createdByAgent,\n approvedAt: input.approvedAt,\n executingAt: input.executingAt,\n completedAt: input.completedAt,\n abandonedAt: input.abandonedAt,\n commitSha: input.commitSha,\n abandonReason: input.abandonReason,\n });\n\n await writeAtomic(path, composeMarkdown(frontMatter, input.body));\n return path;\n }\n\n async readPlan(pathOrId: string): Promise<PlanSpec> {\n const path = pathOrId.endsWith(\".md\") ? this.safePath(pathOrId) : this.planPath(pathOrId);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n const result = planFrontMatterSchema.safeParse(parseYaml(parsed.frontMatter));\n if (!result.success) {\n throw new PlanValidationError(path, formatIssues(result.error));\n }\n return { ...result.data, body: parsed.content.trim(), path };\n }\n\n async listPlans(): Promise<PlanSpec[]> {\n try {\n await this.prepareDirectory(this.plansDirectory);\n const entries = await readdir(this.plansDirectory, { withFileTypes: true });\n const plans: PlanSpec[] = [];\n for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {\n // Plans are always written as `<pln_id>.md`. Ignore any other markdown\n // (hand-written notes, READMEs, build plans) so a shared plans dir with\n // non-plan files can't make discovery throw.\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n if (!/^pln_[a-z0-9]+\\.md$/.test(entry.name)) continue;\n plans.push(await this.readPlan(join(this.plansDirectory, entry.name)));\n }\n return plans;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n }\n\n async deletePlan(id: string): Promise<void> {\n await rm(this.planPath(id), { force: true });\n }\n\n /**\n * The single approved-or-executing plan in `namespace`, or null. If the\n * filesystem somehow holds more than one (a hand edit, a crash mid-\n * transition), the earliest-created wins and the situation is the\n * caller's to reconcile.\n */\n async findActivePlan(namespace: string): Promise<PlanSpec | null> {\n const active = (await this.listPlans()).filter(\n (plan) => plan.namespace === namespace && ACTIVE_PLAN_STATUSES.includes(plan.status),\n );\n if (active.length === 0) return null;\n active.sort((left, right) => left.createdAt.localeCompare(right.createdAt));\n return active[0] ?? null;\n }\n\n // ── Locking ─────────────────────────────────────────────────────────\n\n /** Serialize amendments to a single plan. */\n async withPlanLock<T>(id: string, fn: () => Promise<T>, options?: PlanLockOptions): Promise<T> {\n this.assertPlanId(id);\n return this.withLock(`${id}.lock`, id, fn, options);\n }\n\n /**\n * Serialize lifecycle transitions across an entire namespace so two\n * clients cannot both promote a plan to active. Hold this around the\n * read-active-then-write window.\n */\n async withNamespaceLock<T>(\n namespace: string,\n fn: () => Promise<T>,\n options?: PlanLockOptions,\n ): Promise<T> {\n const safeName = namespace.replace(/[^a-zA-Z0-9_.:-]/g, \"-\");\n return this.withLock(`namespace_${safeName}.lock`, `namespace ${namespace}`, fn, options);\n }\n\n private async withLock<T>(\n lockFileName: string,\n resourceLabel: string,\n fn: () => Promise<T>,\n options?: PlanLockOptions,\n ): Promise<T> {\n const config = { ...DEFAULT_LOCK, ...options };\n await this.prepareDirectory(this.locksDirectory);\n const lockPath = join(this.locksDirectory, lockFileName);\n const deadline = Date.now() + config.timeoutMs;\n\n for (;;) {\n try {\n const handle = await open(lockPath, \"wx\", 0o600);\n await handle.writeFile(`${process.pid}\\n${new Date().toISOString()}\\n`, \"utf8\");\n await handle.close();\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n if (await this.tryStealStaleLock(lockPath, config.staleMs)) continue;\n if (Date.now() >= deadline) throw new PlanLockError(resourceLabel);\n await delay(config.pollMs);\n }\n }\n\n try {\n return await fn();\n } finally {\n await releaseOwnedLock(lockPath);\n }\n }\n\n private async tryStealStaleLock(lockPath: string, staleMs: number): Promise<boolean> {\n try {\n const info = await stat(lockPath);\n if (Date.now() - info.mtimeMs > staleMs) {\n await rm(lockPath, { force: true });\n return true;\n }\n } catch (error) {\n // Lock vanished between EEXIST and stat — treat as free, retry.\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return true;\n throw error;\n }\n return false;\n }\n\n // ── Paths ───────────────────────────────────────────────────────────\n\n private planPath(id: string): string {\n this.assertPlanId(id);\n return this.safePath(join(this.plansDirectory, `${id}.md`));\n }\n\n private assertPlanId(id: string): void {\n if (!/^pln_[a-z0-9]+$/.test(id)) {\n throw new Error(`Invalid plan id: ${id}`);\n }\n }\n\n private safePath(path: string): string {\n const absolute = resolve(path);\n const relativePath = relative(this.repositoryRoot, absolute);\n if (relativePath === \"..\" || relativePath.startsWith(`..${sep}`) || relativePath === \"\") {\n throw new Error(`Plan path escapes repository root: ${path}`);\n }\n return absolute;\n }\n\n private async prepareDirectory(directory: string): Promise<void> {\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(directory));\n await mkdir(directory, { recursive: true, mode: 0o700 });\n }\n}\n\nfunction formatIssues(error: z.ZodError): string[] {\n return error.issues.map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return `${path}: ${issue.message}`;\n });\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Delete `lockPath` only when it still belongs to this process. If a holder's\n * work ran past `staleMs`, another client may have stolen and re-created the\n * lock — deleting it unconditionally would release *their* critical section.\n */\nasync function releaseOwnedLock(lockPath: string): Promise<void> {\n try {\n const contents = await readFile(lockPath, \"utf8\");\n const ownerPid = Number.parseInt(contents.split(\"\\n\")[0] ?? \"\", 10);\n if (ownerPid === process.pid) {\n await rm(lockPath, { force: true });\n }\n } catch {\n // Lock already vanished (stolen then released) — nothing to release.\n }\n}\n","import { generateEntityId } from \"./ids.js\";\nimport {\n ACTIVE_PLAN_STATUSES,\n type PlanFileStore,\n type PlannedFile,\n type PlannedTest,\n type PlanSpec,\n type PlanStatus,\n} from \"./plan-file-store.js\";\n\n/**\n * The plan lifecycle service enforces the state machine on top of the\n * file store. The store knows how to read/write/lock; this service knows\n * which transitions are legal and guarantees that at most one plan in a\n * namespace is active at a time. Transitions that change active state run\n * under the namespace lock; amendments run under the per-plan lock.\n */\n\n/** Legal transitions. Terminal states (complete, abandoned) have none. */\nconst TRANSITIONS: Record<PlanStatus, readonly PlanStatus[]> = {\n draft: [\"approved\", \"abandoned\"],\n approved: [\"executing\", \"abandoned\"],\n executing: [\"complete\", \"abandoned\"],\n complete: [],\n abandoned: [],\n};\n\n/** Only these states accept content amendments. */\nconst AMENDABLE: readonly PlanStatus[] = [\"draft\", \"executing\"];\n\nexport class PlanTransitionError extends Error {\n constructor(from: PlanStatus, to: PlanStatus) {\n super(`Illegal plan transition: ${from} → ${to}.`);\n this.name = \"PlanTransitionError\";\n }\n}\n\nexport class PlanNotFoundError extends Error {\n constructor(id: string) {\n super(`Plan ${id} not found.`);\n this.name = \"PlanNotFoundError\";\n }\n}\n\nexport class ActivePlanExistsError extends Error {\n readonly activePlanId: string;\n constructor(namespace: string, activePlanId: string) {\n super(\n `Namespace \"${namespace}\" already has an active plan (${activePlanId}). ` +\n `Complete or abandon it before approving another.`,\n );\n this.name = \"ActivePlanExistsError\";\n this.activePlanId = activePlanId;\n }\n}\n\nexport type CreatePlanInput = {\n namespace: string;\n title: string;\n brief: string;\n body?: string;\n filesToTouch?: PlannedFile[];\n testsToAdd?: PlannedTest[];\n outOfScope?: string[];\n risks?: string[];\n createdByAgent?: string | null;\n now?: string;\n};\n\nexport type AmendPlanPatch = {\n title?: string;\n brief?: string;\n body?: string;\n filesToTouch?: PlannedFile[];\n testsToAdd?: PlannedTest[];\n outOfScope?: string[];\n risks?: string[];\n};\n\nexport type CompleteOptions = { commitSha?: string; notes?: string };\nexport type AbandonOptions = { reason?: string };\n\nconst DEFAULT_BODY = [\n \"# Goal\",\n \"\",\n \"(what this plan achieves)\",\n \"\",\n \"# Approach\",\n \"\",\n \"(ordered steps)\",\n \"\",\n \"# Notes\",\n \"\",\n \"(freeform; ignored by tooling)\",\n].join(\"\\n\");\n\nexport class PlanLifecycle {\n private readonly store: PlanFileStore;\n\n constructor(store: PlanFileStore) {\n this.store = store;\n }\n\n async create(input: CreatePlanInput): Promise<PlanSpec> {\n const id = generateEntityId(\"pln\");\n const now = input.now ?? new Date().toISOString();\n await this.store.writePlan({\n id,\n namespace: input.namespace,\n title: input.title,\n status: \"draft\",\n brief: input.brief,\n filesToTouch: input.filesToTouch ?? [],\n testsToAdd: input.testsToAdd ?? [],\n outOfScope: input.outOfScope ?? [],\n risks: input.risks ?? [],\n createdAt: now,\n createdByAgent: input.createdByAgent ?? null,\n approvedAt: null,\n executingAt: null,\n completedAt: null,\n abandonedAt: null,\n commitSha: null,\n abandonReason: null,\n body: input.body ?? DEFAULT_BODY,\n });\n return this.store.readPlan(id);\n }\n\n async approve(id: string, now = new Date().toISOString()): Promise<PlanSpec> {\n const current = await this.require(id);\n // The active-plan guard and the write must be atomic across the\n // namespace, otherwise two approvals could both observe \"no active plan\".\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"approved\");\n const active = await this.store.findActivePlan(fresh.namespace);\n if (active && active.id !== id) {\n throw new ActivePlanExistsError(fresh.namespace, active.id);\n }\n return this.rewrite(fresh, { status: \"approved\", approvedAt: now });\n });\n }\n\n async start(id: string, now = new Date().toISOString()): Promise<PlanSpec> {\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"executing\");\n return this.rewrite(fresh, { status: \"executing\", executingAt: now });\n });\n }\n\n async complete(\n id: string,\n options: CompleteOptions = {},\n now = new Date().toISOString(),\n ): Promise<PlanSpec> {\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"complete\");\n return this.rewrite(fresh, {\n status: \"complete\",\n completedAt: now,\n ...(options.commitSha !== undefined ? { commitSha: options.commitSha } : {}),\n });\n });\n }\n\n async abandon(\n id: string,\n options: AbandonOptions = {},\n now = new Date().toISOString(),\n ): Promise<PlanSpec> {\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n this.assertTransition(fresh.status, \"abandoned\");\n return this.rewrite(fresh, {\n status: \"abandoned\",\n abandonedAt: now,\n ...(options.reason !== undefined ? { abandonReason: options.reason } : {}),\n });\n });\n }\n\n async amend(id: string, patch: AmendPlanPatch): Promise<PlanSpec> {\n // Amend takes the NAMESPACE lock, like every lifecycle transition. The\n // per-plan lock alone let an amend interleave with e.g. abandon():\n // amend reads `draft` -> abandon writes `abandoned` -> amend writes back\n // its stale full snapshot, resurrecting the plan as `draft`. One shared\n // mutex makes read-check-write atomic across all mutators.\n const current = await this.require(id);\n return this.store.withNamespaceLock(current.namespace, async () => {\n const fresh = await this.require(id);\n if (!AMENDABLE.includes(fresh.status)) {\n throw new Error(\n `Plan ${id} is ${fresh.status}; only draft or executing plans can be amended.`,\n );\n }\n return this.rewrite(fresh, {\n ...(patch.title !== undefined ? { title: patch.title } : {}),\n ...(patch.brief !== undefined ? { brief: patch.brief } : {}),\n ...(patch.filesToTouch !== undefined ? { filesToTouch: patch.filesToTouch } : {}),\n ...(patch.testsToAdd !== undefined ? { testsToAdd: patch.testsToAdd } : {}),\n ...(patch.outOfScope !== undefined ? { outOfScope: patch.outOfScope } : {}),\n ...(patch.risks !== undefined ? { risks: patch.risks } : {}),\n ...(patch.body !== undefined ? { body: patch.body } : {}),\n });\n });\n }\n\n async current(namespace: string): Promise<PlanSpec | null> {\n return this.store.findActivePlan(namespace);\n }\n\n private assertTransition(from: PlanStatus, to: PlanStatus): void {\n if (!TRANSITIONS[from].includes(to)) {\n throw new PlanTransitionError(from, to);\n }\n }\n\n private async require(id: string): Promise<PlanSpec> {\n try {\n return await this.store.readPlan(id);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new PlanNotFoundError(id);\n }\n throw error;\n }\n }\n\n /** Rewrite the plan file with a partial set of changed fields. */\n private async rewrite(plan: PlanSpec, changes: Partial<PlanSpec>): Promise<PlanSpec> {\n const next = { ...plan, ...changes };\n await this.store.writePlan({\n id: next.id,\n namespace: next.namespace,\n title: next.title,\n status: next.status,\n brief: next.brief,\n filesToTouch: next.filesToTouch,\n testsToAdd: next.testsToAdd,\n outOfScope: next.outOfScope,\n risks: next.risks,\n createdAt: next.createdAt,\n createdByAgent: next.createdByAgent,\n approvedAt: next.approvedAt,\n executingAt: next.executingAt,\n completedAt: next.completedAt,\n abandonedAt: next.abandonedAt,\n commitSha: next.commitSha,\n abandonReason: next.abandonReason,\n body: next.body,\n });\n return this.store.readPlan(next.id);\n }\n}\n\nexport { ACTIVE_PLAN_STATUSES };\n","import { spawn } from \"node:child_process\";\nimport { realpath } from \"node:fs/promises\";\nimport { relative, resolve, sep } from \"node:path\";\nimport { MemoryFileStore } from \"../core/memory-file-store.js\";\nimport { PlanFileStore } from \"../core/plan-file-store.js\";\nimport { RiskAssessor } from \"./assessor.js\";\nimport { createChurnSignal } from \"./signals/churn.js\";\nimport { createIncidentSignal } from \"./signals/incident.js\";\nimport { createPolicySignal } from \"./signals/policy.js\";\nimport type { Assessment, Signal } from \"./types.js\";\n\nexport type RiskAssessRequest = {\n repositoryRoot?: string;\n namespace: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n limit?: number;\n signals?: Signal[];\n};\n\nexport async function assessRisk(input: RiskAssessRequest): Promise<Assessment> {\n const repositoryRoot = resolve(input.repositoryRoot ?? process.cwd());\n const paths = await resolveRiskPaths({\n repositoryRoot,\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n });\n if (paths.length === 0) {\n return {\n items: [],\n stats: { pathsConsidered: 0, itemsProduced: 0, signalsRun: 0, perSignal: [] },\n };\n }\n\n const memoryStore = new MemoryFileStore(repositoryRoot);\n const signals = input.signals ?? [\n createIncidentSignal({ store: memoryStore }),\n createPolicySignal({ repositoryRoot }),\n ...(input.useGit === false ? [] : [createChurnSignal({ repositoryRoot })]),\n ];\n\n const assessment = await new RiskAssessor(signals).assess({\n paths,\n repositoryRoot,\n namespace: input.namespace,\n });\n return {\n ...assessment,\n items: input.limit ? assessment.items.slice(0, input.limit) : assessment.items,\n };\n}\n\nexport async function resolveRiskPaths(input: {\n repositoryRoot: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n}): Promise<string[]> {\n const paths = new Set<string>();\n for (const path of input.paths ?? []) {\n if (!path.trim()) continue;\n // Containment guard: tool callers can pass arbitrary path strings, and a\n // `../`-style escape must never flow into file reads downstream\n // (computeTargetSymbols, savings fallbacks, etc.). Kept paths are\n // rewritten to their resolved repo-relative POSIX form.\n const contained = containedRelativePath(input.repositoryRoot, path);\n if (contained) paths.add(contained);\n }\n\n if (input.planId) {\n const plan = await new PlanFileStore(input.repositoryRoot).readPlan(input.planId);\n for (const file of plan.filesToTouch) {\n const contained = containedRelativePath(input.repositoryRoot, file.path);\n if (contained) paths.add(contained);\n }\n }\n\n if (input.useGit !== false && (input.useGit || paths.size === 0)) {\n for (const path of await changedGitPaths(input.repositoryRoot)) {\n const contained = containedRelativePath(input.repositoryRoot, path);\n if (contained) paths.add(contained);\n }\n }\n\n // A path that stays inside the repository by name can still leave it through\n // a symlink (`docs/k -> ~/.ssh`); downstream reads must never follow it out.\n const realRoot = await realpath(input.repositoryRoot).catch(() => resolve(input.repositoryRoot));\n const inside = await Promise.all(\n [...paths].map(async (path) => {\n const real = await realpath(resolve(input.repositoryRoot, path)).catch(() => null);\n // A deleted or not-yet-created file cannot be read; keep it as a target.\n return real === null || real === realRoot || real.startsWith(`${realRoot}${sep}`);\n }),\n );\n const resolved = [...paths].filter((_, index) => inside[index]).sort();\n // Bound the change set so one huge branch cannot blow any payload derived\n // from it. Sorted above, so the cap keeps the lexicographically-first paths.\n return resolved.length > MAX_RESOLVED_PATHS ? resolved.slice(0, MAX_RESOLVED_PATHS) : resolved;\n}\n\n/** Hard cap on resolved target paths per assessment/context call. */\nexport const MAX_RESOLVED_PATHS = 200;\n\n/**\n * Resolve `path` against `root`; return its repo-relative POSIX form when it\n * stays inside the repository, or null when it escapes (or is empty).\n * Rejects NUL bytes and absolute paths pointing outside the root.\n */\nfunction containedRelativePath(root: string, path: string): string | null {\n const trimmed = normalizePath(path);\n if (!trimmed || trimmed.includes(\"\\0\")) return null;\n const absolute = resolve(root, trimmed);\n const relativePath = relative(resolve(root), absolute).split(sep).join(\"/\");\n if (relativePath === \"\" || relativePath === \"..\" || relativePath.startsWith(\"../\")) return null;\n return relativePath;\n}\n\nasync function changedGitPaths(repositoryRoot: string): Promise<string[]> {\n const [tracked, untracked] = await Promise.all([\n runGit(repositoryRoot, [\"diff\", \"--name-only\", \"HEAD\"]),\n runGit(repositoryRoot, [\"ls-files\", \"--others\", \"--exclude-standard\"]),\n ]);\n return (\n [...tracked.stdout.split(\"\\n\"), ...untracked.stdout.split(\"\\n\")]\n .map((path) => path.trim())\n // CodeBuddy's own memory, plans, review queue and caches are not code\n // changes: as risk targets they only add noise and one `git log` each.\n .filter((path) => path && !path.startsWith(\".codebuddy/\"))\n );\n}\n\nfunction runGit(\n cwd: string,\n args: string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolveResult, reject) => {\n const child = spawn(\"git\", args, { cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => resolveResult({ code: code ?? 0, stdout, stderr }));\n });\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n","import type {\n Assessment,\n AssessmentInput,\n Evidence,\n RiskCategory,\n RiskItem,\n Signal,\n SignalContribution,\n SignalStat,\n} from \"./types.js\";\n\nexport type AssessorOptions = {\n /** Items scoring below this are dropped from the result. Default 0. */\n minScore?: number;\n};\n\ntype ContributionWithSignal = {\n signal: Signal;\n contribution: SignalContribution;\n};\n\n/**\n * Runs every enabled signal in parallel and folds their per-path\n * contributions into a single ranked list. Scoring is deterministic: the\n * same inputs and the same cache state always produce the same output, with\n * stable tie-breaking.\n */\nexport class RiskAssessor {\n private readonly signals: Signal[];\n private readonly minScore: number;\n\n constructor(signals: Signal[], options: AssessorOptions = {}) {\n this.signals = signals;\n this.minScore = options.minScore ?? 0;\n }\n\n async assess(input: AssessmentInput): Promise<Assessment> {\n const enabled = this.signals.filter((signal) => signal.enabled);\n\n const settled = await Promise.all(\n enabled.map(async (signal) => ({\n signal,\n contributions: await signal.assess(input),\n })),\n );\n\n // Group contributions by path, remembering which signal produced each.\n const byPath = new Map<string, ContributionWithSignal[]>();\n const perSignal = new Map<string, SignalStat>();\n\n for (const { signal, contributions } of settled) {\n const stat: SignalStat = perSignal.get(signal.id) ?? {\n id: signal.id,\n category: signal.category,\n contributions: 0,\n totalWeight: 0,\n };\n for (const contribution of contributions) {\n // A signal that returns no evidence for a path does not get to vote —\n // the normalization only counts signals that actually have something\n // to say. This keeps a silent signal from diluting a real one.\n if (contribution.evidence.length === 0) continue;\n const list = byPath.get(contribution.path) ?? [];\n list.push({ signal, contribution });\n byPath.set(contribution.path, list);\n stat.contributions += 1;\n stat.totalWeight += contribution.weight;\n }\n perSignal.set(signal.id, stat);\n }\n\n const items: RiskItem[] = [];\n for (const [path, contributions] of byPath) {\n items.push(this.fold(path, contributions));\n }\n\n const ranked = items.filter((item) => item.score >= this.minScore).sort(compareRiskItems);\n\n return {\n items: ranked,\n stats: {\n pathsConsidered: input.paths.length,\n itemsProduced: ranked.length,\n signalsRun: enabled.length,\n perSignal: [...perSignal.values()].sort((a, b) => a.id.localeCompare(b.id)),\n },\n };\n }\n\n /** Fold all contributions for one path into a single RiskItem. */\n private fold(path: string, contributions: ContributionWithSignal[]): RiskItem {\n let weightedSum = 0;\n let coefficientSum = 0;\n let dominant: ContributionWithSignal | null = null;\n const evidence: Evidence[] = [];\n const contributingSignals: string[] = [];\n\n for (const entry of contributions) {\n const coefficient = entry.signal.coefficient;\n weightedSum += entry.contribution.weight * coefficient;\n coefficientSum += coefficient;\n evidence.push(...entry.contribution.evidence);\n contributingSignals.push(entry.signal.id);\n if (!dominant || dominantWeight(entry) > dominantWeight(dominant)) {\n dominant = entry;\n }\n }\n\n // Normalize only over the signals that contributed, so a path is not\n // punished for the signals that stayed silent about it.\n const score = coefficientSum === 0 ? 0 : clip(weightedSum / coefficientSum, 0, 100);\n const category: RiskCategory = dominant?.signal.category ?? \"policy\";\n const reason = dominant?.contribution.reason ?? \"\";\n\n return {\n path,\n score: round2(score),\n category,\n reason,\n contributingSignals: contributingSignals.sort(),\n evidence,\n };\n }\n}\n\nfunction dominantWeight(entry: ContributionWithSignal): number {\n return entry.contribution.weight * entry.signal.coefficient;\n}\n\n/** Deterministic ordering: score desc, then more signals, then path asc. */\nfunction compareRiskItems(a: RiskItem, b: RiskItem): number {\n if (b.score !== a.score) return b.score - a.score;\n if (b.contributingSignals.length !== a.contributingSignals.length) {\n return b.contributingSignals.length - a.contributingSignals.length;\n }\n return a.path.localeCompare(b.path);\n}\n\nfunction clip(value: number, low: number, high: number): number {\n return Math.min(high, Math.max(low, value));\n}\n\nfunction round2(value: number): number {\n return Math.round(value * 100) / 100;\n}\n","import { spawn } from \"node:child_process\";\nimport { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { Signal, SignalContribution } from \"../types.js\";\n\nexport type ChurnSignalOptions = {\n repositoryRoot: string;\n enabled?: boolean;\n coefficient?: number;\n since?: string;\n};\n\ntype CommitRecord = {\n sha: string;\n author: string;\n ts: string;\n message: string;\n};\n\nconst GIT_LOG_CONCURRENCY = 4;\n\nexport function createChurnSignal(options: ChurnSignalOptions): Signal {\n return {\n id: \"git-churn\",\n category: \"churn\",\n enabled: options.enabled ?? true,\n coefficient: options.coefficient ?? 0.7,\n async assess(input) {\n // Churn is only meaningful at the repository root. Check it once per\n // assessment, not once per path: it was half of every git spawn (#45).\n const root = await runGit(options.repositoryRoot, [\"rev-parse\", \"--show-toplevel\"]);\n // git prints the symlink-resolved top level (macOS /var -> /private/var).\n const expected = await realpath(options.repositoryRoot).catch(() =>\n resolve(options.repositoryRoot),\n );\n if (root.code !== 0 || resolve(root.stdout.trim()) !== expected) {\n return [];\n }\n // `git log --follow` takes one path: run a few at a time, kept in path order.\n const since = options.since ?? \"30 days ago\";\n const logs: CommitRecord[][] = [];\n for (let start = 0; start < input.paths.length; start += GIT_LOG_CONCURRENCY) {\n const batch = input.paths.slice(start, start + GIT_LOG_CONCURRENCY);\n logs.push(\n ...(await Promise.all(\n batch.map((path) => gitLogForPath(options.repositoryRoot, path, since)),\n )),\n );\n }\n const contributions: SignalContribution[] = [];\n for (const [index, path] of input.paths.entries()) {\n const commits = logs[index] ?? [];\n if (commits.length === 0) continue;\n const authors = new Set(commits.map((commit) => commit.author));\n const reverts = commits.filter((commit) => /revert|rollback|backout/i.test(commit.message));\n const weight = Math.min(100, commits.length * 8 + authors.size * 12 + reverts.length * 20);\n contributions.push({\n path,\n weight,\n reason: `${path} changed ${commits.length} time${commits.length === 1 ? \"\" : \"s\"} in the recent git history by ${authors.size} author${authors.size === 1 ? \"\" : \"s\"}.`,\n evidence: commits.slice(0, 5).map((commit) => ({\n kind: \"git_commit\" as const,\n sha: commit.sha,\n message: commit.message,\n ts: commit.ts,\n })),\n });\n }\n return contributions;\n },\n };\n}\n\nasync function gitLogForPath(\n repositoryRoot: string,\n path: string,\n since: string,\n): Promise<CommitRecord[]> {\n const result = await runGit(repositoryRoot, [\n \"log\",\n \"--follow\",\n `--since=${since}`,\n \"--format=%H%x1f%an%x1f%cI%x1f%s%x1e\",\n \"--\",\n path,\n ]);\n if (result.code !== 0 || result.stdout.trim().length === 0) return [];\n return result.stdout\n .split(\"\\x1e\")\n .map((record) => record.trim())\n .filter(Boolean)\n .map((record) => {\n const [sha = \"\", author = \"\", ts = \"\", message = \"\"] = record.split(\"\\x1f\");\n return { sha, author, ts, message };\n })\n .filter((record) => record.sha.length > 0);\n}\n\nfunction runGit(\n cwd: string,\n args: string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"git\", args, { cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => resolve({ code: code ?? 0, stdout, stderr }));\n });\n}\n","import type { IncidentSeverity, MemoryFileStore } from \"../../core/memory-file-store.js\";\nimport type { Signal, SignalContribution } from \"../types.js\";\n\nexport type IncidentSignalOptions = {\n store: MemoryFileStore;\n enabled?: boolean;\n coefficient?: number;\n includeResolved?: boolean;\n};\n\n/**\n * Historical incident signal (Proposal 03.2/03.5 foundation). It reads\n * structured incident metadata from Markdown facts and produces one\n * evidence-backed contribution per affected path.\n */\nexport function createIncidentSignal(options: IncidentSignalOptions): Signal {\n return {\n id: \"incident-memory\",\n category: \"incident\",\n enabled: options.enabled ?? true,\n coefficient: options.coefficient ?? 1.2,\n async assess(input) {\n const incidents = await options.store.findIncidentFactsForPaths({\n namespace: input.namespace,\n paths: input.paths,\n includeResolved: options.includeResolved ?? false,\n });\n\n const byPath = new Map<string, SignalContribution>();\n for (const incident of incidents) {\n for (const path of input.paths) {\n if (!incident.paths.map(normalizePath).includes(normalizePath(path))) continue;\n const existing = byPath.get(path);\n const evidence = {\n kind: \"memory_fact\" as const,\n factId: incident.id,\n content: incident.content,\n createdAt: incident.createdAt,\n };\n if (!existing) {\n byPath.set(path, {\n path,\n weight: severityWeight(incident.severity),\n reason: `This file is linked to prior ${incident.severity} incident memory.`,\n evidence: [evidence],\n });\n continue;\n }\n existing.weight = Math.max(existing.weight, severityWeight(incident.severity));\n existing.reason = `This file is linked to ${existing.evidence.length + 1} prior incident memories.`;\n existing.evidence.push(evidence);\n }\n }\n\n return [...byPath.values()];\n },\n };\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction severityWeight(severity: IncidentSeverity): number {\n switch (severity) {\n case \"critical\":\n return 95;\n case \"high\":\n return 80;\n case \"medium\":\n return 55;\n case \"low\":\n return 30;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport type { Signal, SignalContribution } from \"../types.js\";\n\nconst policyRuleSchema = z.object({\n id: z.string().min(1),\n pattern: z.string().min(1),\n message: z.string().min(1).optional(),\n reason: z.string().min(1).optional(),\n weight: z.number().min(0).max(100).default(50),\n});\n\nconst policyFileSchema = z.object({\n rules: z.array(policyRuleSchema).default([]),\n});\n\nexport type PolicyRule = z.infer<typeof policyRuleSchema>;\nexport type PolicyFile = z.infer<typeof policyFileSchema>;\n\nexport type PolicySignalOptions = {\n repositoryRoot: string;\n enabled?: boolean;\n coefficient?: number;\n policyPath?: string;\n};\n\nexport function createPolicySignal(options: PolicySignalOptions): Signal {\n return {\n id: \"policy\",\n category: \"policy\",\n enabled: options.enabled ?? true,\n coefficient: options.coefficient ?? 1,\n async assess(input) {\n const policy = await readPolicyFile(\n options.policyPath ?? join(options.repositoryRoot, \".codebuddy\", \"policies.yaml\"),\n );\n if (policy.rules.length === 0) return [];\n\n const byPath = new Map<string, SignalContribution>();\n for (const path of input.paths) {\n for (const rule of policy.rules) {\n if (!matchesPolicyGlob(path, rule.pattern)) continue;\n const existing = byPath.get(path);\n const evidence = { kind: \"policy_rule\" as const, ruleId: rule.id, pattern: rule.pattern };\n const reason = rule.message ?? rule.reason ?? `Policy rule ${rule.id} matched ${path}.`;\n if (!existing) {\n byPath.set(path, {\n path,\n weight: rule.weight,\n reason,\n evidence: [evidence],\n });\n continue;\n }\n existing.weight = Math.max(existing.weight, rule.weight);\n existing.evidence.push(evidence);\n if (rule.weight >= existing.weight) existing.reason = reason;\n }\n }\n return [...byPath.values()];\n },\n };\n}\n\nexport async function readPolicyFile(path: string): Promise<PolicyFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n return policyFileSchema.parse(parseYaml(raw) ?? {});\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { rules: [] };\n throw error;\n }\n}\n\n/** Match a repo-relative path against a simple `*` / `**` glob pattern. */\nexport function matchesPolicyGlob(path: string, glob: string): boolean {\n const normalizedPath = normalize(path);\n const normalizedGlob = normalize(glob);\n const pattern = normalizedGlob\n .split(\"**\")\n .map((part) => part.split(\"*\").map(escapeRegExp).join(\"[^/]*\"))\n .join(\".*\");\n return new RegExp(`^${pattern}$`).test(normalizedPath);\n}\n\nfunction normalize(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[|\\\\{}()[\\]^$+?.]/g, \"\\\\$&\");\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, readdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport { generateEntityId } from \"../core/ids.js\";\nimport {\n assertNoSymlinkBetween,\n composeMarkdown,\n parseFrontMatter,\n writeAtomic,\n} from \"../core/markdown-store-fs.js\";\nimport { scanSensitive } from \"../memory-extract/sensitive.js\";\n\n/**\n * The worklog is a chronological record of completed turns — what was done,\n * which files, what memory it produced, how it was verified — so a fresh chat\n * can pick up prior work without the transcript. It is a timeline, not project\n * truth: durable facts stay in `.codebuddy/memory/` and the working tree stays\n * authoritative, so every recalled entry carries a freshness check against the\n * current files. Entries are bounded Markdown under `.codebuddy/worklog/`; raw\n * transcripts are never stored and sensitive summaries are redacted.\n */\n\nconst LIMITS = {\n summaryChars: 600,\n files: 50,\n verification: 10,\n verificationChars: 200,\n} as const;\n\nconst REDACTED = \"[REDACTED SENSITIVE CONTENT]\";\n\nconst entrySchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^wlg_[a-z0-9]+$/),\n namespace: z.string().min(1),\n createdAt: z.string(),\n sourceSessionId: z.string().nullable().default(null),\n sourcePlanId: z.string().nullable().default(null),\n commitSha: z.string().nullable().default(null),\n agentId: z.string().nullable().default(null),\n files: z.array(z.string()).default([]),\n verification: z.array(z.string()).default([]),\n savedMemory: z.array(z.string()).default([]),\n queuedForReview: z.array(z.string()).default([]),\n fingerprint: z.string().regex(/^[a-f0-9]{64}$/),\n});\n\nexport type WorklogEntry = z.infer<typeof entrySchema> & { summary: string; path: string };\n\nexport type WorklogRecordInput = {\n namespace: string;\n summary: string;\n files?: string[];\n verification?: string[];\n savedMemory?: string[];\n queuedForReview?: string[];\n sessionId?: string;\n planId?: string;\n commitSha?: string;\n agentId?: string;\n};\n\n/** A worklog entry as recalled into context, with freshness against the working tree. */\nexport type HandoffSummary = {\n id: string;\n createdAt: string;\n ageDays: number;\n summary: string;\n files: string[];\n verification: string[];\n savedMemory: string[];\n /** Recorded files modified after the entry was written. */\n changedSince: string[];\n /** Recorded files that no longer exist. */\n missing: string[];\n reason: string;\n};\n\nexport class WorklogStore {\n readonly repositoryRoot: string;\n readonly directory: string;\n\n constructor(repositoryRoot = process.cwd()) {\n this.repositoryRoot = resolve(repositoryRoot);\n this.directory = join(this.repositoryRoot, \".codebuddy\", \"worklog\");\n }\n\n /**\n * Record one entry for a completed turn. A retry of the same turn (same\n * namespace, session, summary and files) returns the existing id instead of\n * writing a duplicate.\n */\n async record(input: WorklogRecordInput, now = new Date()): Promise<string> {\n const files = [...new Set((input.files ?? []).map(normalizePath))]\n .filter(Boolean)\n .sort()\n .slice(0, LIMITS.files);\n const summary = boundSummary(input.summary, files);\n const verification = (input.verification ?? [])\n .map((line) => line.trim().slice(0, LIMITS.verificationChars))\n .filter((line) => line && !scanSensitive(line).sensitive)\n .slice(0, LIMITS.verification);\n const fingerprint = createHash(\"sha256\")\n .update(\n JSON.stringify({\n namespace: input.namespace.trim().toLowerCase(),\n session: input.sessionId ?? null,\n summary: summary.replace(/\\s+/g, \" \").toLowerCase(),\n files,\n }),\n )\n .digest(\"hex\");\n\n const existing = (await this.list()).find((entry) => entry.fingerprint === fingerprint);\n if (existing) return existing.id;\n\n const id = generateEntityId(\"wlg\", now.getTime());\n const path = this.entryPath(id);\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n const frontMatter = stringifyYaml({\n schemaVersion: 1,\n id,\n namespace: input.namespace,\n createdAt: now.toISOString(),\n sourceSessionId: input.sessionId ?? null,\n sourcePlanId: input.planId ?? null,\n commitSha: input.commitSha ?? null,\n agentId: input.agentId ?? null,\n files,\n verification,\n savedMemory: input.savedMemory ?? [],\n queuedForReview: input.queuedForReview ?? [],\n fingerprint,\n });\n await writeAtomic(path, composeMarkdown(frontMatter, summary));\n return id;\n }\n\n async read(id: string): Promise<WorklogEntry> {\n const path = this.entryPath(id);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n return {\n ...entrySchema.parse(parseYaml(parsed.frontMatter)),\n summary: parsed.content.trim(),\n path,\n };\n }\n\n /** All readable entries, newest first. Corrupt or foreign files are skipped. */\n // ponytail: full directory scan per call; add an index file if worklogs reach thousands of entries.\n async list(namespace?: string): Promise<WorklogEntry[]> {\n let names: string[];\n try {\n await assertNoSymlinkBetween(this.repositoryRoot, this.directory);\n names = await readdir(this.directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n const entries: WorklogEntry[] = [];\n for (const name of names) {\n if (!/^wlg_[a-z0-9]+\\.md$/.test(name)) continue;\n try {\n const entry = await this.read(name.replace(/\\.md$/, \"\"));\n if (namespace === undefined || entry.namespace === namespace) entries.push(entry);\n } catch {\n // Leave corrupt entries on disk for inspection; never fail recall on one.\n }\n }\n return entries.sort(\n (left, right) =>\n right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id),\n );\n }\n\n /**\n * Prior handoffs for a new turn. With target paths or a task, only entries\n * that overlap them are returned (ranked by overlap, then recency); without\n * either, the most recent entries are returned.\n */\n async recall(input: {\n namespace: string;\n paths?: string[];\n task?: string;\n limit?: number;\n now?: Date;\n }): Promise<HandoffSummary[]> {\n const now = input.now ?? new Date();\n const limit = input.limit ?? 3;\n const entries = await this.list(input.namespace);\n const paths = new Set((input.paths ?? []).map(normalizePath));\n const taskWords = words(input.task ?? \"\");\n const targeted = paths.size > 0 || taskWords.size > 0;\n\n const ranked = entries\n .map((entry, recency) => {\n const fileHits = entry.files.filter((file) => paths.has(file));\n const summaryWords = words(entry.summary);\n const wordHits = [...taskWords].filter((word) => summaryWords.has(word));\n const score = fileHits.length * 3 + Math.min(wordHits.length, 5);\n const reason = !targeted\n ? \"recent work\"\n : [\n fileHits.length > 0 ? `touched ${fileHits.slice(0, 3).join(\", \")}` : \"\",\n wordHits.length > 0 ? `task terms: ${wordHits.slice(0, 5).join(\", \")}` : \"\",\n ]\n .filter(Boolean)\n .join(\"; \");\n return { entry, score, recency, reason };\n })\n .filter((item) => !targeted || item.score > 0)\n .sort((left, right) => right.score - left.score || left.recency - right.recency)\n .slice(0, limit);\n\n return Promise.all(\n ranked.map(async ({ entry, reason }) => {\n const freshness = await this.freshness(entry);\n return {\n id: entry.id,\n createdAt: entry.createdAt,\n ageDays: Math.max(\n 0,\n Math.floor((now.getTime() - Date.parse(entry.createdAt)) / 86_400_000),\n ),\n summary: entry.summary.slice(0, 240),\n files: entry.files.slice(0, 8),\n verification: entry.verification.slice(0, 3),\n savedMemory: entry.savedMemory,\n ...freshness,\n reason,\n };\n }),\n );\n }\n\n private async freshness(\n entry: WorklogEntry,\n ): Promise<{ changedSince: string[]; missing: string[] }> {\n const createdAt = Date.parse(entry.createdAt);\n const changedSince: string[] = [];\n const missing: string[] = [];\n for (const file of entry.files) {\n const absolute = resolve(this.repositoryRoot, file);\n const rel = relative(this.repositoryRoot, absolute);\n if (rel.startsWith(`..${sep}`) || rel === \"..\") continue;\n try {\n if ((await stat(absolute)).mtimeMs > createdAt) changedSince.push(file);\n } catch {\n missing.push(file);\n }\n }\n return { changedSince, missing };\n }\n\n private entryPath(id: string): string {\n if (!/^wlg_[a-z0-9]+$/.test(id)) throw new Error(`Invalid worklog id: ${id}`);\n return join(this.directory, `${id}.md`);\n }\n}\n\n/**\n * Keep the human summary, drop the hook's trailing \"Changed files:\" line (files\n * are recorded separately), cap the length, and redact anything sensitive.\n */\nfunction boundSummary(summary: string, files: string[]): string {\n const text = summary\n .replace(/\\n*Changed files: [^\\n]*\\.?\\s*$/, \"\")\n .trim()\n .slice(0, LIMITS.summaryChars);\n if (!text) return files.length > 0 ? `Changed ${files.slice(0, 5).join(\", \")}.` : \"(no summary)\";\n return redactSentences(text);\n}\n\n/**\n * Redact only the sentences (or lines) that scan sensitive, so one pasted key\n * does not erase the whole handoff. If the result still scans sensitive (a\n * credential split across a sentence boundary), redact the whole summary.\n */\nfunction redactSentences(text: string): string {\n if (!scanSensitive(text).sensitive) return text;\n const redacted = text\n .split(/(?<=[.!?])\\s+|\\n+/)\n .map((sentence) => (scanSensitive(sentence).sensitive ? REDACTED : sentence))\n .join(\" \");\n return scanSensitive(redacted).sensitive ? REDACTED : redacted;\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").trim();\n}\n\nfunction words(text: string): Set<string> {\n return new Set(text.toLowerCase().match(/[a-z0-9_]{4,}/g) ?? []);\n}\n","import { estimateTokens } from \"../savings/tokens.js\";\nimport type { TokenStats } from \"./types.js\";\n\nconst WARNING = \"Context incomplete: inspect omitted policies, risks and incidents before editing.\";\n\ntype Payload = Record<string, unknown> & { tokens: TokenStats };\ntype Candidate = { section: string; value: unknown; priority: number; essential: boolean };\n\n/** Budget the complete compact JSON text, including this accounting and delivery metadata. */\nexport function enforceContextBudget<T extends object>(input: T): T {\n const output = structuredClone(input) as Payload;\n if (!output.tokens) return input;\n output.tokens.essentialOmitted ??= 0;\n if (account(output) <= output.tokens.budget) return output as T;\n\n const candidates: Candidate[] = [];\n const add = (section: string, value: unknown, priority: number, essential = false) => {\n candidates.push({ section, value, priority, essential });\n };\n for (const [section, priority] of [\n [\"diffs\", 10],\n [\"neighbours\", 20],\n [\"handoffs\", 30],\n [\"facts\", 40],\n [\"rules\", 45],\n [\"symbols\", 50],\n [\"policyRules\", 90],\n [\"incidents\", 80],\n ] as const) {\n const values = output[section];\n if (!Array.isArray(values)) continue;\n for (const value of values) {\n const essential = section === \"policyRules\" || (section === \"incidents\" && !value.resolved);\n const severity =\n section === \"incidents\"\n ? ({ critical: 4, high: 3, medium: 2, low: 1 }[value.severity as string] ?? 0)\n : 0;\n add(section, value, priority + severity, essential);\n }\n output[section] = [];\n }\n const risks = output.risks as { items: Array<{ score: number }> } | undefined;\n if (risks) {\n for (const value of risks.items)\n add(\n \"risks\",\n value,\n value.score >= 50 ? 100 + value.score : 60 + value.score / 100,\n value.score > 0,\n );\n risks.items = [];\n }\n if (output.plan) {\n add(\"plan\", output.plan, 55);\n output.plan = null;\n }\n const architecture = output.architecture as { hotspots: unknown[] } | undefined;\n if (architecture) {\n for (const value of architecture.hotspots) add(\"hotspots\", value, 25);\n architecture.hotspots = [];\n }\n output.explain = [];\n if (typeof output.task === \"string\") output.task = compact(output.task, 160);\n const riskStats = (output.risks as { stats?: { perSignal: unknown[] } } | undefined)?.stats;\n if (riskStats) riskStats.perSignal = [];\n\n // Reserve a bounded warning before selecting evidence so adding it cannot\n // silently displace the last safety item. Identity and target paths are exact.\n const previousOmitted = output.tokens.essentialOmitted;\n output.tokens.essentialOmitted = previousOmitted + candidates.filter((c) => c.essential).length;\n output.tokens.warning = WARNING;\n if (account(output) > output.tokens.budget && output.task) output.task = null;\n // No candidate selection can rescue a target set that alone exceeds the\n // budget. Avoid repeatedly tokenizing enormous change sets in that case.\n if (\n estimateTokens({ project: output.project, targetPaths: output.targetPaths }) >\n output.tokens.budget\n ) {\n account(output);\n return output as T;\n }\n\n candidates.sort((a, b) => b.priority - a.priority);\n for (const candidate of candidates) {\n const insert = (value: unknown) => {\n if (candidate.section === \"plan\") output.plan = value;\n else if (candidate.section === \"risks\") risks?.items.push(value as { score: number });\n else if (candidate.section === \"hotspots\") architecture?.hotspots.push(value);\n else (output[candidate.section] as unknown[]).push(value);\n };\n const remove = () => {\n if (candidate.section === \"plan\") output.plan = null;\n else if (candidate.section === \"risks\") risks?.items.pop();\n else if (candidate.section === \"hotspots\") architecture?.hotspots.pop();\n else (output[candidate.section] as unknown[]).pop();\n };\n insert(candidate.value);\n if (candidate.essential) output.tokens.essentialOmitted--;\n if (account(output) <= output.tokens.budget) continue;\n remove();\n if (candidate.essential) output.tokens.essentialOmitted++;\n // Keep policy instructions verbatim. A shortened safety item is explicitly\n // incomplete and retains the warning.\n const smaller = candidate.essential\n ? compactSafety(candidate.value)\n : compact(candidate.value, 100);\n insert(smaller);\n if (account(output) <= output.tokens.budget) continue;\n remove();\n }\n if (output.tokens.essentialOmitted === 0) delete output.tokens.warning;\n account(output);\n return output as T;\n}\n\nfunction compactSafety(value: unknown): unknown {\n if (!value || typeof value !== \"object\") return value;\n const item = value as Record<string, unknown>;\n // Patterns, messages, identities and paths remain exact. Risk/incident\n // narratives may be shortened with an explicit incomplete status.\n return {\n ...item,\n ...(typeof item.reason === \"string\" ? { reason: compact(item.reason, 100) } : {}),\n ...(typeof item.summary === \"string\" ? { summary: compact(item.summary, 100) } : {}),\n ...(Array.isArray(item.evidence)\n ? { evidence: item.evidence.slice(0, 1).map((entry) => compact(entry, 100)) }\n : {}),\n };\n}\n\nfunction compact(value: unknown, limit: number): unknown {\n if (typeof value === \"string\")\n return value.length > limit ? `${value.slice(0, limit - 1)}…` : value;\n if (Array.isArray(value)) return value.slice(0, 3).map((item) => compact(item, limit));\n if (value && typeof value === \"object\")\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [key, compact(item, limit)]),\n );\n return value;\n}\n\n/** Find an exact fixed point because the reported count itself occupies tokens. */\nfunction account(output: Payload): number {\n const tokens = output.tokens;\n const set = (count: number) => {\n tokens.returnedEstimate = count;\n tokens.countedSurface = \"compact_json\";\n tokens.status =\n count > tokens.budget\n ? \"overflow\"\n : tokens.essentialOmitted > 0\n ? \"minimum_envelope\"\n : \"within_budget\";\n if (tokens.status === \"overflow\") tokens.warning = WARNING;\n };\n // Numeric token boundaries can form a cycle. A JSON whitespace field gives\n // deterministic alternative encodings without changing any evidence.\n for (let padding = 0; padding < 32; padding++) {\n if (padding > 0) output.accountingPadding = \" \".repeat(padding);\n let count = estimateTokens(output);\n for (let attempt = 0; attempt < 12; attempt++) {\n set(count);\n const measured = estimateTokens(output);\n if (measured === count) return count;\n count = measured;\n }\n }\n throw new Error(\"Could not stabilize compact context token accounting\");\n}\n","import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { generateEntityId } from \"../core/ids.js\";\nimport { MemoryFileStore } from \"../core/memory-file-store.js\";\nimport { isEligibleMemory } from \"../core/memory-lifecycle.js\";\nimport { termOverlap } from \"../core/memory-search.js\";\nimport { WorklogStore } from \"../worklog/store.js\";\nimport { incidentDoubt } from \"./deterministic.js\";\nimport { type ExtractOptions, extractCandidates } from \"./llm.js\";\nimport { matchResolution } from \"./resolution.js\";\nimport { ReviewStore } from \"./review-store.js\";\nimport { revokes } from \"./rules.js\";\nimport { claimText, redactPersisted, type SensitivityResult, scanFields } from \"./sensitive.js\";\nimport type {\n AfterTurnResult,\n CandidateDecision,\n ExtractionInput,\n MemoryCandidate,\n} from \"./types.js\";\n\n/**\n * The capture orchestrator (`context_after_turn`). It extracts candidates,\n * then gates each one:\n *\n * - `ignored` → dropped.\n * - sensitive content → queued for review, flagged (never auto-saved).\n * - `note` (temporary) → queued for review (never durable).\n * - confident fact/decision/incident (≥ threshold) → saved as durable Markdown.\n * - everything else → queued for review (low confidence).\n *\n * The bias is deliberate: durable memory is the exception, review is the rule.\n */\n\n/** Minimum confidence for a fact/decision/incident to skip review. */\nconst AUTO_SAVE_THRESHOLD = 0.7;\n/** The user stated it (rule) or it passed repeatedly (procedure): trusted, still sensitive-scanned. */\nconst STATED_CONFIDENCE = 0.9;\n\nexport type CaptureOptions = ExtractOptions & {\n repositoryRoot?: string;\n now?: () => Date;\n};\n\nexport async function captureAfterTurn(\n input: ExtractionInput,\n options: CaptureOptions = {},\n): Promise<AfterTurnResult> {\n const repositoryRoot = resolve(options.repositoryRoot ?? process.cwd());\n const now = options.now ?? (() => new Date());\n const memoryStore = new MemoryFileStore(repositoryRoot);\n const reviewStore = new ReviewStore(repositoryRoot);\n\n const extracted =\n input.extract === false\n ? { candidates: [], source: \"deterministic\" as const }\n : await extractCandidates(input, options);\n const source = extracted.source;\n const candidates = [\n ...extracted.candidates,\n ...(input.userRules ?? []).map(ruleCandidate),\n ...(await procedureCandidates(input, repositoryRoot)),\n ];\n\n const saved: CandidateDecision[] = [];\n const queuedForReview: CandidateDecision[] = [];\n const ignored: CandidateDecision[] = [];\n const reasons: string[] = [];\n\n for (const candidate of candidates) {\n // Scan every text surface that reaches durable Markdown: all candidate\n // fields plus the turn's provenance (verification, paths, agent/plan/session/commit).\n const sensitivity = scanFields([\n claimText(candidate),\n candidate.content,\n candidate.subject,\n candidate.predicate,\n candidate.object,\n ...candidate.paths,\n ...(input.verification ?? []),\n input.agentId,\n input.planId,\n input.sessionId,\n input.commitSha,\n ]);\n const decision = await gate({\n candidate,\n input,\n sensitivity,\n memoryStore,\n reviewStore,\n now,\n });\n reasons.push(`${candidate.class}: ${decision.outcome} — ${decision.reason}`);\n if (decision.outcome === \"saved\") saved.push(decision);\n else if (decision.outcome === \"queued\") queuedForReview.push(decision);\n else ignored.push(decision);\n }\n\n for (const revocation of input.revokedRules ?? []) {\n const decision = await revokeRule(revocation, input, memoryStore, reviewStore, now);\n reasons.push(`rule: ${decision.outcome} — ${decision.reason}`);\n // A matched revocation changes existing memory; only an unmatched one is new.\n if (decision.outcome === \"queued\") queuedForReview.push(decision);\n }\n\n const worklogId = await recordWorklog(\n input,\n saved,\n queuedForReview,\n repositoryRoot,\n now,\n reasons,\n );\n return { saved, queuedForReview, ignored, reasons, extractor: source, worklogId };\n}\n\n/**\n * One worklog entry per meaningful turn (files changed, memory saved, or\n * verification reported), so a later chat can recover the work. A worklog\n * failure never undoes or blocks the memory capture above.\n */\nasync function recordWorklog(\n input: ExtractionInput,\n saved: CandidateDecision[],\n queued: CandidateDecision[],\n repositoryRoot: string,\n now: () => Date,\n reasons: string[],\n): Promise<string | null> {\n const files = input.changedFiles ?? [];\n const verification = input.verification ?? [];\n if (files.length === 0 && saved.length === 0 && verification.length === 0 && !input.investigation)\n return null;\n try {\n return await new WorklogStore(repositoryRoot).record(\n {\n namespace: input.namespace,\n summary: input.summary,\n files,\n verification,\n savedMemory: saved.flatMap((decision) => (decision.ref ? [decision.ref] : [])),\n queuedForReview: queued.flatMap((decision) => (decision.ref ? [decision.ref] : [])),\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.commitSha !== undefined ? { commitSha: input.commitSha } : {}),\n ...(input.agentId !== undefined ? { agentId: input.agentId } : {}),\n },\n now(),\n );\n } catch (error) {\n reasons.push(`worklog: not recorded — ${(error as Error).message}`);\n return null;\n }\n}\n\nfunction ruleCandidate(rule: string): MemoryCandidate {\n return {\n class: \"decision\",\n content: rule,\n subject: \"rule\",\n predicate: \"rule\",\n object: rule,\n confidence: STATED_CONFIDENCE,\n paths: [],\n severity: null,\n };\n}\n\n/**\n * A verification command that passed this turn and in at least one earlier\n * captured turn becomes a procedure (\"Verify with: npm test\"). Dedupe is the\n * usual fingerprint, so it is saved once.\n */\nasync function procedureCandidates(\n input: ExtractionInput,\n repositoryRoot: string,\n): Promise<MemoryCandidate[]> {\n const passed = (input.verification ?? []).filter((line) => line.endsWith(\": passed\"));\n if (passed.length === 0) return [];\n let history: string[][];\n try {\n history = (await new WorklogStore(repositoryRoot).list(input.namespace)).map(\n (entry) => entry.verification,\n );\n } catch {\n return [];\n }\n return [...new Set(passed)]\n .filter((line) => history.some((verification) => verification.includes(line)))\n .map((line) => {\n const command = line.slice(0, -\": passed\".length);\n return {\n class: \"fact\" as const,\n content: `Verify with: ${command}`,\n subject: \"procedure\",\n predicate: \"procedure\",\n object: command,\n confidence: STATED_CONFIDENCE,\n paths: [],\n severity: null,\n };\n });\n}\n\n/** Supersede the live rules a user sentence withdraws; with no match, ask a human. */\nasync function revokeRule(\n revocation: string,\n input: ExtractionInput,\n memoryStore: MemoryFileStore,\n reviewStore: ReviewStore,\n now: () => Date,\n): Promise<CandidateDecision> {\n const candidate: MemoryCandidate = {\n class: \"note\",\n content: revocation,\n subject: \"rule\",\n predicate: \"revoke\",\n object: revocation,\n confidence: 0.4,\n paths: [],\n severity: null,\n };\n const matches = (await memoryStore.listFacts()).filter(\n (fact) =>\n fact.predicate === \"rule\" &&\n isEligibleMemory(fact, { namespace: input.namespace }) &&\n revokes(revocation, fact.object),\n );\n const base = { candidate, sensitive: false, sensitiveReasons: [] };\n if (matches.length === 0) {\n const sensitivity = scanFields([revocation]);\n const decision = await gate({ candidate, input, sensitivity, memoryStore, reviewStore, now });\n return { ...decision, reason: `revocation matched no rule; ${decision.reason}` };\n }\n const marker = `revoked:${now().toISOString()}`;\n for (const fact of matches) await memoryStore.markFactSuperseded(fact.id, marker);\n return {\n ...base,\n outcome: \"saved\",\n reason: `revoked ${matches.map((fact) => fact.id).join(\", \")}`,\n ref: matches[0]?.id as string,\n };\n}\n\nasync function gate(args: {\n candidate: MemoryCandidate;\n input: ExtractionInput;\n sensitivity: SensitivityResult;\n memoryStore: MemoryFileStore;\n reviewStore: ReviewStore;\n now: () => Date;\n}): Promise<CandidateDecision> {\n const { candidate, sensitivity } = args;\n const fingerprint = candidateFingerprint(args.input.namespace, candidate);\n const base = {\n candidate,\n sensitive: sensitivity.sensitive,\n sensitiveReasons: sensitivity.reasons,\n };\n\n if (candidate.class === \"ignored\") {\n return { ...base, outcome: \"ignored\", reason: \"classified as chatter\" };\n }\n\n if (sensitivity.sensitive) {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n const ref =\n existing?.id ?? (await queue(args, `sensitive content (${sensitivity.reasons.join(\", \")})`));\n return {\n ...base,\n outcome: \"queued\",\n reason: `sensitive: ${sensitivity.reasons.join(\", \")}`,\n ref,\n };\n }\n\n if (candidate.class === \"note\") {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n if (existing) {\n return { ...base, outcome: \"queued\", reason: \"duplicate review candidate\", ref: existing.id };\n }\n const ref = await queue(args, \"temporary note\");\n return { ...base, outcome: \"queued\", reason: \"temporary note held for review\", ref };\n }\n\n if (candidate.confidence < AUTO_SAVE_THRESHOLD) {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n if (existing) {\n return { ...base, outcome: \"queued\", reason: \"duplicate review candidate\", ref: existing.id };\n }\n const ref = await queue(args, `low confidence (${candidate.confidence.toFixed(2)})`);\n return {\n ...base,\n outcome: \"queued\",\n reason: `low confidence ${candidate.confidence.toFixed(2)} < ${AUTO_SAVE_THRESHOLD}`,\n ref,\n };\n }\n\n if (candidate.class === \"incident\") {\n const doubt = incidentDoubt(candidate.content);\n if (doubt) {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n const ref = existing?.id ?? (await queue(args, `uncertain incident: ${doubt}`));\n return { ...base, outcome: \"queued\", reason: `uncertain incident: ${doubt}`, ref };\n }\n }\n\n if (candidate.class === \"incident\" && isResolution(candidate.content)) {\n const unresolved = await args.memoryStore.listIncidentFacts({\n namespace: args.input.namespace,\n });\n const sharingPaths = await args.memoryStore.findIncidentFactsForPaths({\n namespace: args.input.namespace,\n paths: candidate.paths,\n });\n const match = matchResolution(candidate.content, sharingPaths, unresolved);\n if (match.kind === \"queue\") {\n const ref = await queue(\n args,\n `incident resolution not grounded: ${match.reason}`,\n match.candidates,\n );\n return {\n ...base,\n outcome: \"queued\",\n reason: `resolution not grounded: ${match.reason}`,\n ref,\n };\n }\n await args.memoryStore.markIncidentResolved(match.incident.id, fingerprint);\n return {\n ...base,\n outcome: \"saved\",\n reason: `resolved incident ${match.incident.id} (${match.reason})`,\n ref: match.incident.id,\n };\n }\n\n const superseded = candidate.content.match(/\\bsupersedes\\s+(fact_[a-z0-9]+)\\b/i)?.[1];\n // Mem0-style update check without an LLM: a reworded copy of a live fact is\n // dropped, and a partial overlap goes to review as a possible update rather\n // than being saved beside the fact it may replace. Incidents may recur, and\n // an explicit \"supersedes fact_x\" already says what it replaces.\n if (candidate.class !== \"incident\" && !superseded) {\n const similar = await nearestFact(\n args.memoryStore,\n args.input.namespace,\n candidate,\n fingerprint,\n );\n if (similar && similar.overlap >= DUPLICATE_OVERLAP) {\n return {\n ...base,\n outcome: \"ignored\",\n reason: `near-duplicate of ${similar.id} (${Math.round(similar.overlap * 100)}% shared words)`,\n ref: similar.id,\n };\n }\n if (similar && similar.overlap >= UPDATE_OVERLAP) {\n const existing = (await args.reviewStore.list()).find(\n (item) => item.fingerprint === fingerprint,\n );\n const ref = existing?.id ?? (await queue(args, `possible update of ${similar.id}`));\n return {\n ...base,\n outcome: \"queued\",\n reason: `overlaps ${similar.id} (${Math.round(similar.overlap * 100)}% shared words): review as a possible update`,\n ref,\n };\n }\n }\n\n const ref = await saveDurable(args);\n if (superseded && superseded !== ref) {\n try {\n await args.memoryStore.markFactSuperseded(superseded, ref);\n } catch {\n // A missing/invalid referenced fact does not invalidate the new decision.\n }\n }\n return { ...base, outcome: \"saved\", reason: `confident ${candidate.class} auto-saved`, ref };\n}\n\n/** At or above this word overlap a new fact restates a live one. */\nconst DUPLICATE_OVERLAP = 0.8;\n/** At or above this overlap a new fact may update a live one: a person decides. */\nconst UPDATE_OVERLAP = 0.5;\n\n/** The live fact of this namespace whose content overlaps the candidate most. */\nasync function nearestFact(\n memoryStore: MemoryFileStore,\n namespace: string,\n candidate: MemoryCandidate,\n fingerprint: string,\n): Promise<{ id: string; overlap: number } | null> {\n let best: { id: string; overlap: number } | null = null;\n for (const fact of await memoryStore.listFacts()) {\n // An exact repeat keeps its existing outcome (saveDurable returns that fact).\n if (fact.fingerprint === fingerprint || fact.category === \"incident\") continue;\n if (fact.predicate === \"rule\" || fact.predicate === \"procedure\") continue;\n if (!isEligibleMemory(fact, { namespace })) continue;\n const overlap = termOverlap(candidate.content, fact.content || fact.object);\n if (!best || overlap > best.overlap) best = { id: fact.id, overlap };\n }\n return best;\n}\n\nasync function saveDurable(args: {\n candidate: MemoryCandidate;\n input: ExtractionInput;\n memoryStore: MemoryFileStore;\n now: () => Date;\n}): Promise<string> {\n const { candidate, input, memoryStore, now } = args;\n const fingerprint = candidateFingerprint(input.namespace, candidate);\n const existing = (await memoryStore.listFacts()).find(\n (fact) => fact.namespace === input.namespace && fact.fingerprint === fingerprint,\n );\n if (existing) return existing.id;\n const id = generateEntityId(\"fact\");\n const isIncident = candidate.class === \"incident\";\n await memoryStore.writeFact({\n id,\n namespace: input.namespace,\n subject: candidate.subject,\n predicate: candidate.predicate,\n object: candidate.object,\n confidence: candidate.confidence,\n createdAt: now().toISOString(),\n createdByAgent: input.agentId ?? null,\n sourceInteractionId: null,\n sourceDeleted: false,\n content: candidate.content,\n category: isIncident ? \"incident\" : \"general\",\n paths: candidate.paths,\n severity: isIncident ? candidate.severity : null,\n fingerprint,\n sourcePlanId: input.planId ?? null,\n sourceSessionId: input.sessionId ?? null,\n verification: input.verification ?? [],\n introducedBy: isIncident ? (input.commitSha ?? null) : null,\n });\n return id;\n}\n\nasync function queue(\n args: {\n candidate: MemoryCandidate;\n input: ExtractionInput;\n sensitivity: SensitivityResult;\n reviewStore: ReviewStore;\n now: () => Date;\n },\n reason: string,\n resolvesIncidents: string[] | null = null,\n): Promise<string> {\n const { candidate, input, sensitivity, reviewStore, now } = args;\n const fingerprint = candidateFingerprint(input.namespace, candidate);\n const id = generateEntityId(\"rev\");\n await reviewStore.write({\n id,\n namespace: input.namespace,\n class: candidate.class,\n subject: candidate.subject,\n predicate: candidate.predicate,\n object: candidate.object,\n confidence: candidate.confidence,\n paths: candidate.paths,\n severity: candidate.severity,\n sensitive: sensitivity.sensitive,\n sensitiveReasons: sensitivity.reasons,\n reason,\n createdAt: now().toISOString(),\n createdByAgent: input.agentId ?? null,\n sourcePlanId: input.planId ?? null,\n fingerprint,\n sourceSessionId: input.sessionId ?? null,\n verification: input.verification ?? [],\n content: candidate.content,\n resolvesIncidents,\n });\n await reviewStore.enforceLimit();\n return id;\n}\n\nfunction isResolution(content: string): boolean {\n return /\\b(fixed|resolved|closed|no longer reproduces|verified the fix)\\b/i.test(content);\n}\n\nexport function candidateFingerprint(namespace: string, raw: MemoryCandidate): string {\n // Hash the redacted form so the persisted fingerprint never derives from a raw secret.\n const candidate = redactPersisted(raw);\n const canonical = JSON.stringify({\n namespace: namespace.trim().toLowerCase(),\n class: candidate.class,\n subject: candidate.subject.trim().toLowerCase(),\n predicate: candidate.predicate.trim().toLowerCase(),\n object: candidate.object.trim().replace(/\\s+/g, \" \").toLowerCase(),\n content: candidate.content.trim().replace(/\\s+/g, \" \").toLowerCase(),\n paths: [...new Set(candidate.paths.map((path) => path.replace(/\\\\/g, \"/\")))].sort(),\n });\n return createHash(\"sha256\").update(canonical).digest(\"hex\");\n}\n\n/**\n * Promote a queued review item to a durable fact and remove it from the queue.\n * A queued incident resolution instead resolves the chosen existing incident\n * (`incidentId`, or the single recorded candidate) and returns its id.\n * Powers `codebuddy memory review approve`.\n */\nexport async function approveReviewItem(\n id: string,\n options: { repositoryRoot?: string; now?: () => Date; incidentId?: string } = {},\n): Promise<string> {\n const repositoryRoot = resolve(options.repositoryRoot ?? process.cwd());\n const now = options.now ?? (() => new Date());\n const reviewStore = new ReviewStore(repositoryRoot);\n const memoryStore = new MemoryFileStore(repositoryRoot);\n\n const item = await reviewStore.read(id);\n\n // A queued resolution closes an existing incident; it never writes a new one.\n if (item.resolvesIncidents) {\n const unresolved = await memoryStore.listIncidentFacts({ namespace: item.namespace });\n const target =\n options.incidentId ??\n (item.resolvesIncidents.length === 1 ? item.resolvesIncidents[0] : undefined);\n if (!target) {\n throw new Error(\n item.resolvesIncidents.length === 0\n ? `Review item ${id} is an incident resolution with no candidate incident; pass an incident id to resolve.`\n : `Review item ${id} is an ambiguous incident resolution; pass one incident id. Candidates: ${item.resolvesIncidents.join(\", \")}`,\n );\n }\n if (!unresolved.some((incident) => incident.id === target)) {\n throw new Error(`${target} is not an unresolved incident in namespace ${item.namespace}.`);\n }\n await memoryStore.markIncidentResolved(target, item.fingerprint ?? id);\n await reviewStore.delete(id);\n return target;\n }\n\n const factId = generateEntityId(\"fact\");\n const isIncident = item.class === \"incident\";\n await memoryStore.writeFact({\n id: factId,\n namespace: item.namespace,\n subject: item.subject,\n predicate: item.predicate,\n object: item.object,\n confidence: item.confidence,\n createdAt: now().toISOString(),\n createdByAgent: item.createdByAgent,\n sourceInteractionId: null,\n sourceDeleted: false,\n content: item.content,\n category: isIncident ? \"incident\" : \"general\",\n paths: item.paths,\n severity: isIncident ? (item.severity ?? \"medium\") : null,\n fingerprint: item.fingerprint,\n sourcePlanId: item.sourcePlanId,\n sourceSessionId: item.sourceSessionId,\n verification: item.verification,\n });\n await reviewStore.delete(id);\n return factId;\n}\n","import type { IncidentSeverity } from \"../core/memory-file-store.js\";\nimport type { ExtractionInput, MemoryCandidate, MemoryClass } from \"./types.js\";\n\n/**\n * Deterministic, no-LLM extraction. This is the always-available baseline\n * (offline mode) and the fallback when LLM extraction fails validation. It\n * segments the turn summary into sentences and classifies each with ordered\n * keyword rules. The same input always yields the same candidates, which keeps\n * capture predictable and auditable.\n *\n * Rule order matters: a \"TODO: fix the crash\" is a note, not an incident, so\n * note markers are checked before incident markers.\n */\n\ntype Rule = {\n class: MemoryClass;\n regex: RegExp;\n confidence: number;\n predicate: string;\n subject: string;\n};\n\n/** \"Resolved fact_abc123\": names its incident, so it is unambiguous by construction. */\nconst EXPLICIT_RESOLUTION = /\\b(?:fixed|resolved|closed)\\b.*\\bfact_[a-z0-9]+\\b/i;\n\nconst RULES: Rule[] = [\n {\n class: \"note\",\n subject: \"note\",\n predicate: \"todo\",\n confidence: 0.4,\n regex:\n /\\b(todo|to-do|follow[- ]?up|later|remember to|revisit|temporary|tmp|next time|should probably)\\b/i,\n },\n {\n // Explicit resolution of a named incident (\"Resolved fact_abc123\").\n class: \"incident\",\n subject: \"incident\",\n predicate: \"resolved\",\n confidence: 0.8,\n regex: EXPLICIT_RESOLUTION,\n },\n {\n class: \"decision\",\n subject: \"decision\",\n predicate: \"made\",\n confidence: 0.8,\n regex:\n /\\b(decided|chose|choose|we will|going with|switched to|switch to|adopt(?:ed)?|agreed|settled on|opt(?:ed)? for)\\b/i,\n },\n {\n class: \"incident\",\n subject: \"incident\",\n predicate: \"occurred\",\n confidence: 0.75,\n regex:\n /\\b(bug|regression|broke|broken|crash(?:ed)?|outage|incident|root cause|failure|failed|null pointer|race condition|deadlock)\\b/i,\n },\n {\n class: \"fact\",\n subject: \"project\",\n predicate: \"fact\",\n confidence: 0.55,\n regex:\n /\\b(uses?|is|are|requires?|depends on|stores?|returns?|implemented|added|supports?|configured|lives in|located|handles?)\\b/i,\n },\n];\n\nconst INCIDENT_REGEX = (RULES.find((rule) => rule.predicate === \"occurred\") as Rule).regex;\nexport const SPECULATIVE =\n /\\b(might|maybe|possibly|could|consider(?:ing)?|planned|planning|should|if|would|unless|whether|suppose|hypothetical(?:ly)?|in theory|in case)\\b/i;\n// \"no longer reproduces\" is a resolution, not a negation.\nconst NEGATION =\n /\\b(no|not|never|none|nothing|nobody|without|zero|neither|nor|cannot)\\b(?!\\s+longer)|\\w+n['’]t\\b/i;\nconst EXAMPLE = /\\b(?:e\\.g|i\\.e|for example|for instance|such as|example|sample|hypothetical)\\b/i;\n// Balanced \"double\", \\u201ccurly\\u201d and `code` quotes.\nconst QUOTED = /\"[^\"]*\"|\\u201c[^\\u201d]*\\u201d|`[^`]*`/g;\n\n/**\n * Why an incident-looking sentence is not trustworthy enough to become a\n * durable incident: negated (\"no crash occurred\"), hypothetical (\"if it\n * crashes\"), or quoted/example text. Returns null when it reads as a real\n * event. Shared by the deterministic extractor and the capture gate so LLM\n * candidates get the same scrutiny.\n */\nexport function incidentDoubt(sentence: string): string | null {\n if (EXPLICIT_RESOLUTION.test(sentence)) return null;\n const unquoted = sentence.replace(QUOTED, \" \");\n const onlyQuoted = INCIDENT_REGEX.test(sentence) && !INCIDENT_REGEX.test(unquoted);\n const unbalanced = (sentence.match(/[\"\\u201c\\u201d]/g)?.length ?? 0) % 2 === 1;\n if (onlyQuoted || unbalanced || EXAMPLE.test(sentence)) return \"quoted or example text\";\n if (NEGATION.test(unquoted)) return \"negated statement\";\n if (SPECULATIVE.test(unquoted) && !EXPLICIT_DECISION.test(unquoted))\n return \"hypothetical statement\";\n return null;\n}\nconst EXPLICIT_DECISION = /\\b(decided|chose|agreed|settled on|adopted|switched to)\\b/i;\n\nconst SEVERITY_MARKERS: Array<{ severity: IncidentSeverity; regex: RegExp }> = [\n { severity: \"critical\", regex: /\\b(critical|outage|data loss|corruption|security)\\b/i },\n {\n severity: \"high\",\n regex: /\\b(high severity|regression|crash(?:ed)?|deadlock|broke production)\\b/i,\n },\n { severity: \"low\", regex: /\\b(minor|cosmetic|typo|trivial)\\b/i },\n];\n\nexport function deterministicExtract(input: ExtractionInput): MemoryCandidate[] {\n const changedFiles = (input.changedFiles ?? []).filter(Boolean);\n const candidates: MemoryCandidate[] = [];\n\n for (const sentence of splitSentences(input.summary)) {\n const classified = classify(sentence);\n const doubt = classified?.class === \"incident\" ? incidentDoubt(sentence) : null;\n const rule =\n doubt ||\n (SPECULATIVE.test(sentence) &&\n !EXPLICIT_DECISION.test(sentence) &&\n !EXPLICIT_RESOLUTION.test(sentence))\n ? {\n class: \"note\" as const,\n subject: \"speculation\",\n predicate: \"consider\",\n confidence: 0.3,\n regex: SPECULATIVE,\n }\n : classified;\n if (!rule) {\n candidates.push(ignoredCandidate(sentence));\n continue;\n }\n\n const isIncident = rule.class === \"incident\";\n let confidence = rule.confidence;\n if (isIncident && /\\broot cause\\b/i.test(sentence)) confidence = Math.min(1, confidence + 0.1);\n\n candidates.push({\n class: rule.class,\n content: sentence,\n subject: rule.subject,\n predicate: rule.predicate,\n object: sentence,\n confidence,\n // Incidents and decisions carry the change set so recall can link them to\n // the files they concern (the risk incident signal matches on paths).\n paths: rule.class === \"incident\" || rule.class === \"decision\" ? changedFiles : [],\n severity: isIncident ? guessSeverity(sentence) : null,\n });\n }\n\n return candidates;\n}\n\nfunction classify(sentence: string): Rule | null {\n for (const rule of RULES) {\n if (rule.regex.test(sentence)) return rule;\n }\n return null;\n}\n\nfunction ignoredCandidate(sentence: string): MemoryCandidate {\n return {\n class: \"ignored\",\n content: sentence,\n subject: \"chatter\",\n predicate: \"ignored\",\n object: sentence,\n confidence: 0.2,\n paths: [],\n severity: null,\n };\n}\n\nfunction guessSeverity(sentence: string): IncidentSeverity {\n for (const marker of SEVERITY_MARKERS) {\n if (marker.regex.test(sentence)) return marker.severity;\n }\n return \"medium\";\n}\n\n/** Split into trimmed sentences on terminators and newlines; drop tiny fragments. */\nexport function splitSentences(summary: string): string[] {\n return summary\n .split(/(?<=[.!?])(?<!\\b(?:e\\.g|i\\.e|vs|etc)\\.)\\s+|\\n+/)\n .map((sentence) => sentence.trim().replace(/^[-*•]\\s*/, \"\"))\n .filter((sentence) => sentence.length > 3);\n}\n","import { z } from \"zod\";\nimport { deterministicExtract } from \"./deterministic.js\";\nimport { type ExtractionInput, type MemoryCandidate, memoryCandidateSchema } from \"./types.js\";\n\n/**\n * LLM-assisted extraction is optional and never trusted blindly. An extractor\n * returns raw JSON; we validate it strictly against the candidate schema and\n * retry a bounded number of times. If it never produces valid output — or no\n * extractor is configured — we fall back to the deterministic parser rather\n * than inventing certainty. Raw LLM output is a suggestion, not a fact.\n */\n\n/** Pluggable model backend. Returns unvalidated candidate JSON. */\nexport type MemoryExtractor = {\n extract(input: ExtractionInput): Promise<unknown>;\n};\n\nconst candidateArraySchema = z.array(memoryCandidateSchema);\n\nexport type ExtractOptions = {\n extractor?: MemoryExtractor;\n retries?: number;\n};\n\nexport type ExtractOutcome = {\n candidates: MemoryCandidate[];\n source: \"deterministic\" | \"llm\";\n};\n\nexport async function extractCandidates(\n input: ExtractionInput,\n options: ExtractOptions = {},\n): Promise<ExtractOutcome> {\n if (options.extractor) {\n const validated = await tryLlmExtraction(input, options.extractor, options.retries ?? 2);\n if (validated) return { candidates: validated, source: \"llm\" };\n }\n return { candidates: deterministicExtract(input), source: \"deterministic\" };\n}\n\nasync function tryLlmExtraction(\n input: ExtractionInput,\n extractor: MemoryExtractor,\n retries: number,\n): Promise<MemoryCandidate[] | null> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const parsed = candidateArraySchema.safeParse(await extractor.extract(input));\n if (parsed.success) return parsed.data;\n } catch {\n // Swallow and retry; a throwing extractor is treated like invalid output.\n }\n }\n return null;\n}\n","import type { IncidentFactFile } from \"../core/memory-file-store.js\";\n\n/**\n * Deciding which unresolved incident a \"fixed X\" statement closes. A shared\n * file is never enough: resolution needs an explicit incident id, or fix text\n * that matches exactly one candidate's terms better than every other one.\n * Anything else is ambiguous and goes to review. Severity/recency never break\n * ties, so a generic fix can't close an unrelated higher-severity incident.\n *\n * Terms every candidate shares (e.g. the module name) say nothing about WHICH\n * incident was fixed, so only terms that tell candidates apart count, and the\n * fix must hit exactly one candidate's distinctive terms. A multi-topic fix\n * that touches two incidents is therefore ambiguous, however many terms match.\n */\n\nexport type ResolutionMatch =\n | { kind: \"resolved\"; incident: IncidentFactFile; reason: string }\n /** `candidates` are the unresolved incident ids a reviewer may pick from. */\n | { kind: \"queue\"; reason: string; candidates: string[] };\n\nconst FACT_ID = /\\bfact_[a-z0-9]+\\b/gi;\n\n// Words that carry no event identity: grammar plus generic fix/bug vocabulary.\nconst GENERIC = new Set(\n (\n \"a an the and or but of in on at to for from by with as is are was were be been it its this that these those \" +\n \"we i you they he she them there then than so not no also again now still just only into onto after before when while \" +\n \"fix fixed fixes fixing resolve resolved resolves resolving close closed closes verify verified verifies \" +\n \"bug bugs issue issues problem problems incident incidents error errors regression longer reproduce reproduces \" +\n \"test tests passed passing work works worked working change changed changes\"\n ).split(\" \"),\n);\n\n/** Lowercased content terms with a crude suffix stem (\"crashed\"/\"crashes\" -> \"crash\"). */\nexport function groundingTerms(text: string): Set<string> {\n const terms = new Set<string>();\n for (const word of text.toLowerCase().match(/[a-z][a-z0-9]+/g) ?? []) {\n if (GENERIC.has(word) || /^fact_/.test(word)) continue;\n terms.add(word.length > 4 ? word.replace(/(ing|ed|es|s)$/, \"\") : word);\n }\n return terms;\n}\n\nexport function matchResolution(\n fixText: string,\n pathCandidates: IncidentFactFile[],\n unresolved: IncidentFactFile[],\n): ResolutionMatch {\n const explicit = [...new Set(fixText.match(FACT_ID)?.map((id) => id.toLowerCase()))];\n if (explicit.length > 0) {\n const named = unresolved.filter((incident) => explicit.includes(incident.id));\n const [only] = named;\n if (named.length === 1 && only) {\n return { kind: \"resolved\", incident: only, reason: `explicit incident id ${only.id}` };\n }\n return {\n kind: \"queue\",\n candidates: named.map((incident) => incident.id),\n reason:\n named.length === 0\n ? \"explicit incident id does not name an unresolved incident\"\n : \"explicit ids name several incidents\",\n };\n }\n\n const candidates = pathCandidates.map((incident) => incident.id);\n const fixTerms = groundingTerms(fixText);\n if (pathCandidates.length === 0) {\n return {\n kind: \"queue\",\n candidates,\n reason: \"no unresolved incident touches the changed paths\",\n };\n }\n if (fixTerms.size === 0) {\n return { kind: \"queue\", candidates, reason: \"fix text names no specific event\" };\n }\n\n const incidentTerms = pathCandidates.map((incident) =>\n groundingTerms(`${incident.subject} ${incident.content}`),\n );\n // With several candidates, ignore terms all of them share (no discriminating power).\n const distinctive = (term: string) =>\n pathCandidates.length === 1 || incidentTerms.some((terms) => !terms.has(term));\n const hits = incidentTerms.map((terms) => [...fixTerms].filter((term) => terms.has(term)));\n const withDistinctive = hits\n .map((matched, index) => ({ index, matched, count: matched.filter(distinctive).length }))\n .filter((entry) => entry.count > 0 || pathCandidates.length === 1);\n\n const [best] = withDistinctive;\n if (!best || withDistinctive.length > 1) {\n return {\n kind: \"queue\",\n candidates,\n reason: best\n ? \"fix text matches distinctive terms of several unresolved incidents\"\n : \"fix text does not single out any unresolved incident\",\n };\n }\n const need = Math.min(2, fixTerms.size);\n if (best.matched.length < need) {\n return { kind: \"queue\", candidates, reason: \"fix text is too weakly grounded in the incident\" };\n }\n const incident = pathCandidates[best.index] as IncidentFactFile;\n return {\n kind: \"resolved\",\n incident,\n reason: `grounded match on ${best.matched.length} shared term${best.matched.length === 1 ? \"\" : \"s\"}`,\n };\n}\n","import { mkdir, readdir, readFile, rename, rm } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport {\n assertNoSymlinkBetween,\n composeMarkdown,\n parseFrontMatter,\n writeAtomic,\n} from \"../core/markdown-store-fs.js\";\nimport { INCIDENT_SEVERITIES } from \"../core/memory-file-store.js\";\nimport { redactPersisted } from \"./sensitive.js\";\nimport { MEMORY_CLASSES } from \"./types.js\";\n\n/**\n * The review queue holds memory candidates that are not safe to auto-save —\n * low confidence, sensitive content, or an inherently temporary note. Items are\n * plain Markdown with YAML front matter under `.codebuddy/memory/review/`, so\n * they are inspectable, diffable, and deletable by hand. Approving an item\n * promotes it to a durable fact; rejecting deletes it. Nothing here is ever\n * committed automatically.\n */\n\nconst reviewSchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().regex(/^rev_[a-z0-9]+$/),\n namespace: z.string().min(1),\n class: z.enum(MEMORY_CLASSES),\n subject: z.string().min(1),\n predicate: z.string().min(1),\n object: z.string().min(1),\n confidence: z.number().min(0).max(1),\n paths: z.array(z.string().min(1)).default([]),\n severity: z.enum(INCIDENT_SEVERITIES).nullable().default(null),\n sensitive: z.boolean().default(false),\n sensitiveReasons: z.array(z.string()).default([]),\n reason: z.string(),\n createdAt: z.string(),\n createdByAgent: z.string().nullable(),\n sourcePlanId: z.string().nullable().default(null),\n fingerprint: z\n .string()\n .regex(/^[a-f0-9]{64}$/)\n .nullable()\n .default(null),\n sourceSessionId: z.string().nullable().default(null),\n verification: z.array(z.string()).default([]),\n /**\n * Set only on a queued incident *resolution* (\"Fixed X\") that could not be\n * grounded: the unresolved incident ids it might close. Approving it resolves\n * one of them instead of writing a new incident. null = ordinary item.\n */\n resolvesIncidents: z.array(z.string()).nullable().default(null),\n});\n\nexport type ReviewItemWrite = Omit<\n z.infer<typeof reviewSchema>,\n \"schemaVersion\" | \"fingerprint\" | \"sourceSessionId\" | \"verification\" | \"resolvesIncidents\"\n> & {\n resolvesIncidents?: string[] | null;\n fingerprint?: string | null;\n sourceSessionId?: string | null;\n verification?: string[];\n content: string;\n};\nexport type ReviewItem = z.infer<typeof reviewSchema> & { content: string; path: string };\n\nexport class ReviewStore {\n readonly repositoryRoot: string;\n readonly reviewDirectory: string;\n readonly archiveDirectory: string;\n\n constructor(repositoryRoot = process.cwd()) {\n this.repositoryRoot = resolve(repositoryRoot);\n this.reviewDirectory = join(this.repositoryRoot, \".codebuddy\", \"memory\", \"review\");\n this.archiveDirectory = join(this.repositoryRoot, \".codebuddy\", \"memory\", \"review-archive\");\n }\n\n async write(raw: ReviewItemWrite): Promise<string> {\n // Persistence boundary: nothing sensitive reaches disk, whatever the caller did.\n const input = redactPersisted(raw);\n const path = this.itemPath(input.id);\n await this.prepareDirectory();\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(path));\n const frontMatter = stringifyYaml({\n schemaVersion: 1,\n id: input.id,\n namespace: input.namespace,\n class: input.class,\n subject: input.subject,\n predicate: input.predicate,\n object: input.object,\n confidence: input.confidence,\n paths: input.paths,\n severity: input.severity,\n sensitive: input.sensitive,\n sensitiveReasons: input.sensitiveReasons,\n reason: input.reason,\n createdAt: input.createdAt,\n createdByAgent: input.createdByAgent,\n sourcePlanId: input.sourcePlanId,\n fingerprint: input.fingerprint,\n sourceSessionId: input.sourceSessionId,\n verification: input.verification,\n resolvesIncidents: input.resolvesIncidents ?? null,\n });\n await writeAtomic(path, composeMarkdown(frontMatter, input.content));\n return path;\n }\n\n async read(id: string): Promise<ReviewItem> {\n const path = this.itemPath(id);\n await assertNoSymlinkBetween(this.repositoryRoot, path);\n const parsed = parseFrontMatter(await readFile(path, \"utf8\"));\n return {\n ...reviewSchema.parse(parseYaml(parsed.frontMatter)),\n content: parsed.content.trim(),\n path,\n };\n }\n\n async list(): Promise<ReviewItem[]> {\n try {\n await this.prepareDirectory();\n const entries = await readdir(this.reviewDirectory, { withFileTypes: true });\n const items: ReviewItem[] = [];\n for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n // Only managed review files are queue items. A hand-written README.md\n // (or any non-rev_ markdown) must be ignored, not thrown on — one\n // stray file used to brick every future capture turn.\n if (!/^rev_[a-z0-9]+\\.md$/.test(entry.name)) continue;\n try {\n items.push(await this.read(entry.name.replace(/\\.md$/, \"\")));\n } catch {\n // A single corrupt item is skipped rather than poisoning the whole\n // queue; it stays on disk for manual inspection.\n }\n }\n return items;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n }\n\n async delete(id: string): Promise<void> {\n await rm(this.itemPath(id), { force: true });\n }\n\n async archiveExpired(options: { olderThanDays?: number; now?: Date } = {}): Promise<number> {\n const cutoff =\n (options.now ?? new Date()).getTime() - (options.olderThanDays ?? 30) * 24 * 60 * 60 * 1000;\n const items = await this.list();\n let archived = 0;\n for (const item of items) {\n if (Date.parse(item.createdAt) >= cutoff) continue;\n await this.archive(item);\n archived++;\n }\n return archived;\n }\n\n async enforceLimit(maxItems = 500): Promise<number> {\n const items = (await this.list()).sort((left, right) =>\n left.createdAt.localeCompare(right.createdAt),\n );\n const overflow = Math.max(0, items.length - maxItems);\n for (const item of items.slice(0, overflow)) await this.archive(item);\n return overflow;\n }\n\n private async archive(item: ReviewItem): Promise<void> {\n await mkdir(this.archiveDirectory, { recursive: true, mode: 0o700 });\n await assertNoSymlinkBetween(this.repositoryRoot, this.archiveDirectory);\n await rename(item.path, join(this.archiveDirectory, `${item.id}.md`));\n }\n\n private itemPath(id: string): string {\n if (!/^rev_[a-z0-9]+$/.test(id)) throw new Error(`Invalid review id: ${id}`);\n return this.safePath(join(this.reviewDirectory, `${id}.md`));\n }\n\n private safePath(path: string): string {\n const absolute = resolve(path);\n const relativePath = relative(this.repositoryRoot, absolute);\n if (relativePath === \"..\" || relativePath.startsWith(`..${sep}`) || relativePath === \"\") {\n throw new Error(`Review path escapes repository root: ${path}`);\n }\n return absolute;\n }\n\n private async prepareDirectory(): Promise<void> {\n await assertNoSymlinkBetween(this.repositoryRoot, dirname(this.reviewDirectory));\n await mkdir(this.reviewDirectory, { recursive: true, mode: 0o700 });\n }\n}\n","import { SPECULATIVE } from \"./deterministic.js\";\n\n/**\n * Standing rules the user states (\"from now on…\", \"never…\", \"every PR\n * must…\") and revocations of them (\"stop…\", \"no longer…\"). A rule the user\n * stated is the most trustworthy memory there is, so it is read from the\n * user's own prompt, never from the assistant's paraphrase. Questions and\n * speculation are not rules.\n */\n\nconst MAX_RULE_CHARS = 300;\n/** CodeBuddy's injected context starts here; nothing after it is the user's. */\nconst INJECTED_BLOCK = /^##\\s*CodeBuddy\\b/m;\n/** Quoted or code material is never an instruction to this project. */\nconst FENCED_CODE = /```[\\s\\S]*?(?:```|$)/g;\nconst QUOTE_LINE = /^\\s*>.*$/gm;\n/** An explicit rule introduction: \"from now on\", \"going forward\", \"(a) rule (for …):\". */\nconst RULE_PREFIX =\n /^(?:also,?\\s+|please,?\\s+)?(?:from now on|going forward|(?:a\\s+)?rule\\b[^:.]{0,60}:)[,:]?\\s*/i;\n/** Imperative position: the sentence itself starts with the marker, or \"we/you always|never|must\". */\nconst IMPERATIVE =\n /^(?:please,?\\s+)?(?:always|never)\\s+\\S+\\s+\\S+|^(?:we|you)\\s+(?:always|never|must)\\b|^every\\s+(?!time\\b)\\S+.*\\bmust\\b/i;\nconst QUESTION_START =\n /^(?:why|how|what|when|where|which|who|can|could|would|will|do|does|did|is|are|should)\\b/i;\n/** Withdrawal of a rule: \"stop <verb>ing\", \"no longer\", \"don't … anymore\", \"forget the rule\". */\nconst REVOCATION_MARKER =\n /^(?:please,?\\s+)?stop\\s+\\w+ing\\b|\\bno longer\\b|\\b(?:don't|do not)\\b.*\\banymore\\b|\\b(?:forget|drop|remove)\\s+the\\s+rule\\b/i;\nconst STOPWORDS = new Set([\n \"the\",\n \"and\",\n \"for\",\n \"from\",\n \"now\",\n \"always\",\n \"never\",\n \"rule\",\n \"about\",\n \"longer\",\n \"don't\",\n \"anymore\",\n \"every\",\n \"must\",\n \"please\",\n \"with\",\n \"that\",\n \"this\",\n \"our\",\n \"you\",\n]);\n\nexport function extractUserRules(prompts: string[]): { rules: string[]; revocations: string[] } {\n const rules = new Map<string, string>();\n const revocations = new Map<string, string>();\n for (const prompt of prompts) {\n const own = (prompt.split(INJECTED_BLOCK)[0] ?? \"\")\n .replace(FENCED_CODE, \"\\n\")\n .replace(QUOTE_LINE, \"\");\n for (const raw of own.split(/(?<=[.!?])\\s+|\\n+/)) {\n const sentence = raw.trim();\n if (!sentence || sentence.length > MAX_RULE_CHARS || sentence.endsWith(\"?\")) continue;\n if (QUESTION_START.test(sentence)) continue;\n const key = sentence\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .replace(/[.!]+$/, \"\");\n if (REVOCATION_MARKER.test(sentence)) {\n if (!revocations.has(key)) revocations.set(key, sentence);\n } else if (isRule(sentence) && !SPECULATIVE.test(sentence)) {\n if (!rules.has(key)) rules.set(key, sentence);\n }\n }\n }\n return { rules: [...rules.values()], revocations: [...revocations.values()] };\n}\n\n/** A rule is explicitly introduced, or an imperative with at least a verb and an object. */\nfunction isRule(sentence: string): boolean {\n const rest = sentence.replace(RULE_PREFIX, \"\");\n if (rest !== sentence) return rest.split(/\\s+/).filter(Boolean).length >= 3;\n return IMPERATIVE.test(sentence);\n}\n\n/** Content words, crudely stemmed so \"running\"/\"run\" and \"committing\"/\"commit\" match. */\nexport function ruleWords(text: string): Set<string> {\n return new Set(\n (text.toLowerCase().match(/[a-z][a-z'-]+/g) ?? [])\n .filter((word) => word.length >= 3 && !STOPWORDS.has(word))\n .map((word) => word.replace(/(?:ing|ed|es|s)$/, \"\").replace(/([b-df-hj-np-tv-z])\\1$/, \"$1\")),\n );\n}\n\n/**\n * A revocation names a rule only when it repeats every content word of the\n * rule; anything looser goes to review instead of silently dropping a rule.\n */\nexport function revokes(revocation: string, rule: string): boolean {\n const ruleSet = ruleWords(rule);\n if (ruleSet.size === 0) return false;\n const words = ruleWords(revocation);\n return [...ruleSet].every((word) => words.has(word));\n}\n","import { appendFile, mkdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\n\n/**\n * Local usage traces for `codebuddy dashboard`: one JSON line per MCP tool\n * call, prompt recall, capture and sync, in `.codebuddy/cache/traces.jsonl`\n * (gitignored, never leaves the machine). Recording is best-effort: it never\n * throws and never blocks a tool or hook on failure. `CODEBUDDY_TRACE=0`\n * turns it off. Token counts are cl100k estimates of the payload text.\n */\n\nexport type TraceKind = \"tool\" | \"recall\" | \"capture\" | \"sync\";\n\nexport type TraceEvent = {\n ts: string;\n kind: TraceKind;\n /** Tool name, or the hook step (`context`, `capture`, `sync`). */\n name: string;\n ms: number;\n ok: boolean;\n /** Estimated tokens the agent sent (tool arguments, prompt). */\n tokensIn?: number;\n /** Estimated tokens CodeBuddy returned or injected. */\n tokensOut?: number;\n session?: string;\n detail?: Record<string, string | number | boolean | string[]>;\n};\n\n/** Past this size the oldest half is dropped (~10k events). */\nconst MAX_BYTES = 4 * 1024 * 1024;\n\nexport function tracePath(repositoryRoot: string): string {\n return join(repositoryRoot, \".codebuddy\", \"cache\", \"traces.jsonl\");\n}\n\nexport async function recordTrace(\n repositoryRoot: string,\n event: Omit<TraceEvent, \"ts\"> & { ts?: string },\n): Promise<void> {\n if (process.env.CODEBUDDY_TRACE === \"0\") return;\n const path = tracePath(repositoryRoot);\n try {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, `${JSON.stringify({ ts: new Date().toISOString(), ...event })}\\n`);\n if ((await stat(path)).size > MAX_BYTES) {\n const lines = (await readFile(path, \"utf8\")).split(\"\\n\").filter(Boolean);\n // Atomic: a reader (the dashboard) never sees a half-written file.\n await writeAtomic(path, `${lines.slice(Math.floor(lines.length / 2)).join(\"\\n\")}\\n`);\n }\n } catch {\n // Tracing must never break a tool call or a hook.\n }\n}\n\n/** The newest `limit` events, oldest first. Malformed lines are skipped. */\nexport async function readTraces(repositoryRoot: string, limit = 2_000): Promise<TraceEvent[]> {\n let raw: string;\n try {\n raw = await readFile(tracePath(repositoryRoot), \"utf8\");\n } catch {\n return [];\n }\n return parseTraceLines(raw).slice(-limit);\n}\n\nexport function parseTraceLines(raw: string): TraceEvent[] {\n const events: TraceEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line) as TraceEvent;\n if (typeof event.ts === \"string\" && typeof event.name === \"string\") events.push(event);\n } catch {\n // A torn write from a concurrent hook process; skip it.\n }\n }\n return events;\n}\n","import pTimeout from \"p-timeout\";\nimport type { ContextReranker, SemanticRelevanceRanker } from \"../context/engine.js\";\nimport { loadRuntimeConfig, readConfigFile } from \"../core/config-file.js\";\nimport type { RuntimeHandle } from \"../core/operations.js\";\nimport { DEFAULT_RERANK_MODELS } from \"../providers/models.js\";\n\n/**\n * The model side of per-prompt recall: dense evidence from PostgreSQL/pgvector,\n * the query embedded by the configured provider (local by default). Optional\n * and bounded: a slow or absent database or model leaves lexical recall intact.\n * `CODEBUDDY_SEMANTIC=0` turns it off (never connects to PostgreSQL).\n */\nexport type HookSemantics = {\n semanticRanker?: SemanticRelevanceRanker;\n reranker?: ContextReranker;\n close(): Promise<void>;\n};\n\n/** Connect + namespace lookup; a local PostgreSQL answers in milliseconds. */\nconst CONNECT_BUDGET_MS = 2_500;\n/** Query embedding + exact vector search (the first call also loads the model). */\nconst SEARCH_BUDGET_MS = 3_000;\nconst RERANK_BUDGET_MS = 2_000;\n\n/**\n * The cross-encoder chosen by `.codebuddy/config.json` `rerank` (off by\n * default). Hosted ones need OPENROUTER_API_KEY / HF_TOKEN; without a key\n * (or `CODEBUDDY_RERANK=0`) there is none and the fused order stands.\n */\nexport async function configuredReranker(\n repositoryRoot: string,\n): Promise<ContextReranker | undefined> {\n if (process.env.CODEBUDDY_RERANK === \"0\") return undefined;\n const file = await readConfigFile(repositoryRoot);\n const provider = file.rerank?.provider ?? \"off\";\n if (provider === \"off\") return undefined;\n const model = file.rerank?.model ?? DEFAULT_RERANK_MODELS[provider].id;\n const bounded = (scores: Promise<number[]>) =>\n pTimeout(scores, { milliseconds: RERANK_BUDGET_MS });\n if (provider === \"local\") {\n const revision =\n model === DEFAULT_RERANK_MODELS.local.id ? DEFAULT_RERANK_MODELS.local.revision : undefined;\n return async (task, documents) => {\n const { rerankLocally } = await import(\"../providers/local.js\");\n return bounded(\n rerankLocally({ id: model, ...(revision ? { revision } : {}) }, task, documents),\n );\n };\n }\n const apiKey =\n provider === \"openrouter\"\n ? process.env.OPENROUTER_API_KEY\n : (process.env.HF_TOKEN ?? file.provider?.apiKey);\n if (!apiKey) return undefined;\n const { rerankHuggingFace, rerankOpenRouter } = await import(\"../providers/cloud.js\");\n const call = provider === \"openrouter\" ? rerankOpenRouter : rerankHuggingFace;\n return (task, documents) => call({ apiKey, model, timeoutMs: RERANK_BUDGET_MS }, task, documents);\n}\n\nexport async function openHookSemantics(repositoryRoot: string): Promise<HookSemantics> {\n let runtime: Promise<RuntimeHandle | null> | null = null;\n const connect = async (): Promise<RuntimeHandle | null> => {\n const config = await loadRuntimeConfig(repositoryRoot, { requireDatabase: false });\n if (!config.postgresUrl) return null;\n const { createRuntime } = await import(\"../core/operations.js\");\n const opening = createRuntime(config, {\n repositoryRoot,\n startWorker: false,\n connectTimeoutSeconds: 2,\n });\n try {\n return await pTimeout(opening, { milliseconds: CONNECT_BUDGET_MS });\n } catch {\n // Too slow: release whatever eventually connects.\n void opening.then((handle) => handle.close()).catch(() => undefined);\n return null;\n }\n };\n\n const semanticRanker: SemanticRelevanceRanker | undefined =\n process.env.CODEBUDDY_SEMANTIC === \"0\"\n ? undefined\n : async (task, candidates) => {\n runtime ??= connect().catch(() => null);\n const handle = await runtime;\n if (!handle) return {};\n return handle.memory.rankContextFacts(\n task,\n candidates.map(({ id }) => id),\n { timeoutMs: SEARCH_BUDGET_MS },\n );\n };\n\n const reranker = await configuredReranker(repositoryRoot).catch(() => undefined);\n return {\n ...(semanticRanker ? { semanticRanker } : {}),\n ...(reranker ? { reranker } : {}),\n async close() {\n const handle = await runtime?.catch(() => null);\n await handle?.close().catch(() => undefined);\n },\n };\n}\n","import { mkdir, readFile, rename, rm, stat } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\n\n/**\n * Between the edit hook and the turn-end hook, CodeBuddy needs to remember which\n * files an agent actually changed. This staging store holds that set per session\n * under `.codebuddy/cache/hooks/` (rebuildable, local, gitignored). The turn-end\n * capture hook drains it, so capture works from the *real* change set rather\n * than a summary the model may or may not write.\n */\n/** The staging lock guards a few file writes; one older than this was abandoned. */\nconst STAGING_LOCK_STALE_MS = 10_000;\n\nexport class HookStagingStore {\n readonly directory: string;\n private operations = Promise.resolve();\n\n constructor(repositoryRoot = process.cwd()) {\n this.directory = join(resolve(repositoryRoot), \".codebuddy\", \"cache\", \"hooks\");\n }\n\n async add(sessionId: string, paths: string[]): Promise<void> {\n await this.serialize(async () => {\n const clean = paths.map(normalize).filter(Boolean);\n if (clean.length === 0) return;\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n await this.withFileLock(sessionId, async () => {\n const merged = [...new Set([...(await this.read(sessionId)), ...clean])].sort();\n await writeAtomic(\n this.filePath(sessionId),\n `${JSON.stringify({ paths: merged }, null, 2)}\\n`,\n );\n });\n });\n }\n\n async read(sessionId: string): Promise<string[]> {\n try {\n const parsed = JSON.parse(await readFile(this.filePath(sessionId), \"utf8\"));\n return Array.isArray(parsed?.paths)\n ? parsed.paths.filter((p: unknown) => typeof p === \"string\")\n : [];\n } catch {\n return [];\n }\n }\n\n /** Return the staged paths and clear them. */\n async drain(sessionId: string): Promise<string[]> {\n return this.serialize(async () => {\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n return this.withFileLock(sessionId, async () => {\n const path = this.filePath(sessionId);\n const draining = `${path}.${process.pid}.${Date.now()}.drain`;\n try {\n await rename(path, draining);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n try {\n const parsed = JSON.parse(await readFile(draining, \"utf8\"));\n return Array.isArray(parsed?.paths)\n ? parsed.paths.filter((item: unknown) => typeof item === \"string\")\n : [];\n } finally {\n await rm(draining, { force: true });\n }\n });\n });\n }\n\n /** Claim a batch without consuming edits staged while capture runs. */\n async claim(sessionId: string): Promise<string[] | null> {\n await mkdir(this.directory, { recursive: true, mode: 0o700 });\n const captureLock = `${this.filePath(sessionId)}.capture-lock`;\n for (let attempt = 0; ; attempt++) {\n try {\n await mkdir(captureLock);\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const age =\n Date.now() - (await stat(captureLock).catch(() => ({ mtimeMs: Date.now() }))).mtimeMs;\n if (age > 60_000) {\n await rm(captureLock, { recursive: true, force: true });\n continue;\n }\n if (attempt >= 200) return null;\n await new Promise((resolveWait) => setTimeout(resolveWait, 10));\n }\n }\n try {\n return await this.withFileLock(sessionId, async () => {\n const claimed = this.claimPath(sessionId);\n try {\n return parsePaths(await readFile(claimed, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n try {\n await rename(this.filePath(sessionId), claimed);\n return parsePaths(await readFile(claimed, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n });\n } catch (error) {\n await rm(captureLock, { recursive: true, force: true });\n throw error;\n }\n }\n\n /** Acknowledge only the claimed batch; later edits remain staged. */\n async acknowledge(sessionId: string): Promise<void> {\n await this.withFileLock(sessionId, async () => {\n await rm(this.claimPath(sessionId), { force: true });\n });\n await rm(`${this.filePath(sessionId)}.capture-lock`, { recursive: true, force: true });\n }\n\n /** Restore the claimed batch for retry, merging edits that arrived during capture. */\n async rollback(sessionId: string): Promise<void> {\n await this.withFileLock(sessionId, async () => {\n const claimed = await readFile(this.claimPath(sessionId), \"utf8\")\n .then(parsePaths)\n .catch(() => []);\n const merged = [...new Set([...claimed, ...(await this.read(sessionId))])].sort();\n if (merged.length > 0)\n await writeAtomic(\n this.filePath(sessionId),\n `${JSON.stringify({ paths: merged }, null, 2)}\\n`,\n );\n await rm(this.claimPath(sessionId), { force: true });\n });\n await rm(`${this.filePath(sessionId)}.capture-lock`, { recursive: true, force: true });\n }\n\n private claimPath(sessionId: string): string {\n return `${this.filePath(sessionId)}.claimed`;\n }\n\n private async withFileLock<T>(sessionId: string, operation: () => Promise<T>): Promise<T> {\n const lock = `${this.filePath(sessionId)}.lock`;\n for (let attempt = 0; ; attempt++) {\n try {\n await mkdir(lock);\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\" || attempt >= 200) throw error;\n // A hook killed while holding the lock (host timeout, crash) would\n // otherwise block this session's staging forever. Every operation\n // under it is a few file writes, so 10 s is certainly stale.\n const age = await stat(lock).then(\n (info) => Date.now() - info.mtimeMs,\n () => 0,\n );\n if (age > STAGING_LOCK_STALE_MS) {\n await rm(lock, { recursive: true, force: true });\n continue;\n }\n await new Promise((resolveWait) => setTimeout(resolveWait, 10));\n }\n }\n try {\n return await operation();\n } finally {\n await rm(lock, { recursive: true, force: true });\n }\n }\n\n private async serialize<T>(operation: () => Promise<T>): Promise<T> {\n const previous = this.operations;\n let release!: () => void;\n this.operations = new Promise<void>((resolveOperation) => {\n release = resolveOperation;\n });\n await previous;\n try {\n return await operation();\n } finally {\n release();\n }\n }\n\n private filePath(sessionId: string): string {\n const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, \"_\") || \"default\";\n return join(this.directory, `${safe}.json`);\n }\n}\n\nfunction normalize(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").trim();\n}\n\nfunction parsePaths(raw: string): string[] {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed?.paths)\n ? parsed.paths.filter((path: unknown): path is string => typeof path === \"string\")\n : [];\n}\n"],"mappings":"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","names":["mkdir","readFile","rm","stat","dirname","join","relative","resolve","sep","pTimeout","readFile","join","resolve","resolve","spawn","realpath","relative","resolve","sep","stat","resolve","readFile","join","parseYaml","z","resolve","realpath","sep","normalizePath","relative","runGit","spawn","mkdir","readdir","readFile","stat","dirname","join","relative","resolve","sep","parseYaml","stringifyYaml","z","z","resolve","join","normalizePath","dirname","mkdir","stringifyYaml","readFile","parseYaml","readdir","relative","sep","stat","LIMITS","resolve","fresh","join","hit","readFile","createHash","resolve","z","z","incident","mkdir","readdir","readFile","rm","dirname","join","relative","resolve","sep","parseYaml","stringifyYaml","z","z","resolve","join","dirname","stringifyYaml","readFile","parseYaml","readdir","rm","mkdir","relative","sep","words","resolve","ref","createHash","mkdir","readFile","stat","dirname","join","join","mkdir","dirname","stat","readFile","mkdir","readFile","rename","rm","stat","join","resolve","join","resolve","normalize","mkdir","readFile","rename","rm","stat","join","mkdir","dirname","rm","pTimeout","stat","resolve","relative","sep","readFile"]}
|