This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BPOS-TMP-REPO/api-report/apps/api/src/modules/interaction/port.d.ts
T
JCAI Main AgentandClaude Opus 5 2850e6d4ef M3(完成): interaction 与 activity-registry
interaction(L3):
- 控制权按态转交:活动在跑归活动,流转/审批/终态归系统;输入侧永远归系统(单入口)
- 视图区净化门:含 <script> / on* / 外部资源的模版一律拒推 —— 容器无脚本执行权
- 对话流单入口:自由输入同写任务记忆并抛人事件;SSE 单连接 + 按目标失效广播
- 前端零过程状态:对话流与视图都是服务端投影

activity-registry(L4):
- 安装两审:静态审(签名/SDK/工具契约齐备/模型名已绑定/schema/悬空监听/模版无脚本/
  零环境能力/动态执行/验收等级不得谎报)+ 回放审(旧成不坏是硬门,旧败能成只入报告)
- 资产与包分离版本化:包只携资产初始版,不覆盖已有更高资产版;装载 = 包版本 + 生效资产版
- 进化管线状态机:候选 → 回放 → 人放行 → 生效;回退是显式治理动作

245 个测试通过,门禁五道全绿

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 01:36:05 +08:00

43 lines
1.4 KiB
TypeScript

/**
* module: interaction —— 本模块要外界提供的能力(编码规范 §10.1 / §5.3)。
*/
import type { ChatMessage, StaffId, TaskId, ViewBlock } from '@contracts';
import type { InteractionPhase } from './internal/domain/control-handover.ts';
export type Clock = {
now(): Date;
};
export type IdGenerator = {
next(): string;
};
export type InteractionStore = {
appendMessage(taskId: TaskId, message: ChatMessage): Promise<void>;
listMessages(taskId: TaskId): Promise<ChatMessage[]>;
putView(taskId: TaskId, view: {
blocks?: readonly ViewBlock[];
html?: string;
}): Promise<void>;
setPhase(taskId: TaskId, phase: InteractionPhase): Promise<void>;
phaseOf(taskId: TaskId): Promise<InteractionPhase | undefined>;
};
/** 自由输入即人事件 —— app 注入 `event`(L1) */
export type HumanEventPublisher = {
publishHumanEvent(input: {
taskId: TaskId;
cardId: string;
payload: Record<string, unknown>;
}): Promise<void>;
};
/** 留痕 —— app 注入 `memory`(L2):时间线即任务记忆的可读投影 */
export type MemoryRecorder = {
append(input: {
taskId: TaskId;
kind: 'human-input';
title: string;
detail?: Record<string, unknown>;
}): Promise<void>;
};
/** 收件人解析 —— app 注入 `org`(L1):SSE 只推给有权看的人 */
export type Audience = {
canSee(staffId: StaffId, taskId: TaskId): Promise<boolean>;
};