Mastra 化前置:loop 三修 —— 提交放行发真验收卡、事件只记不跑、轨迹喂回叙事面

勘察(两路 code-explorer)坐实 loop 范式三处真缺口,本轮先修(用户拍板),
与 Mastra 化解耦、按外科手术做(活动内 MVP 期高内聚不过度抽象):

① 提交放行走不到 released:submit/判齐只返回 submitted,task 层当 running
  处理,任务原地重跑到预算耗尽(exhausted 而非 released)。
  修:提交 = 发**验收卡**挂起等裁决(raiseAcceptance 唯一出口:发卡、立监听、
  在途验收入状态信封 sys.loop_state.pending,迁移 0015);判齐重入不发第二张卡;
  裁决 pass → finished released(选口随放行带回),reject → finished 不放行。
  TurnOutcome 增 finished/released/selectedPorts,engines 接线透传。

② onEvent 双拍:自跑一整拍后 deliver 的 tick 再跑一拍 —— 每次人卡回传多耗
  一次不计 steps/activeMs 预算的模型决策。修:onEvent **只记不跑**
  (登记 occur / 收验收裁决入信封,存快照即返),推进统一归 tick,预算一个口径。

③ Agent 每拍失忆:memory.window 定义了但零调用,任务自身轨迹从不喂回 prompt。
  修:叙事面新增【本任务最近轨迹】段,窗口大小取活动声明的
  manifest.declarations.harness.memoryWindow(活动侧唯一记忆配置,不再硬编码)。

测试:turn-runner-acceptance 八例;全量绿,五闸退出码过;loop CONTRACT.md 同步。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
2026-07-28 23:02:41 +08:00
co-authored by Claude Fable 5
parent 967627d753
commit 1917320584
12 changed files with 340 additions and 28 deletions
+22 -2
View File
@@ -10,8 +10,16 @@ export type Clock = { now(): Date };
/** 运行时实例状态 —— loop 的模型定位与就绪集(OS 09 三份持久状态之一) */
export type LoopStateStore = {
save(taskId: TaskId, model: LoopModel, parsed: CaseModel, runtime: CaseRuntime): Promise<void>;
load(taskId: TaskId): Promise<{ model: LoopModel; parsed: CaseModel; runtime: CaseRuntime } | undefined>;
save(
taskId: TaskId,
model: LoopModel,
parsed: CaseModel,
runtime: CaseRuntime,
pending?: PendingAcceptance | null,
): Promise<void>;
load(
taskId: TaskId,
): Promise<{ model: LoopModel; parsed: CaseModel; runtime: CaseRuntime; pending?: PendingAcceptance } | undefined>;
};
/** S-FEEL —— app 注入 `@sfeel`;引擎零 LLM */
@@ -58,6 +66,16 @@ export type ToolGateway = {
registerIntent(input: { taskId: TaskId; tool: string; input: Record<string, unknown>; label: string }): Promise<void>;
};
/**
* 在途验收(提交放行的持久痕):卡发出即记,裁决到达再记 verdict ——
* 判齐重入不再发第二张卡;恢复的那一拍据 verdict 定终局(released 与否)。
*/
export type PendingAcceptance = {
readonly acceptanceCardId: string;
readonly verdict?: 'pass' | 'reject';
readonly selectedPorts?: Record<string, string>;
};
export type CardGateway = {
issue(input: {
taskId: TaskId;
@@ -112,6 +130,8 @@ export type MemoryRecorder = {
}): Promise<void>;
/** 装载:按定位选摘活动记忆入 Agent 上下文(渐进披露) */
loadActivityMemory(activityId: string, limit: number): Promise<Array<{ layer: string; statement: string }>>;
/** 本任务自己的最近轨迹(窗口大小由活动声明的 memoryWindow 定)—— 喂回叙事面,Agent 每拍不失忆 */
window(taskId: TaskId): Promise<Array<{ kind: string; title: string }>>;
};
export type TaskContext = {