create-windy 0.6.14 → 0.6.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/cli.js +1008 -61
  2. package/package.json +1 -1
  3. package/template/.agents/skills/windy-business-module/SKILL.md +58 -8
  4. package/template/.windy-template.json +2 -2
  5. package/template/apps/server/src/agent/client-session/attempt-authority.test.ts +162 -0
  6. package/template/apps/server/src/agent/client-session/attempt-authority.ts +191 -0
  7. package/template/apps/server/src/agent/client-session/bootstrap.ts +27 -11
  8. package/template/apps/server/src/agent/client-session/completion.ts +75 -24
  9. package/template/apps/server/src/agent/client-session/contracts.ts +23 -0
  10. package/template/apps/server/src/agent/client-session/creation.ts +103 -0
  11. package/template/apps/server/src/agent/client-session/digest.ts +11 -1
  12. package/template/apps/server/src/agent/client-session/drizzle-records.ts +150 -0
  13. package/template/apps/server/src/agent/client-session/drizzle-repository.integration.test.ts +30 -3
  14. package/template/apps/server/src/agent/client-session/drizzle-repository.ts +23 -132
  15. package/template/apps/server/src/agent/client-session/finalization.ts +99 -0
  16. package/template/apps/server/src/agent/client-session/host-auth.ts +22 -10
  17. package/template/apps/server/src/agent/client-session/host-revocation-composition.test.ts +77 -0
  18. package/template/apps/server/src/agent/client-session/host-revocation-composition.ts +28 -0
  19. package/template/apps/server/src/agent/client-session/launch-authority.contract.test.ts +21 -0
  20. package/template/apps/server/src/agent/client-session/manifest-admission.ts +11 -0
  21. package/template/apps/server/src/agent/client-session/service.test-support.ts +22 -0
  22. package/template/apps/server/src/agent/client-session/service.ts +104 -134
  23. package/template/apps/server/src/agent/client-session/terminal-digest.test.ts +23 -0
  24. package/template/apps/server/src/agent/client-workflow-artifact/active-blob-references.ts +8 -0
  25. package/template/apps/server/src/agent/client-workflow-artifact/artifact-builder.ts +60 -0
  26. package/template/apps/server/src/agent/client-workflow-artifact/authority-current.ts +59 -0
  27. package/template/apps/server/src/agent/client-workflow-artifact/binding-registry.test.ts +189 -0
  28. package/template/apps/server/src/agent/client-workflow-artifact/binding-registry.ts +153 -0
  29. package/template/apps/server/src/agent/client-workflow-artifact/bootstrap.ts +77 -0
  30. package/template/apps/server/src/agent/client-workflow-artifact/cancellation.ts +47 -0
  31. package/template/apps/server/src/agent/client-workflow-artifact/completed-recovery.ts +31 -0
  32. package/template/apps/server/src/agent/client-workflow-artifact/contracts.ts +104 -0
  33. package/template/apps/server/src/agent/client-workflow-artifact/drizzle-locks.ts +30 -0
  34. package/template/apps/server/src/agent/client-workflow-artifact/drizzle-mapper.ts +138 -0
  35. package/template/apps/server/src/agent/client-workflow-artifact/drizzle-repository.ts +346 -0
  36. package/template/apps/server/src/agent/client-workflow-artifact/error.ts +21 -0
  37. package/template/apps/server/src/agent/client-workflow-artifact/handler.ts +167 -0
  38. package/template/apps/server/src/agent/client-workflow-artifact/host-revocation.ts +29 -0
  39. package/template/apps/server/src/agent/client-workflow-artifact/in-memory-repository.ts +232 -0
  40. package/template/apps/server/src/agent/client-workflow-artifact/job-port.ts +101 -0
  41. package/template/apps/server/src/agent/client-workflow-artifact/presentation.ts +41 -0
  42. package/template/apps/server/src/agent/client-workflow-artifact/recovery.contract.test.ts +253 -0
  43. package/template/apps/server/src/agent/client-workflow-artifact/release-binding.ts +85 -0
  44. package/template/apps/server/src/agent/client-workflow-artifact/repository.test.ts +204 -0
  45. package/template/apps/server/src/agent/client-workflow-artifact/repository.ts +97 -0
  46. package/template/apps/server/src/agent/client-workflow-artifact/routes-handler.contract.test.ts +201 -0
  47. package/template/apps/server/src/agent/client-workflow-artifact/routes.ts +161 -0
  48. package/template/apps/server/src/agent/client-workflow-artifact/runtime-composition.ts +101 -0
  49. package/template/apps/server/src/agent/client-workflow-artifact/scope-authority.ts +39 -0
  50. package/template/apps/server/src/agent/client-workflow-artifact/service-authorization.ts +117 -0
  51. package/template/apps/server/src/agent/client-workflow-artifact/service-support.ts +28 -0
  52. package/template/apps/server/src/agent/client-workflow-artifact/service.contract.test.ts +345 -0
  53. package/template/apps/server/src/agent/client-workflow-artifact/service.ts +350 -0
  54. package/template/apps/server/src/agent/client-workflow-artifact/session-boundary.ts +39 -0
  55. package/template/apps/server/src/agent/client-workflow-artifact/source-access.contract.test.ts +98 -0
  56. package/template/apps/server/src/agent/client-workflow-artifact/source-access.ts +80 -0
  57. package/template/apps/server/src/agent/client-workflow-artifact/takeover.ts +122 -0
  58. package/template/apps/server/src/agent/client-workflow-artifact/task-authority.contract.test.ts +97 -0
  59. package/template/apps/server/src/agent/client-workflow-artifact/task-authority.ts +147 -0
  60. package/template/apps/server/src/agent/client-workflow-artifact/terminal-authority.contract.test.ts +100 -0
  61. package/template/apps/server/src/agent/client-workflow-artifact/terminal-replay.ts +31 -0
  62. package/template/apps/server/src/agent/client-workflow-artifact/terminal-seal.ts +211 -0
  63. package/template/apps/server/src/agent/client-workflow-artifact/workflow-artifact.test-support.ts +173 -0
  64. package/template/apps/server/src/agent/client-workflow-artifact/workflow-loader.contract.test.ts +254 -0
  65. package/template/apps/server/src/agent/client-workflow-artifact/workflow-loader.ts +285 -0
  66. package/template/apps/server/src/agent/run-facade.test-support.ts +17 -4
  67. package/template/apps/server/src/agent/run-facade.test.ts +16 -0
  68. package/template/apps/server/src/agent/run-session-authorization.ts +12 -10
  69. package/template/apps/server/src/agent/runtime-bootstrap-input.ts +5 -1
  70. package/template/apps/server/src/agent/runtime-bootstrap.ts +33 -33
  71. package/template/apps/server/src/agent/runtime-public-ports.ts +40 -0
  72. package/template/apps/server/src/agent/session-invalidation/contracts.ts +25 -26
  73. package/template/apps/server/src/agent/session-projection-access.ts +31 -19
  74. package/template/apps/server/src/agent/unavailable-routes.ts +21 -0
  75. package/template/apps/server/src/agent/workflow-runtime-bootstrap.ts +2 -0
  76. package/template/apps/server/src/agent-workflow/artifact-source-authorization.ts +12 -6
  77. package/template/apps/server/src/agent-workflow/command-facade.ts +70 -11
  78. package/template/apps/server/src/agent-workflow/drizzle-artifact-port.ts +9 -9
  79. package/template/apps/server/src/agent-workflow/drizzle-delegation-completion.ts +1 -1
  80. package/template/apps/server/src/agent-workflow/platform-node-adapters.ts +14 -6
  81. package/template/apps/server/src/agent-workflow/project-launch-authority.contract.test.ts +53 -0
  82. package/template/apps/server/src/agent-workflow/project-launch-authority.ts +92 -0
  83. package/template/apps/server/src/agent-workflow/runtime-composition.ts +30 -14
  84. package/template/apps/server/src/app/agent-runtime-composition.ts +6 -1
  85. package/template/apps/server/src/app/client-agent-workflow-artifact-binding.ts +14 -0
  86. package/template/apps/server/src/application-services.ts +6 -0
  87. package/template/apps/server/src/data-access/scope-containment.test.ts +31 -0
  88. package/template/apps/server/src/data-access/scope-containment.ts +48 -0
  89. package/template/apps/server/src/jobs/artifact-publication.test.ts +192 -0
  90. package/template/apps/server/src/jobs/artifact-publication.ts +56 -0
  91. package/template/apps/server/src/jobs/artifact-publisher.ts +101 -0
  92. package/template/apps/server/src/jobs/drizzle-artifact.ts +73 -1
  93. package/template/apps/server/src/jobs/drizzle-execution-repository.ts +14 -1
  94. package/template/apps/server/src/jobs/drizzle-execution.integration.test.ts +65 -0
  95. package/template/apps/server/src/jobs/drizzle-repository.integration.test.ts +1 -0
  96. package/template/apps/server/src/jobs/execution-repository.ts +28 -0
  97. package/template/apps/server/src/jobs/execution.test.ts +3 -1
  98. package/template/apps/server/src/jobs/in-memory-execution.ts +16 -0
  99. package/template/apps/server/src/jobs/in-memory-lease.ts +45 -1
  100. package/template/apps/server/src/jobs/legacy-adapter.integration.test.ts +2 -0
  101. package/template/apps/server/src/jobs/postgres-cleanup-contract.test.ts +58 -0
  102. package/template/apps/server/src/jobs/worker.ts +8 -14
  103. package/template/apps/server/src/module-host/background-ai-unavailable.ts +18 -0
  104. package/template/apps/server/src/module-host/durable-context.ts +19 -22
  105. package/template/apps/server/src/module-host/implementation-completeness.test.ts +80 -1
  106. package/template/apps/server/src/module-host/implementation-completeness.ts +28 -1
  107. package/template/apps/server/src/module-host/request-context.ts +32 -8
  108. package/template/apps/server/src/module-host/storage-port.ts +3 -0
  109. package/template/apps/server/src/module-host/workflow-input-artifact-port.test.ts +104 -0
  110. package/template/apps/server/src/module-host/workflow-input-artifact-port.ts +229 -0
  111. package/template/apps/server/src/module-host/workflow-input-materialization.test.ts +163 -0
  112. package/template/apps/server/src/module-host/workflow-input-materialization.ts +161 -0
  113. package/template/apps/server/src/workflow/drizzle-repository.integration.test.ts +1 -0
  114. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.vue +2 -1
  115. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.webtest.ts +16 -0
  116. package/template/docs/architecture/agent-workflow.md +13 -2
  117. package/template/docs/architecture/durable-jobs.md +7 -0
  118. package/template/docs/operations/agent-session-memory.md +2 -1
  119. package/template/docs/operations/agent-session-troubleshooting.md +87 -2
  120. package/template/docs/operations/agent-workflow-recovery.md +25 -14
  121. package/template/docs/platform/client-agent-session.md +148 -2
  122. package/template/packages/ai-client/package.json +2 -1
  123. package/template/packages/ai-client/src/client-agent/index.ts +1 -0
  124. package/template/packages/ai-client/src/client-agent/workflow-artifact/contracts.ts +85 -0
  125. package/template/packages/ai-client/src/client-agent/workflow-artifact/http.test.ts +49 -0
  126. package/template/packages/ai-client/src/client-agent/workflow-artifact/http.ts +82 -0
  127. package/template/packages/ai-client/src/client-agent/workflow-artifact/index.ts +3 -0
  128. package/template/packages/ai-client/src/client-agent/workflow-artifact/validation.test.ts +154 -0
  129. package/template/packages/ai-client/src/client-agent/workflow-artifact/validation.ts +332 -0
  130. package/template/packages/database/drizzle/0062_client_agent_workflow_artifact.sql +63 -0
  131. package/template/packages/database/drizzle/meta/0062_snapshot.json +14839 -0
  132. package/template/packages/database/drizzle/meta/_journal.json +7 -0
  133. package/template/packages/database/package.json +1 -1
  134. package/template/packages/database/src/agent-runtime-schema.test.ts +177 -0
  135. package/template/packages/database/src/schema/client-agent-workflow-artifact.ts +158 -0
  136. package/template/packages/database/src/schema/index.ts +1 -0
  137. package/template/packages/jobs/package.json +1 -1
  138. package/template/packages/jobs/src/handlers.test.ts +10 -0
  139. package/template/packages/jobs/src/handlers.ts +28 -11
  140. package/template/packages/modules/package.json +1 -1
  141. package/template/packages/modules/src/ai-client-execution-policy.ts +6 -0
  142. package/template/packages/modules/src/manifest.ts +2 -0
  143. package/template/packages/modules/src/system-agent-audit-actions.ts +3 -0
  144. package/template/packages/modules/src/system-ai-api-bindings.ts +15 -0
  145. package/template/packages/modules/src/system-audit-actions.ts +15 -0
  146. package/template/packages/server-sdk/index.ts +52 -0
  147. package/template/packages/server-sdk/package.json +5 -1
  148. package/template/packages/server-sdk/src/client-agent-session.ts +13 -1
  149. package/template/packages/server-sdk/src/client-agent-workflow-artifact.contract.test.ts +113 -0
  150. package/template/packages/server-sdk/src/client-agent-workflow-artifact.ts +183 -0
  151. package/template/packages/server-sdk/src/durable-handler.ts +7 -0
  152. package/template/packages/server-sdk/src/request-context.ts +7 -0
  153. package/template/packages/server-sdk/src/workflow-input-artifact-port.ts +104 -0
  154. package/template/packages/server-sdk/src/workflow-input-artifact-validation.contract.test.ts +124 -0
  155. package/template/packages/server-sdk/src/workflow-input-artifact-validation.ts +347 -0
  156. package/template/packages/server-sdk/src/workflow-input-materialization-handler.ts +43 -0
  157. package/template/packages/storage/package.json +1 -1
  158. package/template/packages/storage/src/blob-store-put-once.test.ts +70 -0
  159. package/template/packages/storage/src/blob-store.ts +9 -0
  160. package/template/packages/storage/src/local-file-blob-put-once.ts +120 -0
  161. package/template/packages/storage/src/local-file-blob-store.ts +53 -1
  162. package/template/packages/storage/src/memory-blob-store.ts +73 -33
@@ -6,6 +6,22 @@ import AiRuntimeFilters from "./AiRuntimeFilters.vue";
6
6
  afterEach(() => document.body.replaceChildren());
7
7
 
8
8
  describe("AI Runtime 操作者筛选", () => {
9
+ test("当前时间范围使用主按钮样式并暴露选中状态", () => {
10
+ const wrapper = mount(AiRuntimeFilters, {
11
+ props: {
12
+ range: "month",
13
+ actors: [],
14
+ },
15
+ });
16
+
17
+ const selectedRange = wrapper.get("button[data-variant='default']");
18
+ const unselectedRange = wrapper.get("button[data-variant='ghost']");
19
+
20
+ expect(selectedRange.text()).toContain("近 30 天");
21
+ expect(selectedRange.attributes("aria-pressed")).toBe("true");
22
+ expect(unselectedRange.attributes("aria-pressed")).toBe("false");
23
+ });
24
+
9
25
  test("按姓名搜索后通过设计系统 Select 选择服务端返回的操作者", async () => {
10
26
  const wrapper = mount(AiRuntimeFilters, {
11
27
  props: {
@@ -4,8 +4,8 @@
4
4
 
5
5
  AH-2 在 `system.agent` 内提供预设 Workflow 的发布、持久运行、恢复、受限委派和只读投影。
6
6
  它不把 `system.workflow` 审批状态机改造成图引擎:Approval Work Item 和 Durable Job 都只是
7
- 类型化 Node Adapter。PageAgent 仍只通过 Client Agent Session 在浏览器宿主运行,不能嵌入
8
- 服务端 Workflow Runtime。
7
+ 类型化 Node Adapter。PageAgent 仍通过 Client Agent Session 在浏览器宿主运行;Workflow 只用
8
+ 固定 taskKey 的 Job Adapter 等待受治理 Artifact,不把浏览器 Agent 循环嵌入服务端 Runtime。
9
9
 
10
10
  `system.agent-workflow` Feature 依赖 `system.agent`,仅 Advanced License 可用;读取与管理分别
11
11
  要求 `system.agent-workflow.read`、`system.agent-workflow.manage`。API、菜单、路由和审计动作
@@ -41,6 +41,17 @@ Feature、Permission、License 与对象授权,客户端提交的授权摘要
41
41
  side-effect 与 Evaluation 使用 `RESTRICT` 或独立 retention,不允许删除 Run 顺带抹除审计与恢复
42
42
  事实。
43
43
 
44
+ PageAgent Artifact Port 不扩展节点枚举:Release 继续使用
45
+ `job(system.agent-workflow.client-agent-artifact) -> artifact -> final`,且每个 Workflow 最多
46
+ 登记一个该类 project-owned binding。binding 必须 pin 完整 `releaseDigest`,并验证固定 taskKey
47
+ Job 唯一、Job 到 Artifact 以及 Artifact 到 Final 都是唯一无 branch 直接边、Artifact policy/kind
48
+ 一致且 failure policy 无 fallback/skip;新 Release 不继承旧 Release 的 PageAgent 权限。
49
+ `0062_client_agent_workflow_artifact.sql` 只为 fresh deploy
50
+ 增加 pending/claim/receipt/Artifact 桥接事实,不迁移或回填历史聊天、日志或 Run。桥接表通过
51
+ `command_id` 引用 canonical command;generation、request、fence、authorization、Scope 与
52
+ policy commitment 由 begin/claim/complete 事务锁定 command 和 Run 后逐项比较,不能用会随
53
+ 恢复轮换的复合外键代替当前事实复核。
54
+
44
55
  ## 委派
45
56
 
46
57
  Delegation 固定 `childAgentRunId`;父子 Workflow 因果 Event 使用独立的
@@ -113,6 +113,13 @@ env/file fallback。每次 resolve 都重新执行当前 License、Feature、Per
113
113
 
114
114
  任务产物读取统一经过 `DurableArtifactService`:先按 `jobId + kind` 回读持久化元数据,再校验 Owner 或显式 manage 能力、留存时间、Blob 大小和 SHA-256。调用方不能凭 `ArtifactRef` 猜测下载;API 层仍需执行对应 RBAC Guard 并记录下载审计。
115
115
 
116
+ 需要跨进程恢复的 Handler 使用 `publishArtifactOnce(publicationKey, artifact)`。Host 从
117
+ `job/stage/publicationKey` 派生稳定 Artifact ID:完全相同的重放返回原 Artifact,任何 kind、
118
+ BlobRef、hash、size、owner 或 metadata 漂移都 fail closed。Workflow PageAgent Port 在此之前
119
+ 还要求 BlobStore `putOnce`:稳定 ref 的相同字节重放成功,不同字节产生 identity conflict;
120
+ 这样“Blob 已写、桥接终态未写”与“桥接终态已写、Durable Artifact 未发布”两个崩溃窗都能用
121
+ 同一 terminal receipt 收敛,而不会再次执行浏览器或 Provider 副作用。
122
+
116
123
  模块 Route 通过 `ModuleJobPort` 控制本人提交的后台任务。宿主不会把完整
117
124
  `DurableJobSnapshot` 下发给业务,而是投影为不含 payload、内部错误、租约和 Artifact
118
125
  引用的 `ModuleJobView`。每次 get/cancel/recover 都重新执行当前 Route Guard,并要求
@@ -30,7 +30,8 @@ Migration `0060_slimy_rocket_raccoon.sql` 增加最终受治理消息投影、Ru
30
30
  派生坐标,并创建 `agent_session_run_projection_receipts`。启动后应存在
31
31
  `agent_context_messages`,且新建 Memory 必须同时保存 `derived_from_session_id` 与
32
32
  `derived_through_sequence`;Turn Event、Context Version 和 Memory 投影还应保存同一个规范化案件
33
- 坐标。后续 `0061_agent_workflow.sql` 只增加 AH-2 Workflow 的结构性 DDL;0058—0061
33
+ 坐标。后续 `0061_agent_workflow.sql` 与 `0062_client_agent_workflow_artifact.sql` 只增加
34
+ AH-2 Workflow 与 governed Client Artifact 的结构性 DDL;0058—0062
34
35
  共同属于空库 fresh-deploy 基线,不提供旧开发期 Agent 数据迁移、回填或清理脚本。开发期数据由
35
36
  部署边界外的容器/数据卷清理处理,运行时仍对任何无法核验的新记录 fail closed。
36
37
 
@@ -5,8 +5,9 @@
5
5
  先确认 Server 使用 PostgreSQL,而不是非生产内存模式;再确认 Migration 0058、0059 已应用、
6
6
  `AI_ARTIFACT_ENCRYPTION_SECRET` 与写入时一致,以及当前用户具备 Feature、Permission、License。
7
7
  不要临时改成内存 Session。首次 fresh-deploy 验收应在部署前清空旧开发 Docker 容器及数据卷,并从
8
- 空库顺序应用 AH-1 的 0058—0060;启用 AH-2 Workflow 的同一 0.6.14 基线还要继续应用结构性
9
- `0061_agent_workflow.sql`。运行中排障不得清表重建。
8
+ 空库顺序应用 AH-1 的 0058—0060;启用 AH-2 Workflow 的已发布 0.6.14 基线还要继续应用结构性
9
+ `0061_agent_workflow.sql`;0.6.15 targeted candidate 的 Workflow PageAgent Artifact Port
10
+ fresh deploy 继续应用 `0062_client_agent_workflow_artifact.sql`。运行中排障不得清表重建。
10
11
 
11
12
  ## 旧开发期 Agent 聊天记录无法读取
12
13
 
@@ -16,6 +17,90 @@
16
17
  验收从已清空旧开发容器和数据卷的空库开始;不得删除或迁移正式 Run 审计、Client Agent Session、
17
18
  Artifact、审批、上传或业务数据来“修复”此现象。
18
19
 
20
+ ## PageAgent Workflow 显示无待领取工作
21
+
22
+ 先核对当前 Actor 是否拥有目标 Run,再核对 Release 的 Job Node 是否固定使用
23
+ `system.agent-workflow.client-agent-artifact`,以及 project-owned binding 是否唯一匹配
24
+ Workflow Key 和 Node ID。begin 必须先在当前 command/fence 事务中写 pending;缺少 pending
25
+ 说明 Runtime 尚未到达该 Node 或绑定/授权已 fail closed。不要从浏览器创建工作、传 command ID,
26
+ 也不要把其它 Actor 或 Run 的 pending 改过来。
27
+
28
+ ## PageAgent Workflow 重复 claim conflict 或领取响应丢失
29
+
30
+ 检查 installation、Host session、client binding digest、claim generation、TTL,以及关联 Client
31
+ Session 是否已经产生 attempt、receipt 或在途请求。只有同一 installation/session/binding 且完全
32
+ 没有副作用证据时,Server 才允许立即接管丢失响应;否则等待 TTL、显式取消或由原宿主继续。
33
+ 禁止删除 Client Session、重置 generation 或签发新的并行 grant。
34
+
35
+ ## PageAgent Workflow receipt 被拒绝
36
+
37
+ 保留 workId、claim generation、terminal receipt ID/digest 与 canonical history head,检查 Client
38
+ Session receipt 链、当前 authorization/Scope/run policy 和 command generation/effect fence。
39
+ 这通常表示迟到写、跨 claim 重放、授权漂移或 receipt 链不完整。不得重新执行 Provider 来制造新
40
+ receipt,也不得手工写 completed;修复真实授权问题后只协调仍属当前 fence 的原 Session。
41
+
42
+ ## SDK 能 claim 但无法解析 Server workId
43
+
44
+ 先逐层核对 Server 生成器、Server SDK、AI Client validator、测试样例和文档中的 opaque prefix。
45
+ Workflow Artifact `workId` 唯一 canonical 前缀是 `cawa_`,claim token 是 `cawc_`,两者不可互换;
46
+ 跨 package 复制的 opaque 常量必须有同一契约证据。不要放宽 validator 接受多个历史前缀,这会掩盖
47
+ 真实服务端响应与 SDK 漂移。
48
+
49
+ ## Migration SQL 存在但 Drizzle journal 后续失败
50
+
51
+ 新增编号 Migration 时必须同时提交 SQL、schema、`meta/_journal.json` 条目和对应
52
+ `meta/<编号>_snapshot.json`。snapshot 的 `prevId` 必须精确等于前一编号 snapshot 的 `id`,新表、列、
53
+ 索引、外键和 check 名称要与 SQL/schema 闭合;可用仓库锁定的 Drizzle 版本从前一 snapshot 独立再生成
54
+ 并在标准化随机 id 后逐字比对。不要手写空 snapshot、跳过 prevId 或修改已发布历史 Migration。
55
+
56
+ ## cancel 后仍出现新的 PageAgent 出网
57
+
58
+ 只在 claim/advance Route 检查 fence 不足以保护 Provider attempt。确认 workflow-owned Client Session
59
+ 已在 Composition 绑定 canonical attempt authority checker:预留前、真正调用 Provider 紧前和在途期间
60
+ 都要核对 Run/Node/command、generation/fence 及 Actor/Operation/binding/Host session。判定 revoked 或
61
+ checker 异常必须先撤销 Session,再拒绝或 abort;无 bridge 的普通 Client Session 才返回 ordinary。
62
+
63
+ ## Session 已 completed 但 Workflow Artifact 一直 running
64
+
65
+ 这是 finalize-to-bridge crash window。检查 completed Session 是否保留 terminal digest、final result 和
66
+ 完整 receipt 链,以及 bridge 是否仍保留 claim token hash/client session binding。Durable handler 重启后
67
+ 应只读这些稳定事实,确定性重建 terminal receipt/result/Blob,执行 `putOnce` 后 complete bridge;不要等
68
+ 浏览器重发 advance,也不要重放 Provider。缺少任一稳定事实或 canonical authority 已漂移时 fail closed。
69
+
70
+ ## completed advance 有时接受不同 result
71
+
72
+ bridge 必须持久化首次 `receiptIds + result` 的 canonical terminal request digest。completed 重试只有该
73
+ 摘要完全一致才返回原终态;receipt 顺序、集合或 result 任一变化都拒绝。数据库 completed check 还要
74
+ 要求该摘要非空,非 completed 状态要求为空,避免部署或恢复路径绕过 Service。
75
+
76
+ ## Workflow 已完成后相同 advance retry 返回 NOT_FOUND
77
+
78
+ 不要让 completed replay 继续调用只接受 active/dispatched effect 的普通 loader。终态路径应先用
79
+ claim token/generation、Host/Session、当前 Actor/RBAC/Scope 做授权,再从 canonical
80
+ Release/Definition/Run/Node/command 只读复核不可变坐标与 digest;允许 command 为
81
+ committed/reconciled、Run/Node 为 completed。相同 terminal request digest 返回原 Artifact,摘要
82
+ 漂移仍冲突,当前撤权或 Scope 漂移仍隐藏。
83
+
84
+ ## 新 Workflow Release 意外继承 PageAgent 权限
85
+
86
+ project binding 不能只登记 `workflowKey + nodeId`,必须登记审核 Release 的 `releaseDigest`。loader
87
+ 还要确认固定 taskKey Job 全 Release 唯一,并且只有无 branch 的 `job -> artifact -> final` 直接链,
88
+ Artifact kind/policy 与绑定一致,failure policy 不含 fallback/skip。发布新 Release 时先复核拓扑和
89
+ Operation/Artifact policy,再显式更新 digest;缺失或不一致时保持不可领取。
90
+
91
+ ## PageAgent Workflow 长期 cancellation-requested
92
+
93
+ 这是两阶段取消在撤销 Client Session 或提交 cancelled 前退出的信号。确认启动恢复已扫描该行,
94
+ 然后用原 workId 继续 revoke 关联 Session 并 finalize cancel。迟到 Provider 响应保持拒绝;不要直接
95
+ 改成 cancelled,也不要删除桥接行来让 Job 重跑。
96
+
97
+ ## Workflow Artifact stable Blob conflict
98
+
99
+ 核对 terminal receipt、稳定 Blob ref、canonical JSON SHA-256/size 与 Durable
100
+ publicationKey。相同坐标的相同字节应幂等成功;不同字节表示 identity drift 或存储损坏,必须隔离
101
+ 冲突对象、保留 digest 与数据库快照并 fail closed。禁止更换 filename/ref/publicationKey 绕过冲突,
102
+ 否则会掩盖副作用重放。
103
+
19
104
  ## 重启后 Session 消失或 head 不连续
20
105
 
21
106
  检查 `agent_sessions.head_sequence` 与同 Session 的最大 Event sequence。若不一致,停止该 Session
@@ -28,17 +28,22 @@ ArtifactRef。不要从 Web 图、日志文本或子 Agent 最终回答反推业
28
28
 
29
29
  ## 重复故障速查
30
30
 
31
- | 现象 | 核对 | 安全处置 |
32
- | --------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------- |
33
- | Run 长期 `running` | deadline、cancellation、活跃 Node、head sequence | 只对合法非终态执行 Recovery;不要直接改状态 |
34
- | Node 重启后重复调用外部系统 | prepared/committed command、idempotency key、Adapter receipt | 先 reconcile 同一 command;禁止创建新 key 盲重试 |
35
- | condition 后继不明确 | Node result receipt 的 `selectedBranch`、digest、terminal Event | receipt 缺失则 fail closed;不得重新让模型选择 |
36
- | 子 Agent 权限拒绝 | Release required guards、父级 ceiling、当前 Host、Scope/Workspace | 修复真实授权或发布新 Release;不得从请求中删除 required guards |
37
- | Budget 显示还有余量但不能继续 | reservation、Provider usage measurement status | unknown 不是零;补真实计量或终止,不手工放宽 |
38
- | Approval/Job 已完成但 Node 仍等待 | command external receipt、Work Item/Job 当前事实 | 用原 command coordinate reconcile 后原子提交 Node 终态 |
39
- | Artifact 无法打开 | ArtifactRef source/hash/retention、当前对象授权 | 每次重新授权并签短期 token;不得持久化旧下载 URL |
40
- | Evaluation unavailable | 两臂 Release、Run、Provider、metrics source、rubric evidence | 保留 unavailable 与 reason;不得创建假 Run 或填零 |
41
- | Web 图与节点列表不同 | API Run projection、浏览器缓存、Graph adapter | 先刷新 canonical 投影;图坐标不是 Runtime 事实 |
31
+ | 现象 | 核对 | 安全处置 |
32
+ | ------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------- |
33
+ | Run 长期 `running` | deadline、cancellation、活跃 Node、head sequence | 只对合法非终态执行 Recovery;不要直接改状态 |
34
+ | Node 重启后重复调用外部系统 | prepared/committed command、idempotency key、Adapter receipt | 先 reconcile 同一 command;禁止创建新 key 盲重试 |
35
+ | condition 后继不明确 | Node result receipt 的 `selectedBranch`、digest、terminal Event | receipt 缺失则 fail closed;不得重新让模型选择 |
36
+ | 子 Agent 权限拒绝 | Release required guards、父级 ceiling、当前 Host、Scope/Workspace | 修复真实授权或发布新 Release;不得从请求中删除 required guards |
37
+ | Budget 显示还有余量但不能继续 | reservation、Provider usage measurement status | unknown 不是零;补真实计量或终止,不手工放宽 |
38
+ | Approval/Job 已完成但 Node 仍等待 | command external receipt、Work Item/Job 当前事实 | 用原 command coordinate reconcile 后原子提交 Node 终态 |
39
+ | PageAgent 显示无待领取工作 | Run Actor、固定 taskKey、project binding、pending 桥接行 | 修正真实 Release/绑定或等待 begin;不得伪造 pending |
40
+ | PageAgent 反复 claim conflict | installation/session/binding、claim TTL、attempt/receipt/在途请求 | 仅无副作用的同绑定丢失响应可接管;其余等待或显式取消 |
41
+ | PageAgent receipt 被拒绝 | claim generation、Session receipt 链、command/fence、当前授权 | 保留 receipt 与 digest;不得重发模型调用或手工改桥接终态 |
42
+ | PageAgent 长期 cancellation-requested | 关联 Client Session、撤销结果、启动恢复日志 | 用原 workId 继续 revoke/finalize;不得直接改 cancelled |
43
+ | Artifact identity conflict | terminal receipt、稳定 Blob ref、hash/size、Durable publicationKey | 隔离冲突字节并保留证据;禁止换 key 掩盖重复副作用 |
44
+ | Artifact 无法打开 | ArtifactRef source/hash/retention、当前对象授权 | 每次重新授权并签短期 token;不得持久化旧下载 URL |
45
+ | Evaluation unavailable | 两臂 Release、Run、Provider、metrics source、rubric evidence | 保留 unavailable 与 reason;不得创建假 Run 或填零 |
46
+ | Web 图与节点列表不同 | API Run projection、浏览器缓存、Graph adapter | 先刷新 canonical 投影;图坐标不是 Runtime 事实 |
42
47
 
43
48
  ## 取消与恢复
44
49
 
@@ -53,21 +58,27 @@ Budget,然后协调 side-effect command。授权收窄、Release 漂移、unkn
53
58
 
54
59
  ## Fresh deploy 与保留
55
60
 
56
- 本次基线只支持清空旧开发 Docker 容器及数据卷后的空数据库首次部署。按 migration 顺序执行到
57
- 0061;0061 只有 DDL,不包含旧 Agent 会话、聊天、logs 的清理、搬迁或兼容 DML。部署后检查所有
61
+ 包含本 Port 的后续候选只支持清空旧开发 Docker 容器及数据卷后的空数据库首次部署。按 migration
62
+ 顺序执行到 0062;0061—0062 只有 DDL,不包含旧 Agent 会话、聊天、logs 的清理、搬迁或兼容 DML。部署后检查所有
58
63
  Run 下游外键不是 cascade。生产留存或删除必须另行形成受治理策略,不能直接删除 Run 抹掉历史。
59
64
 
60
65
  ## 真实验收清单
61
66
 
62
- - 空 PostgreSQL 顺序执行到 0061,并验证重复执行的 migration tracker 语义;
67
+ - 空 PostgreSQL 顺序执行到 0062,并验证重复执行的 migration tracker 语义;
63
68
  - 在进程退出故障点分别覆盖外部副作用提交前、提交后 receipt 前、Node 终态前和后继提交前;
64
69
  - 覆盖并发 Recovery/CAS、取消与迟到响应、deadline、retry/backoff/skip/fail-run;
65
70
  - 覆盖真实并发 branch、全局 `maxParallelism`、Condition 非参与分支和嵌套 `join:any` loser 取消;
66
71
  - 覆盖父级剩余 Budget 并发预留、unknown token/cost fail closed、子 Agent 授权收窄;
67
72
  - 用真实 Workspace Registry 验证 child Session/Run 与每次 Tool 调用撤权后的 fail-closed;
68
73
  - 覆盖 Approval Work Item、Durable Job、write Tool 和 Subagent 四类 command reconciliation;
74
+ - 覆盖 PageAgent begin 持锁前后、claim 响应前后、Session 创建前后、Blob putOnce 前后、桥接终态
75
+ 前后和 Durable publishArtifactOnce 前后的退出故障点;
76
+ - 覆盖两阶段取消重启恢复、过期/迟到 claim 拒绝、无 attempt 的同绑定接管,以及 stable receipt、
77
+ Blob ref、Durable Artifact ID 不变且 Provider 副作用不重放;
69
78
  - 使用真实 Provider 和相同冻结坐标执行单/多 Agent 双臂评测,保存每 arm 原始可复核 evidence;
70
79
  - 验证 Artifact 每次打开重新授权,过期 token 不进入 Event、receipt 或业务表;
80
+ - 验证 PageAgent Artifact 的 canonical source ref 每次打开重新授权,不暴露 Provider URL、Key、
81
+ 物理 model、Host Auth envelope 或内部 fence;
71
82
  - 验证主站只读图、语义节点列表和对象授权,且没有在线编辑入口。
72
83
 
73
84
  普通代码静态检查、单元测试、build 或空数据库 fixture 都不能替代上述真实环境证据。正式合并候选
@@ -1,6 +1,6 @@
1
1
  # Governed Client Agent Session
2
2
 
3
- 更新时间:2026-08-26。
3
+ 更新时间:2026-08-28。
4
4
 
5
5
  ## 目的与边界
6
6
 
@@ -35,6 +35,7 @@ Windy 拥有会话、模型代理、receipt、终态和审计语义。
35
35
  ```ts
36
36
  clientExecution: {
37
37
  mode: "governed-session",
38
+ launchAuthority: "direct", // Workflow Artifact 专用 Operation 使用 workflow-artifact
38
39
  maxSteps: 12,
39
40
  maxRequestBytes: 262_144,
40
41
  maxResponseBytes: 262_144,
@@ -46,6 +47,10 @@ clientExecution: {
46
47
  Manifest 不声明 Provider URL、物理模型或 Secret。客户端收到的 `modelAlias` 只是本次
47
48
  Session 的固定逻辑别名。
48
49
 
50
+ `launchAuthority="workflow-artifact"` 是 Host enforcement,不是 prompt 约定:普通
51
+ `/agent/runs` 与普通 Client Session create 均隐藏并拒绝该 Operation,只有固定 Workflow
52
+ Artifact service 的内部 create seam 可签发 Session。
53
+
49
54
  ## HTTP 契约
50
55
 
51
56
  创建与 capability 请求使用配对后短期 `bax_` installation session:
@@ -133,6 +138,138 @@ Repository 不保存 raw prompt、Provider response、Secret 或 bearer。HTTP
133
138
  finalize、终态后的模型调用和跨 Run/Actor/binding receipt 重放均被拒绝。取消会 abort
134
139
  在途 Provider 请求;即使响应随后到达,也不能再追加 receipt 或改变终态。
135
140
 
141
+ ## Workflow Artifact Port
142
+
143
+ 预设 Workflow 调用 PageAgent 时复用既有 `job -> artifact -> final` 图节点,不新增
144
+ Client Agent 节点或在线画布。Release 的 Job Node 固定使用
145
+ `system.agent-workflow.client-agent-artifact` taskKey;project-owned Composition 为每个
146
+ Workflow 最多绑定一个 PageAgent Node、一个已声明 Operation 和 Artifact Policy。业务
147
+ Handler 只看到 `begin / claimOrAdvance / reconcileOrCancel` 三动作深 Port,不获得 Host
148
+ Auth、Provider 坐标、Client Session bearer 或 BlobStore。
149
+
150
+ 绑定必须 pin 审核时的完整 Immutable Release,而不是只写可被后续版本复用的 Workflow Key:
151
+
152
+ ```ts
153
+ {
154
+ workflowKey: "analysis.cross-case.full-review",
155
+ releaseDigest: "sha256:<审核后 Immutable Release digest>",
156
+ scopeContainmentContractVersion: 1,
157
+ nodeId: "page-agent-artifact",
158
+ operationKey: "analysis.cross-case.page-agent",
159
+ terminalResultAuthority: {
160
+ version: "sharp.cross-case-result.v1",
161
+ digest: "sha256:<project validator rules digest>",
162
+ canonicalize: async ({ workflowInput, inputArtifacts, proposedResult, actorId, scopeDigest, signal }) => {
163
+ // inputArtifacts 是 terminal 时重新授权并打开的 JSON,可校验 sourceArtifactId/locator
164
+ },
165
+ },
166
+ clientTaskAuthority: {
167
+ version: "sharp.cross-case-client-task.v1",
168
+ digest: "sha256:<project task projection digest>",
169
+ build: async ({ workflowInput, inputArtifacts, actorId, scopeDigest, signal }) => {
170
+ // inputArtifacts 是 Host 当前重授权并打开后的 JSON;只返回有界执行输入
171
+ return { taskKey: "sharp.cross-case.page-agent", input: { /* canonical locator/task */ } };
172
+ },
173
+ },
174
+ launchAuthority: {
175
+ version: "sharp.cross-case-launch.v1",
176
+ digest: "sha256:<membership/source/version/scope admission digest>",
177
+ authorizeRelease: async ({ definition, coordinates, actorId, signal }) => {},
178
+ authorizeRun: async ({ releaseId, releaseDigest, workflowInput, inputArtifacts, actorId, currentAuthorizationScope, signal }) => ({
179
+ authorizationScope: narrowToExactCase(currentAuthorizationScope, workflowInput),
180
+ }),
181
+ },
182
+ artifact: {
183
+ kind: "analysis-report",
184
+ contentType: "application/json",
185
+ filename: "analysis.json",
186
+ retentionPolicyKey: "analysis.case-artifact",
187
+ maxByteSize: 4 * 1024 * 1024,
188
+ },
189
+ }
190
+ ```
191
+
192
+ 该 Release 中固定 taskKey 的 Job Node 必须唯一,并且只能形成无 branch 的
193
+ `job -> artifact -> final` 直接链;Artifact Node 的 kind/policy 必须与绑定一致,三节点的
194
+ failure policy 不得通过 fallback/skip 绕开链路。发布新 Release 后必须重新审核并更新
195
+ `releaseDigest`,旧绑定不会静默授予新 Release PageAgent 权限。
196
+
197
+ terminal authority 在 Client Session 原子完成前收到 loader 当前 Workflow input,以及重新
198
+ reauthorize/resolve/open 后逐项核对实际 metadata 与字节上限的 canonical JSON input artifacts,
199
+ 再结合候选 canonical result、Actor、冻结 scope digest 与 AbortSignal 做 input-relative provenance
200
+ 校验。任一来源撤权、Owner/source 漂移、打开失败或 project 拒绝时 Session 与 Artifact 都保持
201
+ 未完成;返回值还要再次通过 Operation output schema。binding commitment 只承诺 authority
202
+ `version/digest`,绝不序列化函数本体。
203
+
204
+ 受绑定保护的 Workflow 不能从通用 `POST /agent/workflows/releases` 或 `/runs` 发布、复造或
205
+ 启动;即使 Actor、权限、Definition、coordinates 与 release digest 完全相同也按未发现拒绝。
206
+ project-owned preset 只能使用 Host 返回但不挂通用路由的 `agentWorkflowProjects` Seam:发布先
207
+ 调用 `launchAuthority.authorizeRelease`,启动先调用 `authorizeRun`,再把返回的 exact-case scope
208
+ 与 Host 传入的 `currentAuthorizationScope` 做 containment,并以该窄 scope 持久化 Run/Job
209
+ authorization。项目不得猜 tenant、roles 或 grants;Digest 只是 commitment,不是 launch capability。
210
+
211
+ claim 进入 running 前,Host 用当前 Run 的冻结 scope 对 Node `inputArtifacts` 重新执行 Durable
212
+ Artifact 字节、Owner 与 source authorization,并只把打开的 JSON payload 交给 project-owned
213
+ `clientTaskAuthority`。浏览器只收到 `{schemaVersion, taskKey, input, inputDigest}` 的 256 KiB
214
+ canonical task;`@southwind-ai/ai-client` 对未知字段、非 JSON、错误格式 digest/状态组合 fail closed,
215
+ 不会下发 raw Artifact。task authority 与 terminal authority 独立,前者控制执行输入,后者控制
216
+ input-relative 终态结果。
217
+
218
+ 浏览器可见 `workId` 的 canonical opaque 前缀固定为 `cawa_`;Server 生成器、
219
+ `@southwind-ai/server-sdk` 和 `@southwind-ai/ai-client` validator 必须同步,调用方只能原样回传,
220
+ 不得解析前缀后的内部身份。
221
+
222
+ Server 在浏览器可领取前先持久化 pending,并在同一事务锁定 canonical command 与 Run,
223
+ 复核 Actor、Scope、authorization、run policy、request digest、generation 和 effect fence。
224
+ 生产 Web 使用当前登录 Cookie,扩展使用已配对 `bax_` Host Auth;两者都只得到绑定
225
+ installation/session/run/node/command/scope/digest 的短期 grant。Client Agent Session 的
226
+ receipt 链完成后,Server 以一次性 terminal receipt 将 canonical JSON 写入稳定 Blob 坐标,
227
+ 再用 `publishArtifactOnce` 发布 Durable Artifact;重启只协调同一 receipt,不重放模型副作用。
228
+ 每次 Provider attempt 在预留前和真正出网紧前检查 canonical bridge,并在执行期间持续检查
229
+ Run/Node/command、generation/fence、Actor、Operation、client binding、Host session 与当前授权;
230
+ 取消、Host revoke 或 fence 轮换会先撤销 Session 并阻止新出网,普通非 Workflow Session 仍沿用
231
+ 原有授权语义。
232
+
233
+ Session finalize 与 Blob/bridge complete 之间允许进程退出。恢复只读已持久化的 completed Session、
234
+ 完整 receipt 链、final result 与 terminal request digest,确定性重建 terminal receipt、JSON 与稳定
235
+ Blob ref,再执行 `putOnce` 和 bridge complete。恢复不等待浏览器重发 advance,也不再次调用
236
+ Provider。completed advance 只有 `receiptIds + result` 的 canonical terminal request digest 与首次
237
+ 完成完全一致时才幂等返回;任何顺序、receipt 或 result 漂移都 fail closed。
238
+ 此 terminal replay 使用独立的 terminal-safe authorization:继续复核当前 Actor、RBAC、Scope、
239
+ Host/Session/claim 及原 Release/Definition/command 不可变坐标,但不要求 command 仍处于
240
+ `dispatched` 或 Run 仍处于 active。因而 command 已 committed/reconciled、Run 已 completed 后,
241
+ 相同摘要仍返回同一 Artifact。Scope 不做当前 digest 与冻结 digest 的机械相等比较:Host 从
242
+ Durable Job 读取不可伪造的冻结 authorizationScope,并证明当前 Actor scope 仍包含该冻结范围;
243
+ 相等是特例,当前范围缩小到不再包含冻结范围时仍按未发现处理,也不会恢复成更宽 Run。
244
+
245
+ 模块 Durable Handler 需要把 Storage resource 或 JSON snapshot 作为后续 Workflow input 时,使用
246
+ `context.workflowInputArtifacts`(或 `requireModuleWorkflowInputArtifactPublicationPortV1`)。Host
247
+ 先执行既有 resource-file policy/对象授权,再 `BlobStore.putOnce` 并在当前真实 Job lease 内调用
248
+ `publishArtifactOnce`;返回的 `AgentWorkflowArtifactRef.artifactId` 来自 Durable Artifact receipt,
249
+ 绝不能用 Storage `fileId` 替代。source coordinate 仍须由模块注册的 authoritative source
250
+ Adapter 支持当前对象复验。
251
+
252
+ Workflow 启动前的时序使用两阶段 `ModuleRequestContext.workflowInputMaterialization`:模块同时在
253
+ Manifest 声明 `<module>.workflow-input-materialize` Task,并用
254
+ `defineModuleWorkflowInputMaterializationHandlerV1` 注册固定 Handler。Route 先 `begin`,Host 只把
255
+ module-owned source specs 与当前 Actor/scope 提交为真实 Durable Job;后续 `resolve` 只返回
256
+ `pending`,或从同一 succeeded Job 的正式 publication 投影 `ready + AgentWorkflowArtifactRef[]`。
257
+ `begin`、Durable payload parser 与 worker publication 复用同一 public strict parser:resource/json
258
+ 字段按 mode 必填且互斥,未知字段、getter/稀疏数组、危险键、非有限数字、超深/超节点/超字节 JSON
259
+ 一律在 Storage/Blob 写入前拒绝;resource request 也必须精确匹配 `fileId/purpose/resourceType/resourceId`。
260
+ 调用方只能在 ready 后把 refs 连同 source IDs 交给 preset start;project prepare 仍重读业务对象并
261
+ 逐项匹配坐标,Workflow start 随后再次校验 Durable Artifact 字节、Owner、source authorization 与
262
+ 冻结 scope。客户端回传的是待复验 capability-like ref,不是来源授权事实。取消、撤权、Job/metadata
263
+ 漂移或非 succeeded 状态不会返回 refs;Coordinator 不创建 synthetic job。
264
+ 该固定 Manifest task 的实现事实就是同 key、同 feature/permission/audit 的 Durable Handler;
265
+ Module completeness 不要求再注册 scheduled `registerTaskHandlers` no-op,任一 capability 坐标漂移
266
+ 仍按缺少实现 fail closed。
267
+
268
+ `completed` 与 `cancelled` 是吸收态。取消先持久化 `cancellation-requested`,再撤销关联
269
+ Client Session,最后提交 cancelled;启动恢复会继续未完成的取消。只有尚未产生 attempt、
270
+ receipt 或在途请求的同一 installation/session/binding 才能立即接管丢失响应的 claim;其它
271
+ 迟到写入、过期 claim、fence 漂移、不同内容占用同一 Blob/Artifact 坐标均 fail closed。
272
+
136
273
  ## 部署与稳定错误
137
274
 
138
275
  生产 Server 必须配置 `WINDY_PUBLIC_BASE_URL=https://windy.example`。它只用于生成受信
@@ -157,7 +294,8 @@ Provider 错误脱敏。
157
294
  2. Server 配置 `WINDY_PUBLIC_BASE_URL`,生产必须是最终用户可访问的 HTTPS 利剑服务 origin;
158
295
  3. Agent Server 继续使用现有 `QWEN_API_URL`、`QWEN_API_KEY`、`QWEN_MODEL` 与 deployment
159
296
  配置,绝不把这些值复制到 Web、扩展或业务模块;
160
- 4. 业务模块仅在目标 Agent Operation 上声明 `clientExecution`,同时保留原
297
+ 4. 业务模块仅在目标 Agent Operation 上声明 `clientExecution`;Workflow 专用 Operation 还必须
298
+ 声明 `launchAuthority: "workflow-artifact"`,同时保留原
161
299
  Feature/Permission/License/Scope 与 `providerDataPolicy`;
162
300
  5. 在 project-owned `client-agent-host-auth-binding.ts` 装配实现
163
301
  `ModuleClientAgentHostAuthAdapter` 的 P-256 pairing/bax Adapter;其 `authenticate` 只返回
@@ -169,5 +307,13 @@ Provider 错误脱敏。
169
307
  7. 服务地址或 installation pairing 切换前调用 binding revoke,清除内存中的 grant;无法
170
308
  联系旧服务时不得复用旧 token,等待其短 TTL 到期。
171
309
 
310
+ Workflow Artifact Port 还要求 fresh deploy 顺序应用
311
+ `0062_client_agent_workflow_artifact.sql`,并在 project-owned
312
+ `client-agent-workflow-artifact-binding.ts` 登记审核后的 Workflow/Node/Operation/Artifact
313
+ 绑定。已经发布的 `0.6.14` recipe 保持不可变;既有 Starter 的 project-owned Composition
314
+ 由 `0.6.15` narrow recipe 以唯一 import/Omit/runtime property 三锚点接入。binding 缺失时
315
+ 创建新默认空 seam;只有完整匹配旧默认空 seam 才升级 release/scope/terminal authority 注释契约,客户已登记或
316
+ 任意字节漂移均在写入前停止并保留 WIP。
317
+
172
318
  协议没有 BYOK、用户模型选择、逐动作审批或逐目标网页 origin 授权字段。宿主配对只负责
173
319
  识别目标 Windy 服务、当前登录 actor、installation 和撤销边界。
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@southwind-ai/ai-client",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "engines": {
@@ -19,6 +19,7 @@
19
19
  ".": "./index.ts",
20
20
  "./agent": "./src/agent/index.ts",
21
21
  "./client-agent": "./src/client-agent/index.ts",
22
+ "./client-agent/workflow-artifact": "./src/client-agent/workflow-artifact/index.ts",
22
23
  "./contracts": "./src/agent/contracts/index.ts",
23
24
  "./document": "./src/document/index.ts",
24
25
  "./embedding": "./src/embedding/index.ts",
@@ -1,3 +1,4 @@
1
1
  export * from "./contracts.js";
2
2
  export * from "./http.js";
3
3
  export * from "./validation.js";
4
+ export * from "./workflow-artifact/index.js";
@@ -0,0 +1,85 @@
1
+ import type { ClientAgentSessionGrant } from "../contracts.js";
2
+
3
+ export const clientAgentWorkflowArtifactWorkIdPrefix = "cawa_" as const;
4
+
5
+ export interface ClaimClientAgentWorkflowArtifactRequest {
6
+ readonly workflowRunId: string;
7
+ /** installation/conversation/tab/document epoch 的宿主 commitment。 */
8
+ readonly clientBindingDigest: `sha256:${string}`;
9
+ }
10
+
11
+ export interface AdvanceClientAgentWorkflowArtifactRequest<Result = unknown> {
12
+ readonly workId: string;
13
+ readonly claimToken: string;
14
+ readonly claimVersion: number;
15
+ /** 当前 claim 的完整、按序 Provider receipt 链。 */
16
+ readonly receiptIds: readonly string[];
17
+ readonly result?: Result;
18
+ }
19
+
20
+ export interface CancelClientAgentWorkflowArtifactRequest {
21
+ readonly workId: string;
22
+ readonly claimToken: string;
23
+ readonly claimVersion: number;
24
+ }
25
+
26
+ export type ClientAgentWorkflowArtifactStatus =
27
+ | "pending"
28
+ | "running"
29
+ | "completed"
30
+ | "cancelled";
31
+
32
+ export const clientAgentWorkflowArtifactSafeCodes = [
33
+ "HOST_UNAVAILABLE",
34
+ "NO_PENDING_WORK",
35
+ "CLAIM_CONFLICT",
36
+ "WORK_NOT_FOUND",
37
+ "WORK_EXPIRED",
38
+ "WORK_CANCELLED",
39
+ "RECEIPT_REJECTED",
40
+ "ARTIFACT_REJECTED",
41
+ "INTERNAL_ERROR",
42
+ ] as const;
43
+
44
+ export type ClientAgentWorkflowArtifactSafeCode =
45
+ (typeof clientAgentWorkflowArtifactSafeCodes)[number];
46
+
47
+ export interface ClientAgentWorkflowArtifactSummary {
48
+ readonly artifactId: string;
49
+ readonly kind: string;
50
+ readonly contentType: string;
51
+ readonly filename: string;
52
+ readonly byteSize: number;
53
+ readonly sha256: string;
54
+ }
55
+
56
+ export type ClientAgentWorkflowJsonValue =
57
+ | null
58
+ | boolean
59
+ | number
60
+ | string
61
+ | readonly ClientAgentWorkflowJsonValue[]
62
+ | { readonly [key: string]: ClientAgentWorkflowJsonValue };
63
+
64
+ export interface ClientAgentWorkflowExecutionTask {
65
+ readonly schemaVersion: 1;
66
+ readonly taskKey: string;
67
+ readonly input: ClientAgentWorkflowJsonValue;
68
+ readonly inputDigest: `sha256:${string}`;
69
+ }
70
+
71
+ /**
72
+ * Browser 只观察 claim lifecycle、短期 Client Agent grant 和最终 Artifact 摘要。
73
+ * Workflow Node/command、Scope、effect fence 与 Provider deployment 均不属于此 DTO。
74
+ */
75
+ export interface ClientAgentWorkflowArtifactResponse {
76
+ readonly workId: string;
77
+ readonly status: ClientAgentWorkflowArtifactStatus;
78
+ readonly claimVersion: number;
79
+ /** 仅 running claim 返回;绑定当前 installation/session 与 claimVersion。 */
80
+ readonly claimToken?: string;
81
+ readonly sessionGrant?: ClientAgentSessionGrant;
82
+ readonly task?: ClientAgentWorkflowExecutionTask;
83
+ readonly artifact?: ClientAgentWorkflowArtifactSummary;
84
+ readonly safeCode?: ClientAgentWorkflowArtifactSafeCode;
85
+ }
@@ -0,0 +1,49 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import {
3
+ clientAgentWorkflowArtifactAdvanceRequest,
4
+ clientAgentWorkflowArtifactClaimRequest,
5
+ } from "./http.js";
6
+
7
+ describe("Client Agent Workflow Artifact HTTP contract", () => {
8
+ test("Web Cookie 与 Extension 复用同一 claim route", () => {
9
+ const body = {
10
+ workflowRunId: "workflow-run-1",
11
+ clientBindingDigest: `sha256:${"a".repeat(64)}` as const,
12
+ };
13
+ const web = clientAgentWorkflowArtifactClaimRequest(body, {
14
+ mode: "current-session",
15
+ });
16
+ const extension = clientAgentWorkflowArtifactClaimRequest(body, {
17
+ mode: "paired-extension",
18
+ accessToken: "bax_installation-session",
19
+ });
20
+
21
+ expect(web.url).toBe(extension.url);
22
+ expect(web.init.credentials).toBe("same-origin");
23
+ expect(web.init.headers).toEqual({ "content-type": "application/json" });
24
+ expect(extension.init.credentials).toBe("omit");
25
+ expect(extension.init.headers).toEqual({
26
+ "content-type": "application/json",
27
+ authorization: "Bearer bax_installation-session",
28
+ });
29
+ });
30
+
31
+ test("advance 只发送 opaque claim 与完整 receipt 链", () => {
32
+ const request = clientAgentWorkflowArtifactAdvanceRequest(
33
+ {
34
+ workId: `cawa_${"w".repeat(32)}`,
35
+ claimToken: `cawc_${"c".repeat(32)}`,
36
+ claimVersion: 2,
37
+ receiptIds: ["receipt_0001"],
38
+ result: { summary: "研判完成" },
39
+ },
40
+ { mode: "current-session" },
41
+ );
42
+ const serialized = String(request.init.body);
43
+
44
+ expect(serialized).not.toContain("workflowRunId");
45
+ expect(serialized).not.toContain("nodeRunId");
46
+ expect(serialized).not.toContain("providerUrl");
47
+ expect(serialized).not.toContain("fenceToken");
48
+ });
49
+ });