/** * 记忆引擎 **incident 席**在本仓的唯一落点形。 * * ## 为什么要一只共用工厂(而不是每个宿主各写一行 `logger.warn`) * core 的记忆引擎有**两条**到宿主的披露路: * · **mount 路**——`MemoryEngine` 自己的 `onIncident`,由 core 的 Runner 在 `prepare-memory` 里桥到 * `RunnerDeps.onError(err, { phase: "memory", sessionId })`(亲读 `dist/core/runner/prepare-memory.js` * 的 `const onEngineIncident = (err) => deps.onError?.(err, { phase: "memory", sessionId })`); * · **无锁公开面路**——`FileMemoryEngineBackend` 的**构造期** `onIncident`,是那条腿上唯一的披露口 * (`adoptLayoutLocked` 取 `onIncident ?? this.onIncident`)。 * 同一条事实(例如一次性的目录布局搬家)会按调用路径落到其中**一条**,而本仓有**两个宿主** * (HTTP 服务的 `boot/runner-deps.ts` 与 `run-local.ts`)各自持有 `onError` 座。四个落点各写一行 = * 四份会各自漂移的形;实际已经漂过一次:服务腿把整族印成 `memory_consolidation_failed`(只有一支是 * consolidation),run-local 腿把整族印成 `engine_error` 并用 `String(err)` 抹掉 `err.code`。 * * ## 形(一处定义,四处引用) * `memory_engine_incident` + `{ sessionId?, code, detail }`,并计 `memory_engine_incident_total{code}`。 * 🔴 `code` 是**结构化字段**而不是被折进散文:它是运维唯一能按名告警的那一位,而这一族里最要紧的几条 * (一次性布局搬家、无主根内容、控制面写失败)一辈子只发生一次 —— 折平就等于没说。无码的成员 * (core 里有大量不带 `.code` 的记忆相 Error)落 `null` / 计数标签 `"none"`,**不编**一个码。 * * ⚠️ 与 `main.ts` 三只 **operator 面**引擎座(`memory_compliance_incident` / `memory_origin_incident` / * `memory_consolidation_incident`)**刻意不合并**:那三条的事件名回答「哪一张操作面」,是三个产品面的 * 分辨位;本工厂回答「引擎事故席」,是同一件事的四个落点。合并会丢掉前者的分辨位。 */ import type { Logger } from "./observability/logger.js"; import type { Metrics } from "./observability/metrics.js"; /** 落点依赖。`metrics` 可缺席(run-local 的 backend 构造期座就没有计数面的消费者)。 */ export interface MemoryEngineIncidentSinkDeps { logger: Pick; metrics?: Pick; } /** 命名照工厂律:返回的是**带行为的闭包** ⇒ `create*`。 */ export declare function createMemoryEngineIncidentSink(deps: MemoryEngineIncidentSinkDeps): (err: unknown, ctx?: { sessionId?: string; }) => void; //# sourceMappingURL=memory-incident-sink.d.ts.map