AIDAWORK / SEQUENCE

交互卡内核结算与 Outbox 唤醒:从两阶段 Settle 到原载体精确续跑

独立图页 ↗
机制说明(SoT)图是辅读 · 结论以说明与证据为准

Interaction 定义 pending、resolved、cancelled、expired、failed。一次 settlement attempt 有独立状态,所以提交失败或重试不能直接解释为整个 Interaction 重开。客户端携带版本提交,服务端校验当前权威状态。

本页可直接往下读完整机制说明,不需要「演示 / 播放故事」。术语不熟先看 术语表。

先读机制说明,结论以说明与证据为准 · 基于固定代码版本核验 · 部署状态另行确认

机制说明(全文)

Interaction:提交、结算与续跑

从用户提交到恢复执行

Interaction 定义 pending、resolved、cancelled、expired、failed。一次 settlement attempt 有独立状态,所以提交失败或重试不能直接解释为整个 Interaction 重开。客户端携带版本提交,服务端校验当前权威状态。

accepted 的关键是把 settlement 与持久化 resume intent 交接起来,再由 owner 恢复执行。终态不可重开。桌面上的输入草稿、按钮位置和收件箱展示只影响交互体验,不拥有业务迁移权。Business effect batch 保留一次明确业务意图下的有界成员集合:根 ActionProposal 保存范围,Interaction 只结算这一份授权;成员 proposal 不是可独立发现的待授权请求,也不是第二个 Interaction Kernel。

材料全家桶(Save As / batch / critical-fields / inbox vs Kernel / 聊天附件):见 ../interaction-materials/NOTES.md。

Interaction Protocol v2 ↔ Local File V5 附件交接

  • 前置:migration 113(conversation_interactions.protocol_version IN (1,2),schema identity interaction-protocol-v2)是 mig 114(对话级附件列)的硬前置;114 再前置 115。附件 schema 升级叠在 Interaction v2 清仓之后,不是并行无关变更。
  • 附件 vs Interaction:对话附件走 chat 提交路径——chat-submission-store 在同一事务写入 user message 后 LocalFileMessageAttachmentStore.insertSubmitted;后续 run 组装用 listForConversation(ADR-0079)。这是 conversation/message relation + operation ledger,不是 Interaction Kernel 的 settlement 对象。
  • 交叉点:Local File 的 Save As / change authorize 以 Interaction producer 注册(local_file_save_as、local_file_change 类),kind 如 local_file_save_as_v4;它们挂在 Kernel protocol v2 上,与「对话级 path-free 附件行」分层——前者是人机门/材料收集,后者是聊天上下文里的 folder/file relation。
  • 协议门:Interaction API 用头 Aida-Interaction-Protocol-Version;未接受则 426 interaction_protocol_upgrade_required。Desktop 协议 v3 的 426 DESKTOP_UPGRADE_REQUIRED 是另一扇门(见 desktop-runtime);Interaction Kernel 协议仍是 2,与 Desktop 协议 3 互不相干。

钉点:aida-agent e2adc9a3c325a258a88d68103de87e6630a3b676。

业务复核卡改由后台 owner 执行(2026-10-14 钉点)

business_effect / business_progress 加入 BACKGROUND_OWNED_RESUME_BINDINGS:结算后由后台 owner 经 dispatchExact 立即执行,响应 transport=background;此前继承 attended_stream,需等 outbox 周期 drain(≤60s),点卡片与打字确认两条路径不一致(ADR-0089)。

卡过期后原任务怎么收口(钉点 Agent e2adc9a3c325 · Desktop 8eecd12081db)

expired 是 Interaction 终态,但它等着的那个任务树原来会一直挂着。现在两端各有收口:Agent 在新消息受理时(以及会话 lease 恢复,只限 legacy)关闭「只等过期卡」的任务树,判定 fail-closed;Desktop 的过期卡提供「结束原任务」,只停这张卡绑定的原始 Root(Runtime Work 走 Main 持久 Stop,legacy 沿用 cancel),对话已被别的工作占用时不停任何任务。细节见 state-authority 与 desktop-client。

四表结算与 Outbox 精确唤醒微追踪(视图 kernel-settlement-outbox)

当模型调用 ask_user / plugin_view / file_access / route_clarification 挂起载体后,用户点击卡片提交答复的完整 4 表状态机流转如下(见视图 kernel-settlement-outbox):

阶段 核心函数与 SQL 表 状态跳变与不变量校验
1. 策略校验与 Begin InteractionKernel.settle (kernel.ts L776–821) → store.beginSettlement 1) 解析 actorDecision(若为 client_resource 或 local_file_access 则额外调 isVerifiedClientResourceSettlement 验签);<br>2) conversation_interactions 必须处于 lifecycle_status = 'pending',插入 conversation_interaction_settlement_attempts (attempt_status = 'submitting', interaction_version = v, payload_hash);<br>3) 若交互已非 pending,alreadyWritten 检查最近一条 accepted attempt 是否同 actorRef + 同 payloadHash,命中则返回 status: 'duplicate' 幂等放行。
2. 领域验证与 Complete validateSubmittedAnswerWithDeadline + authorityCoordinator.verify → store.completeSettlement (kernel.ts L828–874) 1) 校验 resolution.actorPolicyVersion === actorDecision.policyVersion;<br>2) 在同一事务中将 conversation_interactions 推进至 lifecycle_status = 'resolved', version = v + 1,将 conversation_interaction_settlement_attempts 置为 attempt_status = 'accepted';<br>3) 同时写入 conversation_interaction_resume_commands(command_id = attempt_id, owner_kind = 'runtime_work_activation', status = 'pending', 冻结 destination)与 conversation_interaction_outbox。
3. 冻结目的地 3 表 Join 唤醒 activateRuntimeWorkFromAcceptedSettlement (run-work-control.ts L3398–3583) 1) lockRoot 下执行 3 表 Join(conversation_interaction_resume_commands c ⋈ conversation_interaction_settlement_attempts a ⋈ conversation_interactions i);<br>2) 强制校验五项铁律:a.attempt_status === 'accepted'、i.lifecycle_status === 'resolved'、a.interaction_version + 1 === i.version(严防过期修订覆盖)、canonicalJsonSha256(i.envelope.resumeDestinationBinding) === canonicalJsonSha256({kind, rootRunId, targetPosition})(创建时冻结的目的地必须与结算时一致)、以及 run_checkpoints.pending_interaction_id === interactionId;<br>3) 调 settleRuntimeWorkInteractionInTx 写入交互结算消息并更新 message_cursor_id;将 agent_runs 置为 status = 'pending'、runtime_invocations 置为 'pending'、run_checkpoints 置为 `status = 'active', resume_point = 'settlement:<settlementId>'
4. 死信与失败隔离 recoverRuntimeWorkChildInteraction (run-work-control.ts L3283–3389) 若子交互唤醒遭遇永久错误或重试耗尽,在 lockRoot 下同步关闭 conversation_interaction_resume_commands 与 conversation_interaction_outbox(均置 dead_letter),防止崩溃重启后死信复活。

证据与范围

  • aida-agent · packages/agent/src/shared/interaction-kernel-state.ts L11–41 · INTERACTION_STATUSES · e2adc9a3c325

  • aida-agent · docs/architecture/lifecycle-map.md L42–98 · e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)

  • aida-agent · docs/architecture/lifecycle-map.md L110–198 · e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)

  • aida-agent · packages/agent/src/shared/interaction-kernel-state.ts L137–157 · e2adc9a3c325

  • aida-agent · packages/agent/src/session/chat-submission-store.ts L541–556 · closeRunsWaitingOnlyOnExpiredInteractions · e2adc9a3c325

  • aida-desktop · apps/desktop/src/chat/interaction-workbench/endOriginalWork.ts L33–74 · endOriginalWorkForExpiredCard · 4346d79eb364

  • aida-agent · CONTEXT.md L858–863 · Business effect batch · e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)

  • aida-agent · packages/agent/src/runtime/continuation/interaction-delivery-mode.ts L1–13 · business_effect · e2adc9a3c325

  • aida-agent · packages/agent/src/interaction-kernel/contract.ts L24–54 · CONVERSATION_INTERACTION_PROTOCOL_VERSION · e2adc9a3c325

  • aida-agent · packages/agent/migrations/113_interaction_protocol_v2.sql L1–28 · 113 · e2adc9a3c325

  • aida-agent · packages/agent/migrations/114_local_file_v5_conversation_attachments.sql L1–8 · 114 · e2adc9a3c325

  • aida-agent · packages/agent/src/session/chat-submission-store.ts L1742–1782 · insertSubmitted · e2adc9a3c325

  • aida-agent · packages/agent/src/interaction-kernel/producer-inventory.ts L17–47 · local_file_save_as · e2adc9a3c325

结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。

机制说明

Interaction:提交、结算与续跑

从用户提交到恢复执行

Interaction 定义 pending、resolved、cancelled、expired、failed。一次 settlement attempt 有独立状态,所以提交失败或重试不能直接解释为整个 Interaction 重开。客户端携带版本提交,服务端校验当前权威状态。

accepted 的关键是把 settlement 与持久化 resume intent 交接起来,再由 owner 恢复执行。终态不可重开。桌面上的输入草稿、按钮位置和收件箱展示只影响交互体验,不拥有业务迁移权。Business effect batch 保留一次明确业务意图下的有界成员集合:根 ActionProposal 保存范围,Interaction 只结算这一份授权;成员 proposal 不是可独立发现的待授权请求,也不是第二个 Interaction Kernel。

材料全家桶(Save As / batch / critical-fields / inbox vs Kernel / 聊天附件):见 ../interaction-materials/NOTES.md。

Interaction Protocol v2 ↔ Local File V5 附件交接

  • 前置:migration 113(conversation_interactions.protocol_version IN (1,2),schema identity interaction-protocol-v2)是 mig 114(对话级附件列)的硬前置;114 再前置 115。附件 schema 升级叠在 Interaction v2 清仓之后,不是并行无关变更。
  • 附件 vs Interaction:对话附件走 chat 提交路径——chat-submission-store 在同一事务写入 user message 后 LocalFileMessageAttachmentStore.insertSubmitted;后续 run 组装用 listForConversation(ADR-0079)。这是 conversation/message relation + operation ledger,不是 Interaction Kernel 的 settlement 对象。
  • 交叉点:Local File 的 Save As / change authorize 以 Interaction producer 注册(local_file_save_as、local_file_change 类),kind 如 local_file_save_as_v4;它们挂在 Kernel protocol v2 上,与「对话级 path-free 附件行」分层——前者是人机门/材料收集,后者是聊天上下文里的 folder/file relation。
  • 协议门:Interaction API 用头 Aida-Interaction-Protocol-Version;未接受则 426 interaction_protocol_upgrade_required。Desktop 协议 v3 的 426 DESKTOP_UPGRADE_REQUIRED 是另一扇门(见 desktop-runtime);Interaction Kernel 协议仍是 2,与 Desktop 协议 3 互不相干。

钉点:aida-agent e2adc9a3c325a258a88d68103de87e6630a3b676。

业务复核卡改由后台 owner 执行(2026-10-14 钉点)

business_effect / business_progress 加入 BACKGROUND_OWNED_RESUME_BINDINGS:结算后由后台 owner 经 dispatchExact 立即执行,响应 transport=background;此前继承 attended_stream,需等 outbox 周期 drain(≤60s),点卡片与打字确认两条路径不一致(ADR-0089)。

卡过期后原任务怎么收口(钉点 Agent e2adc9a3c325 · Desktop 8eecd12081db)

expired 是 Interaction 终态,但它等着的那个任务树原来会一直挂着。现在两端各有收口:Agent 在新消息受理时(以及会话 lease 恢复,只限 legacy)关闭「只等过期卡」的任务树,判定 fail-closed;Desktop 的过期卡提供「结束原任务」,只停这张卡绑定的原始 Root(Runtime Work 走 Main 持久 Stop,legacy 沿用 cancel),对话已被别的工作占用时不停任何任务。细节见 state-authority 与 desktop-client。

四表结算与 Outbox 精确唤醒微追踪(视图 kernel-settlement-outbox)

当模型调用 ask_user / plugin_view / file_access / route_clarification 挂起载体后,用户点击卡片提交答复的完整 4 表状态机流转如下(见视图 kernel-settlement-outbox):

阶段 核心函数与 SQL 表 状态跳变与不变量校验
1. 策略校验与 Begin InteractionKernel.settle (kernel.ts L776–821) → store.beginSettlement 1) 解析 actorDecision(若为 client_resource 或 local_file_access 则额外调 isVerifiedClientResourceSettlement 验签);<br>2) conversation_interactions 必须处于 lifecycle_status = 'pending',插入 conversation_interaction_settlement_attempts (attempt_status = 'submitting', interaction_version = v, payload_hash);<br>3) 若交互已非 pending,alreadyWritten 检查最近一条 accepted attempt 是否同 actorRef + 同 payloadHash,命中则返回 status: 'duplicate' 幂等放行。
2. 领域验证与 Complete validateSubmittedAnswerWithDeadline + authorityCoordinator.verify → store.completeSettlement (kernel.ts L828–874) 1) 校验 resolution.actorPolicyVersion === actorDecision.policyVersion;<br>2) 在同一事务中将 conversation_interactions 推进至 lifecycle_status = 'resolved', version = v + 1,将 conversation_interaction_settlement_attempts 置为 attempt_status = 'accepted';<br>3) 同时写入 conversation_interaction_resume_commands(command_id = attempt_id, owner_kind = 'runtime_work_activation', status = 'pending', 冻结 destination)与 conversation_interaction_outbox。
3. 冻结目的地 3 表 Join 唤醒 activateRuntimeWorkFromAcceptedSettlement (run-work-control.ts L3398–3583) 1) lockRoot 下执行 3 表 Join(conversation_interaction_resume_commands c ⋈ conversation_interaction_settlement_attempts a ⋈ conversation_interactions i);<br>2) 强制校验五项铁律:a.attempt_status === 'accepted'、i.lifecycle_status === 'resolved'、a.interaction_version + 1 === i.version(严防过期修订覆盖)、canonicalJsonSha256(i.envelope.resumeDestinationBinding) === canonicalJsonSha256({kind, rootRunId, targetPosition})(创建时冻结的目的地必须与结算时一致)、以及 run_checkpoints.pending_interaction_id === interactionId;<br>3) 调 settleRuntimeWorkInteractionInTx 写入交互结算消息并更新 message_cursor_id;将 agent_runs 置为 status = 'pending'、runtime_invocations 置为 'pending'、run_checkpoints 置为 `status = 'active', resume_point = 'settlement:<settlementId>'
4. 死信与失败隔离 recoverRuntimeWorkChildInteraction (run-work-control.ts L3283–3389) 若子交互唤醒遭遇永久错误或重试耗尽,在 lockRoot 下同步关闭 conversation_interaction_resume_commands 与 conversation_interaction_outbox(均置 dead_letter),防止崩溃重启后死信复活。

证据与范围

  • aida-agent · packages/agent/src/shared/interaction-kernel-state.ts L11–41 · INTERACTION_STATUSES · e2adc9a3c325

  • aida-agent · docs/architecture/lifecycle-map.md L42–98 · e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)

  • aida-agent · docs/architecture/lifecycle-map.md L110–198 · e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)

  • aida-agent · packages/agent/src/shared/interaction-kernel-state.ts L137–157 · e2adc9a3c325

  • aida-agent · packages/agent/src/session/chat-submission-store.ts L541–556 · closeRunsWaitingOnlyOnExpiredInteractions · e2adc9a3c325

  • aida-desktop · apps/desktop/src/chat/interaction-workbench/endOriginalWork.ts L33–74 · endOriginalWorkForExpiredCard · 4346d79eb364

  • aida-agent · CONTEXT.md L858–863 · Business effect batch · e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)

  • aida-agent · packages/agent/src/runtime/continuation/interaction-delivery-mode.ts L1–13 · business_effect · e2adc9a3c325

  • aida-agent · packages/agent/src/interaction-kernel/contract.ts L24–54 · CONVERSATION_INTERACTION_PROTOCOL_VERSION · e2adc9a3c325

  • aida-agent · packages/agent/migrations/113_interaction_protocol_v2.sql L1–28 · 113 · e2adc9a3c325

  • aida-agent · packages/agent/migrations/114_local_file_v5_conversation_attachments.sql L1–8 · 114 · e2adc9a3c325

  • aida-agent · packages/agent/src/session/chat-submission-store.ts L1742–1782 · insertSubmitted · e2adc9a3c325

  • aida-agent · packages/agent/src/interaction-kernel/producer-inventory.ts L17–47 · local_file_save_as · e2adc9a3c325

结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。

代码证据

引用核验检查固定 commit 的文件与范围;实现结论来自代码阅读。自动检查不证明生产环境已启用。

已核验实现

Interaction 的 pending / resolved / cancelled / expired / failed 与 attempt 五态分别定义。

aida-agentpackages/agent/src/shared/interaction-kernel-state.ts:11–417f2e519936b57902d4907ed8026fe1ecdd146e82符号:INTERACTION_STATUSES
已核验实现

客户端提交带版本 settlement,终态不可重开;accepted 通过持久化 resume intent 交接给 owner。

aida-agentpackages/agent/src/shared/interaction-kernel-state.ts:11–417f2e519936b57902d4907ed8026fe1ecdd146e82符号:INTERACTION_STATUSES
aida-agentpackages/agent/src/shared/interaction-kernel-state.ts:11–417f2e519936b57902d4907ed8026fe1ecdd146e82符号:INTERACTION_STATUSES
已核验实现

UI 草稿与展示位置不会成为业务状态迁移权威。

aida-agentpackages/agent/src/shared/interaction-kernel-state.ts:11–417f2e519936b57902d4907ed8026fe1ecdd146e82符号:INTERACTION_STATUSES
aida-agentpackages/agent/src/shared/interaction-kernel-state.ts:137–1577f2e519936b57902d4907ed8026fe1ecdd146e82
已核验实现

Business effect batch 是同一业务意图下的有界变更集合:根 ActionProposal 保存成员范围,Conversation Interaction 只结算这一份授权;成员 proposal 不是可独立发现的待授权请求,也不是第二个 Interaction Kernel。

aida-agentGLOSSARY.md:832–8377f2e519936b57902d4907ed8026fe1ecdd146e82符号:Business effect batch
已核验实现

Migration 113 (Interaction protocol v2) is the schema prerequisite for migration 114 (Local File V5 conversation attachments); Kernel CONVERSATION_INTERACTION_PROTOCOL_VERSION=2; conversation attachments are written by chat-submission-store.insertSubmitted, not Interaction settlement.

aida-agentpackages/agent/migrations/113_interaction_protocol_v2.sql:12–317f2e519936b57902d4907ed8026fe1ecdd146e82符号:interaction-protocol-v2
aida-agentpackages/agent/migrations/114_local_file_v5_conversation_attachments.sql:2–327f2e519936b57902d4907ed8026fe1ecdd146e82符号:113
aida-agentpackages/agent/src/session/chat-submission-store.ts:1762–17927f2e519936b57902d4907ed8026fe1ecdd146e82符号:insertSubmitted
aida-agentpackages/agent/src/interaction-kernel/contract.ts:2–327f2e519936b57902d4907ed8026fe1ecdd146e82符号:CONVERSATION_INTERACTION_PROTOCOL_VERSION
已核验实现

Local File Save As registers Interaction producer local_file_save_as on protocol v2, layered separately from conversation path-free attachment relations.

aida-agentpackages/agent/src/interaction-kernel/producer-inventory.ts:107–1377f2e519936b57902d4907ed8026fe1ecdd146e82符号:local_file_save_as
aida-agentpackages/agent/src/runtime/local/local-file-v4-tool.ts:1127–11587f2e519936b57902d4907ed8026fe1ecdd146e82符号:local_file_save_as_v4
已核验实现

业务复核卡(business_effect / business_progress)与 runtime_work_activation、local_file_change 同属 BACKGROUND_OWNED_RESUME_BINDINGS:结算后由后台 owner 经 dispatchExact 立即执行,响应 transport=background,不再依赖对话流或 outbox 周期 drain(ADR-0089)。

aida-agentpackages/agent/src/runtime/continuation/interaction-delivery-mode.ts:1–137f2e519936b57902d4907ed8026fe1ecdd146e82符号:business_effect
已核验实现

卡过期后原任务的收口分两端:Agent 在新消息受理(及会话 lease 恢复,只限 legacy)时关闭只等过期卡的任务树;Desktop 过期卡提供「结束原任务」,只针对该卡绑定的原始 rootRunId——先读服务端 active-run 视图,Runtime Work 由 Main 持久 Stop(与输入框 Stop 同一提交身份),legacy run 得到 426 时沿用服务端 cancel;当前对话已被别的工作占用则不停任何任务。

aida-agentpackages/agent/src/session/chat-submission-store.ts:955–9707f2e519936b57902d4907ed8026fe1ecdd146e82符号:closeRunsWaitingOnlyOnExpiredInteractions
aida-agentpackages/agent/src/session/run-store.ts:2060–20717f2e519936b57902d4907ed8026fe1ecdd146e82符号:closeRunsWaitingOnlyOnExpiredInteractions
aida-desktopapps/desktop/src/chat/interaction-workbench/endOriginalWork.ts:51–924346d79eb36402355e51118df0edf1f98586880c符号:endOriginalWorkForExpiredCard