M2: 基座能力 —— memory / toolbox / channel / message

- memory   任务记忆四性质(只追加·信封盖戳·治理先行·归侧)、活动记忆四层与条目三件套、
           任务日志两级投影(结构化零 LLM / 叙述性小结不入事实库)、度量八指标只读投影
- toolbox  注册两审(静态审 + 试运行审)、效应等级决定运行时待遇、契约演进只增不破坏、
           白名单与纯工具私有作用域、ToolInvoker(两缝之二,live/record/replay)
- channel  通道实例配置、入站归一(解析 → 系统写 → 数据事件)、出站发送与关联记录登记
- message  通知 / 跨任务征答(就地作答 · 驳回重答只增不改)/ 死信 / 无主兜底

app:message 接上 event 的 MessageFallback;派发器按目标 ID 取 advisory lock 串行消费 +
消费幂等表;/api/ingest 模拟邮件通道(mock 只在外界)

已验证:无主 RFQ 邮件入站 → 归属解析 no-match → 事件落库 → 兜底落 OP 岗位的消息要素
门禁五道全绿;150 个单元测试 + 1 个 PG 集成测试

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
JCAI Main Agent
2026-07-27 01:16:52 +08:00
co-authored by Claude Opus 5
parent 14d4fa046a
commit f0444f1417
73 changed files with 7488 additions and 31 deletions
+109
View File
@@ -0,0 +1,109 @@
/**
* module: toolbox —— 对外类型(编码规范 §10.1)。
*
* 两条缝之二(§7.3):`ToolInvoker` 支持 record | replay | live ——
* **任何工具执行不经 ToolInvoker,回放审就对它失明**(§12.5#10)。
*/
import type { ActionIntent, TaskId } from '@contracts';
import type { AuditFinding } from './internal/domain/registration-audit.ts';
import type { CallDisposition, EffectLevel, EvolutionViolation, Preauthorization, ToolContract } from './internal/domain/tool-contract.ts';
export type { ActionIntent, AuditFinding, CallDisposition, EffectLevel, EvolutionViolation, Preauthorization, ToolContract };
export declare const INVOKER_MODES: readonly ["live", "record", "replay"];
export type InvokerMode = (typeof INVOKER_MODES)[number];
export declare class ToolNotFoundError extends Error {
readonly tool: string;
constructor(tool: string);
}
export declare class ToolNotAllowedError extends Error {
readonly tool: string;
readonly activityId: string;
constructor(tool: string, activityId: string);
}
export declare class ToolDisabledError extends Error {
readonly tool: string;
constructor(tool: string);
}
export declare class ToolReplayMissError extends Error {
readonly key: string;
constructor(key: string);
}
export declare class RegistrationRejectedError extends Error {
readonly findings: readonly AuditFinding[];
constructor(findings: readonly AuditFinding[]);
}
export type ToolCall = {
readonly tool: string;
readonly operation?: string;
readonly input: Record<string, unknown>;
readonly activityId: string;
readonly taskId?: TaskId;
readonly stepNo?: number;
};
export type ToolResult = {
readonly ok: boolean;
readonly output?: Record<string, unknown>;
readonly error?: {
readonly code: string;
readonly retryable: boolean;
readonly message: string;
};
readonly latencyMs: number;
readonly mode: InvokerMode;
};
/** 调用留痕:入参快照、出参、时延与错误自动留痕入任务记忆(OS 7.3) */
export type InvocationTrace = {
readonly tool: string;
readonly input: Record<string, unknown>;
readonly result: ToolResult;
readonly at: string;
};
/**
* 工具调用器 —— 活动基座六件里的「工具(调用契约)」。
* **读类**过程中自由调用;**写类**登记为动作意向,放行后落地(除契约显式预授权者)。
*/
export type ToolInvoker = {
readonly mode: InvokerMode;
/** 判定运行时待遇 —— 调用方据此决定是即调还是登记意向 */
disposition(call: ToolCall, preauthorized: readonly Preauthorization[]): Promise<CallDisposition>;
invoke(call: ToolCall): Promise<ToolResult>;
/** 落地预检第四项:工具契约含 validate 能力时调之(ADR-005) */
validate(call: ToolCall): Promise<ToolResult | undefined>;
withMode(mode: InvokerMode): ToolInvoker;
};
export type RegisterToolInput = {
readonly contract: ToolContract;
/** 契约测试集:样例入参 → 期望出参形状;试运行审的依据 */
readonly samples: ReadonlyArray<{
input: Record<string, unknown>;
expectShape: Record<string, unknown>;
}>;
/** 连接配置的值 —— 只存治理台,加密落库(ADR-009) */
readonly connectionValues?: Readonly<Record<string, string>>;
};
export type RegistrationVerdict = {
readonly accepted: boolean;
readonly staticFindings: readonly AuditFinding[];
readonly evolution: readonly EvolutionViolation[];
readonly trialRun: {
readonly ran: number;
readonly passed: number;
readonly failures: readonly string[];
};
};
export type ToolboxService = {
/** 注册两审:静态审读清单,试运行审验代码 */
register(input: RegisterToolInput): Promise<RegistrationVerdict>;
list(): Promise<ToolContract[]>;
get(name: string): Promise<ToolContract | undefined>;
/** 有活动声明引用的工具不得删除;可停用 —— 停用后调用返回结构化错误 */
setEnabled(name: string, enabled: boolean): Promise<void>;
bindConnection(name: string, values: Readonly<Record<string, string>>): Promise<void>;
/** 白名单:活动只经调用契约用工具,授权在白名单与契约,不在活动代码 */
setAllowlist(activityId: string, tools: readonly string[]): Promise<void>;
allowlistOf(activityId: string): Promise<string[]>;
/** 安装静态审:活动声明的工具契约齐备?装不齐不上架 */
assertContractsAvailable(names: readonly string[]): Promise<{
ok: boolean;
missing: string[];
}>;
};