ai-workflow-flow-dsl-reference 0.1.0

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 (64) hide show
  1. package/dist/index.d.ts +8 -0
  2. package/dist/index.js +18 -0
  3. package/dist/resource-module/KindDefinitions/WikiPage/manifest.xnl +10 -0
  4. package/dist/resource-module/WikiPages/README/manifest.xnl +6 -0
  5. package/dist/resource-module/WikiPages/foundation__depa-axioms/manifest.xnl +6 -0
  6. package/dist/resource-module/WikiPages/foundation__naming-axioms/manifest.xnl +6 -0
  7. package/dist/resource-module/WikiPages/foundation__syntax-axioms/manifest.xnl +6 -0
  8. package/dist/resource-module/WikiPages/spec__ai-workflow__ctrl-workflow/manifest.xnl +6 -0
  9. package/dist/resource-module/WikiPages/spec__ai-workflow__data-workflow/manifest.xnl +6 -0
  10. package/dist/resource-module/WikiPages/spec__ai-workflow__resources/manifest.xnl +6 -0
  11. package/dist/resource-module/WikiPages/spec__bp-ctrl-flow__domains/manifest.xnl +6 -0
  12. package/dist/resource-module/WikiPages/spec__bp-ctrl-flow__nodes/manifest.xnl +6 -0
  13. package/dist/resource-module/WikiPages/spec__eager-data-flow__domains/manifest.xnl +6 -0
  14. package/dist/resource-module/WikiPages/spec__eager-data-flow__files/manifest.xnl +6 -0
  15. package/dist/resource-module/WikiPages/spec__eager-data-flow__nodes/manifest.xnl +6 -0
  16. package/dist/resource-module/WikiPages/spec__eager-data-flow__refs/manifest.xnl +6 -0
  17. package/dist/resource-module/WikiPages/spec__flow-core__domains/manifest.xnl +6 -0
  18. package/dist/resource-module/WikiPages/spec__flow-core__files/manifest.xnl +6 -0
  19. package/dist/resource-module/WikiPages/spec__flow-core__nodes/manifest.xnl +6 -0
  20. package/dist/resource-module/WikiPages/spec__flow-core__orchestration/manifest.xnl +6 -0
  21. package/dist/resource-module/WikiPages/spec__flow-core__refs/manifest.xnl +6 -0
  22. package/dist/resource-module/WikiPages/spec__instant-ctrl-flow__domains/manifest.xnl +6 -0
  23. package/dist/resource-module/WikiPages/spec__instant-ctrl-flow__nodes/manifest.xnl +6 -0
  24. package/dist/resource-module/WikiPages/spec__work-ctrl-flow__domains/manifest.xnl +6 -0
  25. package/dist/resource-module/WikiPages/spec__work-ctrl-flow__nodes/manifest.xnl +6 -0
  26. package/dist/resource-module/WikiPages/std__ai-ctrl-workflow__axioms/manifest.xnl +6 -0
  27. package/dist/resource-module/WikiPages/std__ai-data-workflow__axioms/manifest.xnl +6 -0
  28. package/dist/resource-module/WikiPages/std__behavior-tree__axioms/manifest.xnl +6 -0
  29. package/dist/resource-module/WikiPages/std__bp-ctrl-flow__axioms/manifest.xnl +6 -0
  30. package/dist/resource-module/WikiPages/std__eager-data-flow__axioms/manifest.xnl +6 -0
  31. package/dist/resource-module/WikiPages/std__instant-ctrl-flow__axioms/manifest.xnl +6 -0
  32. package/dist/resource-module/WikiPages/std__work-ctrl-flow__axioms/manifest.xnl +6 -0
  33. package/dist/resource-module/content/.depa-flow-dsl-provenance.json +127 -0
  34. package/dist/resource-module/content/README.md +164 -0
  35. package/dist/resource-module/content/foundation/depa-axioms.md +41 -0
  36. package/dist/resource-module/content/foundation/naming-axioms.md +167 -0
  37. package/dist/resource-module/content/foundation/syntax-axioms.md +60 -0
  38. package/dist/resource-module/content/spec/ai-workflow/ctrl-workflow.md +53 -0
  39. package/dist/resource-module/content/spec/ai-workflow/data-workflow.md +78 -0
  40. package/dist/resource-module/content/spec/ai-workflow/resources.md +242 -0
  41. package/dist/resource-module/content/spec/bp-ctrl-flow/domains.md +30 -0
  42. package/dist/resource-module/content/spec/bp-ctrl-flow/nodes.md +122 -0
  43. package/dist/resource-module/content/spec/eager-data-flow/domains.md +59 -0
  44. package/dist/resource-module/content/spec/eager-data-flow/files.md +68 -0
  45. package/dist/resource-module/content/spec/eager-data-flow/nodes.md +151 -0
  46. package/dist/resource-module/content/spec/eager-data-flow/refs.md +90 -0
  47. package/dist/resource-module/content/spec/flow-core/domains.md +39 -0
  48. package/dist/resource-module/content/spec/flow-core/files.md +50 -0
  49. package/dist/resource-module/content/spec/flow-core/nodes.md +203 -0
  50. package/dist/resource-module/content/spec/flow-core/orchestration.md +161 -0
  51. package/dist/resource-module/content/spec/flow-core/refs.md +78 -0
  52. package/dist/resource-module/content/spec/instant-ctrl-flow/domains.md +20 -0
  53. package/dist/resource-module/content/spec/instant-ctrl-flow/nodes.md +47 -0
  54. package/dist/resource-module/content/spec/work-ctrl-flow/domains.md +29 -0
  55. package/dist/resource-module/content/spec/work-ctrl-flow/nodes.md +90 -0
  56. package/dist/resource-module/content/std/ai-ctrl-workflow/axioms.md +31 -0
  57. package/dist/resource-module/content/std/ai-data-workflow/axioms.md +24 -0
  58. package/dist/resource-module/content/std/behavior-tree/axioms.md +72 -0
  59. package/dist/resource-module/content/std/bp-ctrl-flow/axioms.md +48 -0
  60. package/dist/resource-module/content/std/eager-data-flow/axioms.md +57 -0
  61. package/dist/resource-module/content/std/instant-ctrl-flow/axioms.md +37 -0
  62. package/dist/resource-module/content/std/work-ctrl-flow/axioms.md +54 -0
  63. package/dist/resource-module/manifest.xnl +9 -0
  64. package/package.json +29 -0
@@ -0,0 +1,203 @@
1
+ # L3 · flow-core statements
2
+
3
+ > 本页定义 InstantCtrlFlow、WorkCtrlFlow、BPCtrlFlow 共享的公开 CtrlFlow authoring grammar。产品扩展 statement 见各 `spec/<profile>/nodes.md`。
4
+
5
+ ## 根与有序语句
6
+
7
+ 三个产品根都是可执行 definition。它们的 `[]` 直接保存 statements,按声明顺序执行;嵌套 body 的 `[]` 遵守同一规则。
8
+
9
+ ```xnl
10
+ <WorkCtrlFlow #depa.flows.demo.OrderRouting apiVersion="depa.flows/v1" version="1.0.0" [
11
+ <Run #load-order {
12
+ src = "vfs://./flow-code/order.ts#loadOrder"
13
+ }>
14
+ <Return #result {
15
+ src = "vfs://./flow-code/order.ts#toResult"
16
+ }>
17
+ ]>
18
+ ```
19
+
20
+ 根 `#id` 必须是 FQN;`apiVersion`、`version` 位于 metadata 段;标题等业务描述位于 `{}`。根 `[]` 不允许额外的结构包装。
21
+
22
+ ## 值传递
23
+
24
+ CtrlFlow statement 组成一条显式数据链:flow 调用输入是根 `[]` 第一条 statement 的 `input`;普通 statement 的 `output` 是下一条 statement 的 `input`。嵌套 body 也遵守同一规则。
25
+
26
+ - `Run` output 替换当前值。
27
+ - `If` predicate 读取当前值;被选 Branch body 的最终 output 成为 `If` output;无匹配且无 Otherwise 时原值原样通过。
28
+ - `Fallback` 的每个 Strategy 从同一份进入 Fallback 的 input 开始;首个成功 strategy 的最终 output 成为 Fallback output。
29
+ - `Until` 每轮 body 的最终 output 成为下一次 predicate 的 input。
30
+ - 动态代码不得修改 `input`;新数据必须通过函数 output 返回。
31
+ - 节点的 `config` 属性是传给代码的静态配置,缺省为 `{}`;`src`、`when` 等结构字段不混入 config。
32
+
33
+ ## `Run`
34
+
35
+ `Run` 调用一个代码入口。`src` 必填;函数 output 直接成为下一条 statement 的 input。
36
+
37
+ ```xnl
38
+ <Run #load-quote {
39
+ src = "vfs://./flow-code/quote.ts#loadQuote"
40
+ config = { currency = "TRY" includeTax = true }
41
+ }>
42
+ ```
43
+
44
+ ```ts
45
+ export async function loadQuote(runtime, input, config) {
46
+ return runtime.callEffect('pricing.quote', input, config);
47
+ }
48
+ ```
49
+
50
+ 函数正常返回表示 statement 技术成功,返回值可以是任意 data;抛出或返回 runtime 定义的 fault 表示技术失败。业务值如 `refused`、`notFound`、`declined` 仍是正常 output,不得自动转成技术失败。
51
+
52
+ ## `If` / `Branches` / `Branch` / `Otherwise`
53
+
54
+ `If` 在唯一的 `()` 子域中拥有一个 `Branches`;`Branches[]` 包含一个或多个有序 `Branch`,以及最多一个 `Otherwise`。`Otherwise` 若存在必须是最后一项。
55
+
56
+ ```xnl
57
+ <If #route-quote (
58
+ <Branches [
59
+ <Branch #manual-review {
60
+ when = "vfs://./flow-code/quote.ts#needsManualReview"
61
+ config = { threshold = 5000 }
62
+ } [
63
+ <Run #create-review {
64
+ src = "vfs://./flow-code/quote.ts#createReview"
65
+ }>
66
+ <Return #review-result {
67
+ src = "vfs://./flow-code/quote.ts#reviewResult"
68
+ }>
69
+ ]>
70
+ <Branch #accepted {
71
+ when = "vfs://./flow-code/quote.ts#isAccepted"
72
+ } [
73
+ <Return #accepted-result {
74
+ src = "vfs://./flow-code/quote.ts#acceptedResult"
75
+ }>
76
+ ]>
77
+ <Otherwise [
78
+ <Return #rejected-result {
79
+ src = "vfs://./flow-code/quote.ts#rejectedResult"
80
+ }>
81
+ ]>
82
+ ]>
83
+ )>
84
+ ```
85
+
86
+ ```ts
87
+ export function needsManualReview(runtime, input, config) {
88
+ return input.total >= config.threshold;
89
+ }
90
+
91
+ export function isAccepted(runtime, input, config) {
92
+ return input.decision === 'accepted';
93
+ }
94
+ ```
95
+
96
+ 执行规则:
97
+
98
+ 1. 按声明顺序调用 `Branch.when` predicate。
99
+ 2. predicate 必须按 `boolean = fn(runtime, input, config)` 返回 boolean;非 boolean 是协议错误。
100
+ 3. 选择第一个返回 `true` 的 Branch,只执行其 `[]` body,后续 Branch 不再求值。
101
+ 4. 全部为 `false` 时执行可选 `Otherwise[]`;没有 `Otherwise` 时 `If` 是 no-op,继续根或外层 body 的下一条 statement。
102
+ 5. predicate 的技术失败直接使 `If` 技术失败;它不是 `false`。
103
+
104
+ WorkCtrlFlow/BPCtrlFlow 在完成选择后必须记录 branch decision;恢复时复用已发生决策,不重新求值改变路径。
105
+
106
+ ## `Fallback`
107
+
108
+ `Fallback[]` 保存按优先级排列的 strategy。每个 `Strategy[]` 是有序 statements;执行器选择第一个**技术成功**的 strategy。
109
+
110
+ ```xnl
111
+ <Fallback #load-customer [
112
+ <Strategy #primary [
113
+ <Run #load-primary {
114
+ src = "vfs://./flow-code/customer.ts#loadPrimary"
115
+ }>
116
+ ]>
117
+ <Strategy #replica [
118
+ <Run #load-replica {
119
+ src = "vfs://./flow-code/customer.ts#loadReplica"
120
+ }>
121
+ ]>
122
+ <Strategy #cached [
123
+ <Run #load-cache {
124
+ src = "vfs://./flow-code/customer.ts#loadCached"
125
+ }>
126
+ ]>
127
+ ]>
128
+ ```
129
+
130
+ - strategy 内全部 statements 技术成功时,Fallback 成功并继续外层下一条 statement。
131
+ - strategy 出现技术失败时,丢弃该 strategy 的临时输出,并以进入 Fallback 时的原 input 尝试下一项;外部副作用是否可回滚由 runtime/effect 事务契约决定,Fallback 不承诺补偿。
132
+ - 全部 strategy 技术失败时,Fallback 向外传播聚合 fault。
133
+ - 任意正常业务 output 都算技术成功,即使值是 `refused` 或 `notFound`;业务路由必须在后续 `If` 中表达。
134
+ - strategy 内的 `Return` 仍立即结束整个 flow,不只是结束该 strategy。
135
+
136
+ ## `Until`
137
+
138
+ `Until.when` 是退出 predicate code ref;`Until[]` 是每轮按序执行的 statements。每轮开始前先求值 predicate,因此初始即为 `true` 时 body 执行零次。
139
+
140
+ ```xnl
141
+ <Until #await-ready {
142
+ when = "vfs://./flow-code/job.ts#isReady"
143
+ maxIterations = 20
144
+ config = { expectedStatus = "ready" }
145
+ } [
146
+ <Run #poll {
147
+ src = "vfs://./flow-code/job.ts#poll"
148
+ }>
149
+ ]>
150
+ ```
151
+
152
+ ```ts
153
+ export function isReady(runtime, input, config) {
154
+ return input?.status === config.expectedStatus;
155
+ }
156
+ ```
157
+
158
+ predicate 返回 `false` 时执行一轮 body 后再次检查;返回 `true` 时继续外层下一条 statement。predicate 或 body 的技术失败向外传播;`maxIterations` 超限产生技术 fault,防止定义导致无界同步循环。
159
+
160
+ ## `Return`
161
+
162
+ `Return` 立即终止整个 flow 并产生公开 output。它可以使用 `value` 或 `src` 之一;两者都省略时返回当前 input:
163
+
164
+ ```xnl
165
+ <Return #literal-result {
166
+ value = { status = "accepted" }
167
+ }>
168
+ ```
169
+
170
+ ```xnl
171
+ <Return #computed-result {
172
+ src = "vfs://./flow-code/quote.ts#toResult"
173
+ config = { includeAudit = true }
174
+ }>
175
+ ```
176
+
177
+ ```ts
178
+ export function toResult(runtime, input, config) {
179
+ return {
180
+ quote: input,
181
+ includeAudit: config.includeAudit,
182
+ };
183
+ }
184
+ ```
185
+
186
+ `Return.src` 使用普通动态代码协议;其 output 就是 flow output。`Return.value` 是不调用代码的字面量 output;无 `src`/`value` 时当前 input 就是 flow output。`Return` 之后同一 body 中的 statements 不执行。
187
+
188
+ ## 动态代码协议
189
+
190
+ 所有 `src` / `when` 引用的 export 都遵守:
191
+
192
+ ```text
193
+ output = fn(runtime, input, config)
194
+ ```
195
+
196
+ | 参数 | owner | 约束 |
197
+ |---|---|---|
198
+ | `runtime` | profile engine | 显式注入长生命周期依赖、effect 契约和必要的实例能力;代码不得读隐式全局。 |
199
+ | `input` | statement runner | 当前不可变数据视图;predicate 与普通代码收到同一份形态。 |
200
+ | `config` | definition node | 节点声明的静态 `config` map;不得包含函数或复制 runtime。 |
201
+ | `output` | code export | 普通 data;predicate 限定为 boolean;技术失败通过 fault 通道表达。 |
202
+
203
+ 代码可同步或异步返回;runner 必须 await 后再推进下一条 statement。XNL 只保存 `vfs://...#Export`,不内嵌函数、表达式字符串、闭包或 handler object。
@@ -0,0 +1,161 @@
1
+ # L3 · CtrlFlow 编排原语与产品能力
2
+
3
+ > loader 的 grammar acceptance 只证明定义合法;节点是否可执行由对应版本的 profile runtime capability 决定。
4
+
5
+ ## 公共语义边界
6
+
7
+ 所有动态节点都遵守同一调用协议:
8
+
9
+ ```text
10
+ output = fn(runtime, input, config)
11
+ ```
12
+
13
+ - `Run` 是调用 `vfs://...#Export` 脚本的基本叶节点。
14
+ - 组合节点只组织子节点;XNL 不承载 TypeScript 表达式、HTTP 请求、状态写入或具体 effect 实现。
15
+ - `data`、`fault`、`suspension` 始终三分:业务拒绝是 data,技术错误是 fault,等待是 suspension。
16
+ - `Retry`、`Race`、`Timeout` 不能暗中补偿已经完成的 effect;补偿必须由显式流程或 effect/runtime 契约定义。
17
+ - predicate、集合选择、转换和实现引用都指向代码 export,DSL 不引入表达式语言。
18
+
19
+ ## 公共原语
20
+
21
+ | tag | 子域 / 关键字段 | 语义 |
22
+ |---|---|---|
23
+ | `Run` | `src`, `config` | 调用一个脚本,output 成为下一条 statement 的 input。 |
24
+ | `If` | 唯一 `Branches` | 按有序 `Branch.when` 做业务 data 路由;没有匹配时使用 `Otherwise`。 |
25
+ | `Require` | `when`, `config` | 技术前置条件为 false 时产生结构化 fault。 |
26
+ | `Fallback` | 一个或多个 `Strategy[]` | 只消费技术 fault,按顺序尝试替代策略。 |
27
+ | `Retry` | body `[]`, retry policy | 只因可重试 fault 重试子流程;成功后输出子流程 output。 |
28
+ | `Timeout` | body `[]`, deadline | 限制子流程时长,取消仍在运行的子操作并产生 timeout fault。 |
29
+ | `Until` | `when`, `maxIterations`, body `[]` | 有界循环,predicate 为 true 时退出。 |
30
+ | `ForEach` | `when`, iteration policy, body `[]` | 对代码选择的集合逐项编排,支持 sequential 或 bounded-parallel。 |
31
+ | `Parallel` | 唯一 `Lanes` / `Lane[]` | 并发分叉并汇合;每个 lane 收到同一份 immutable input,output 按 lane id 聚合。 |
32
+ | `Race` | 唯一 `Candidates` / `Candidate[]` | 多候选并发竞争,明确 `first-success` 或 `first-completed`,结束后取消未完成候选。 |
33
+ | `CallFlow` | `flow` | 经 FlowContract/registry 解析并调用另一 Flow,得到目标 flow 的 output。 |
34
+ | `Return` | `src`、`value` 或当前 input | 结束当前 flow 并产生公开 output。 |
35
+
36
+ `Require` 比泛化的 `Guard` 更准确:它表达“条件不满足即技术上不能继续”。业务条件不满足时继续使用 `If + Otherwise`,不要把业务拒绝伪装成 fault。
37
+
38
+ `Parallel` 的 XNL 形态如下;`()` 表示唯一的 `Lanes` 子域:
39
+
40
+ ```xnl
41
+ <Parallel #load-context {
42
+ join = "all"
43
+ } (
44
+ <Lanes [
45
+ <Lane #profile [
46
+ <Run #load-profile {
47
+ src = "vfs://./scripts/profile.ts#loadProfile"
48
+ }>
49
+ ]>
50
+ <Lane #permissions [
51
+ <Run #load-permissions {
52
+ src = "vfs://./scripts/permission.ts#loadPermissions"
53
+ }>
54
+ ]>
55
+ ]>
56
+ )>
57
+ ```
58
+
59
+ 其 output 是类似 `{ profile: ..., permissions: ... }` 的聚合 data;后续 `Run` 决定怎样组合业务对象。`Race` 使用 `Candidates/Candidate`,不借用 `If` 的 `Branches`。
60
+
61
+ ## 产品能力矩阵
62
+
63
+ | 能力 | InstantCtrlFlow | WorkCtrlFlow | BPCtrlFlow |
64
+ |---|---|---|---|
65
+ | `Run` / `If` / `Require` / `Fallback` / `Until` / `Return` | 是 | 是 | 是 |
66
+ | `Retry` | 当前 invocation 内的内存期 attempt | 持久 attempt/backoff | 持久 attempt/backoff |
67
+ | `Timeout` | 当前调用内 deadline | 持久 deadline,可恢复 | 持久 deadline,可恢复 |
68
+ | `Parallel` / `Race` / `ForEach` | 当前调用内并发与取消 | 保存 branch/lane/candidate 状态与结果 | 与 WorkCtrlFlow 相同,用于技术工作 |
69
+ | `CallFlow` | 仅同步、不可持久挂起目标 | 可调用 InstantCtrlFlow/EagerDataFlow;持久子 WorkCtrlFlow 需独立生命周期协议 | 与 WorkCtrlFlow 相同,可再扩展子 BPCtrlFlow |
70
+ | `Delay` | 可以有,仅当前调用内等待 | 不使用,持久等待使用 `Timer` | 不使用,持久等待使用 `Timer` |
71
+ | `ExternalJob` / `Timer` | 否 | 是 | 是 |
72
+ | `TaskStep` / `TaskSpace` | 否 | 否 | 是 |
73
+ | 人工任务并行/汇合 | 否 | 否 | 归 `TaskGroup.executionMode`,不是 `Parallel` |
74
+
75
+ 关键区别是:`Parallel` 在 InstantCtrlFlow 中只是一次 invocation 内的并发调度;在 WorkCtrlFlow/BPCtrlFlow 中是持久化并发实例模型,必须保存每个 lane 的启动、完成、fault、winner、取消和 deadline 事实。因此三种产品可以共享 DSL tag,但不能共享一套忽略生命周期差异的运行时实现。
76
+
77
+ ## InstantCtrlFlow:一次调用内完成的脚本编排器
78
+
79
+ InstantCtrlFlow 用于协调多个 `vfs://...#Export` 的读取、校验、转换、聚合和有限并发脚本。它可以编排:
80
+
81
+ - 并行查询、并行调用 effect、竞争不同数据源。
82
+ - 有界重试、请求级超时、批量和集合处理。
83
+ - 调用同样无持久化的子 InstantCtrlFlow,或同步调用 EagerDataFlow。
84
+ - 从显式 runtime 取得 effect 依赖;脚本不直接绑定 HTTP、数据库或 UI 实现。
85
+
86
+ InstantCtrlFlow 不承担:
87
+
88
+ - 重启后仍需恢复的等待、重试或并发任务。
89
+ - 人工审批、外部回调和长期计时。
90
+ - 隐式共享状态或脚本内偷偷改变流程上下文。
91
+ - 自动 Saga 补偿。
92
+
93
+ InstantCtrlFlow 不拥有 snapshot、WaitHandle、人工任务、外部恢复消息或跨调用实例事实。它只有正常 output 或技术 fault 两种公开完成结果,业务 `refused`、`declined`、`notFound` 等仍是 data。
94
+
95
+ ## WorkCtrlFlow:可恢复的技术编排 actor
96
+
97
+ WorkCtrlFlow 是长生命周期、可恢复的技术编排器,协调跨进程技术工作:外部消息、Timer、持久重试、deadline,以及可恢复的并发分支。
98
+
99
+ WorkCtrlFlow runtime snapshot 拥有:
100
+
101
+ - execution snapshot、当前 statement path 和已发生 branch decision。
102
+ - attempt、deadline、lane/candidate outcome、取消请求。
103
+ - 已调度唤醒、resume token、已应用恢复消息和 child-flow 生命周期事实。
104
+
105
+ WorkCtrlFlow 适合订单履约、轮询/对账、文档生成、多系统交接和具备韧性的服务编排。它不建模人工工作语义;可以等待通用外部结果,但任务域属于 BPCtrlFlow。
106
+
107
+ WorkCtrlFlow 必须把 snapshot、WaitHandle 和恢复消息视为 runtime control facts,绝不回填 definition 或 authoring layout。已记录的 branch decision 在恢复时直接复用,不能因时间、配置或外部数据变化而重新改道。
108
+
109
+ ## BPCtrlFlow:带人工任务事实的业务编排 actor
110
+
111
+ BPCtrlFlow 在 WorkCtrlFlow 上扩展,面向人、角色、任务组和可审计任务结果均为一等事实的长业务过程。它围绕人工工作编排技术步骤,但不把行为树 failure 滥用为业务决策。
112
+
113
+ - `TaskSpace`、`TaskGroup` 和 `Task` 拥有分配、聚合、状态和人工工作生命周期。
114
+ - `TaskStep` 只把任务域结果桥接回公共 data 链。
115
+ - 后续 `If` 路由 `approved`、`refused`、`forwarded`、`abandoned` 等业务 data。
116
+ - 人工并行和汇合只属于 `TaskGroup.executionMode`,不与通用 `Parallel` 竞争事实源。
117
+
118
+ BPCtrlFlow 适合审批、异常处置、运营交接、case management 和需要持久业务审计的过程。非法任务状态迁移、任务存储不可用和恢复协议损坏是技术 fault;等待人工操作是 suspension;人工操作结果是 data。
119
+
120
+ ## FlowContract 与调用
121
+
122
+ 每一种可调用产品都拥有唯一的 `FlowContract` 子域。InstantCtrlFlow、WorkCtrlFlow 和 BPCtrlFlow 的 CtrlFlow contract 声明静态 `input`、`output` 类型引用;WorkCtrlFlow/BPCtrlFlow 额外受 lifecycle capability 约束。FlowContract 不是 runtime validator,也不声明代码实现。
123
+
124
+ ```xnl
125
+ <InstantCtrlFlow #depa.demo.CustomerLookup apiVersion="depa.flows/v1" version="1.0.0" (
126
+ <FlowContract #depa.demo.CustomerLookup {
127
+ input = "vfs://./flow-code/customer.types.ts#CustomerLookupInput"
128
+ output = "vfs://./flow-code/customer.types.ts#CustomerLookupOutput"
129
+ }>
130
+ ) [
131
+ <Run #lookup {
132
+ src = "vfs://./flow-code/customer.ts#lookupCustomer"
133
+ }>
134
+ <Return #result>
135
+ ]
136
+ ```
137
+
138
+ `FlowContract #id` 必须等于产品根 FQN。`CallFlow` 先解析 definition,再解析目标 product form、contract 和允许的 invocation mode;因此 InstantCtrlFlow 不能同步调用一个可能 suspend 的 WorkCtrlFlow。EagerDataFlow 使用端口化 FlowContract,并额外声明 input/output ports。
139
+
140
+ ## Runtime 与 DEPA 边界
141
+
142
+ ```text
143
+ canonical XNL definition
144
+ -> loader / validator / profile capability processor
145
+ -> CtrlFlow AST
146
+ -> derived execution plan
147
+ -> profile runtime actor
148
+ ```
149
+
150
+ - definition XNL 拥有静态 topology、FlowContract 和 config。
151
+ - derived execution plan 是可重建投影,不是新的 authoring 真源。
152
+ - InstantCtrlFlow invocation 只拥有临时调度、取消和当前调用事实。
153
+ - WorkCtrlFlow/BPCtrlFlow runtime actor 拥有持久 snapshot、deadline、attempt、branch decision、lane/candidate state 和 resume message。
154
+ - TaskSpace 拥有人工任务事实;业务结果作为 data 进入后续 predicate。
155
+ - 动态代码通过显式 runtime 取得依赖,不成为 topology 或持久状态的第二 owner。
156
+
157
+ `Retry`、`Timeout`、`Parallel` 和 `Race` 负责 control、fault、cancellation facts。只要 runtime actor 需要跨边界等待、取消确认或恢复,就通过显式 message/port;同步 `Run` 不伪装成 actor。
158
+
159
+ ## 规范约束
160
+
161
+ 该矩阵和边界由 loader、compiler、runtime、examples 与 tests 共同验证。合法 definition 仍可能因为当前 runtime capability 不可用而得到 `runtime-capability-unavailable`;实现不得静默降级成其他 profile 或节点语义。
@@ -0,0 +1,78 @@
1
+ # L3 · flow-core 引用与代码协议
2
+
3
+ > URI 总规则见 M-N4;本页只登记公共 CtrlFlow grammar 使用的 scheme 和 code ref 字段。
4
+
5
+ ## 引用一览
6
+
7
+ | scheme | target | public fields | example |
8
+ |---|---|---|---|
9
+ | `vfs://` | bundle 内/工作区文件与 export | `Run.src`, `Branch.when`, `Until.when`, `Return.src` | `"vfs://./flow-code/quote.ts#isAccepted"` |
10
+ | `config://` | 当前 bundle 的 `ConfigEntry` 或其 sub-path | profile/node config binding | `"config://#pricing/currency"` |
11
+ | `config-def://` | 当前 bundle 的 `ConfigEntryDef` | schema/tooling 引用 | `"config-def://#pricing"` |
12
+ | `flow-authoring://` | 当前 bundle 的 layout entry | editor projection | `"flow-authoring://#route-quote"` |
13
+ | `instant-ctrl-flow://` | InstantCtrlFlow definition / contract | `CallFlow.flow` | `"instant-ctrl-flow://depa.flows.CustomerLookup"` |
14
+ | `work-ctrl-flow://` | WorkCtrlFlow definition / contract | `CallFlow.flow` | `"work-ctrl-flow://depa.flows.OrderFulfillment"` |
15
+ | `bp-ctrl-flow://` | BPCtrlFlow definition / contract | `CallFlow.flow` | `"bp-ctrl-flow://depa.flows.ExpenseApproval"` |
16
+
17
+ profile 可登记额外 scheme,例如 BPCtrlFlow 的 task entry;未在 flow-core 或 profile 表中登记的 scheme 不得凭名称推导。
18
+
19
+ ## Code Ref
20
+
21
+ 动态逻辑统一使用:
22
+
23
+ ```text
24
+ vfs://<file-path>#<export-name>
25
+ ```
26
+
27
+ - `./` 相对当前 bundle 根,`@/` 相对工作区根。
28
+ - export fragment 必填;只指向文件而没有 `#Export` 是无效 code ref。
29
+ - code ref 属于引用它的 statement,直接写在该节点字段上;不经过类型目录或第二次注册。
30
+ - loader 只解析并校验引用;module load、执行和 fault 归一化属于 runtime effect。
31
+
32
+ ```xnl
33
+ <Run #load {
34
+ src = "vfs://./flow-code/order.ts#loadOrder"
35
+ config = { includeHistory = true }
36
+ }>
37
+
38
+ <Branch #approved {
39
+ when = "vfs://./flow-code/order.ts#isApproved"
40
+ } [
41
+ <Return #result {
42
+ src = "vfs://./flow-code/order.ts#approvedResult"
43
+ }>
44
+ ]>
45
+ ```
46
+
47
+ ## Function Contract
48
+
49
+ 每个 code ref 的 export 都遵守同一协议:
50
+
51
+ ```ts
52
+ type FlowCode<Runtime, Input, Config, Output> = (
53
+ runtime: Runtime,
54
+ input: Readonly<Input>,
55
+ config: Readonly<Config>,
56
+ ) => Output | Promise<Output>;
57
+ ```
58
+
59
+ 等价关系是:
60
+
61
+ ```text
62
+ output = fn(runtime, input, config)
63
+ ```
64
+
65
+ - `runtime` 由 profile engine 显式注入,承载长生命周期依赖和 effect 契约。
66
+ - `input` 是不可变的当前值:根从 flow 调用输入开始,之后由上一条 statement 的 output 传入。
67
+ - `config` 来自 statement 的静态 `config` map,缺省 `{}`。
68
+ - 普通代码 output 是 data;predicate code output 必须是 boolean。
69
+ - 技术失败通过 throw/fault 通道表达,不能用业务 data 值伪装。
70
+
71
+ XNL 中禁止函数体、闭包、handler object 和 JavaScript `expr` 字符串。实现不能依赖隐式全局、单例或 `this` 来补充函数签名之外的依赖。
72
+
73
+ ## 解析边界
74
+
75
+ - 逻辑 scheme 只在当前 bundle 内解析,不跨 definition 搜索同名 entry。
76
+ - 跨 bundle 代码复用通过显式 `vfs://` 引用;跨 flow 调用须由对应产品节点和注册 scheme 定义,不能把另一个 manifest 当脚本执行。
77
+ - 所有 URI 都必须写在引号字符串中。
78
+ - `flow-authoring://` 只能解析布局事实,不能用于读取 statement config 或 runtime state。
@@ -0,0 +1,20 @@
1
+ # L3 · InstantCtrlFlow 事实与域
2
+
3
+ > 公共 definition、config 与 layout 规则见 [flow-core 事实与域](../flow-core/domains.md),单文件/目录 bundle 规则见 [flow-core 文件组织](../flow-core/files.md)。InstantCtrlFlow 不增加 authoring domain。
4
+
5
+ ## Capability Table
6
+
7
+ | fact / domain | 状态 | 说明 |
8
+ |---|---|---|
9
+ | `<InstantCtrlFlow>` definition | 启用 | 根 `[]` 直接保存共享 CtrlFlow statements |
10
+ | `config` / `config.def` | 可选 | 使用 flow-core 的静态 config 与 shape facet |
11
+ | `flow.authoring` | 可选 | 只保存布局,不复制 statements |
12
+ | WorkCtrlFlow snapshot / WaitHandle / ResumeSignal | 禁用 | InstantCtrlFlow 不允许持久挂起或恢复 |
13
+ | `state.def` / `state.seed` | 禁用 | InstantCtrlFlow 没有跨调用实例状态 |
14
+ | `task.space` | 禁用 | 人工任务事实只属于 BPCtrlFlow |
15
+
16
+ 单文件是 InstantCtrlFlow 的常见发行形态,但目录 bundle 同样合法。两种形态都以产品 definition 为 topology 真源,code ref 都按 `vfs://...#Export` 解析。
17
+
18
+ ## Rejected Authoring Facts
19
+
20
+ `tree.xnl`、`action.types.xnl`、`Tree` 根、独立 `CtrlFlow` 根以及公开 `Sequence` / `Selector` / `Condition` 都是已移除语法,加载器必须拒绝,不能作为 InstantCtrlFlow 兼容入口。
@@ -0,0 +1,47 @@
1
+ # L3 · InstantCtrlFlow statements
2
+
3
+ > InstantCtrlFlow 完整继承[共享 CtrlFlow statements](../flow-core/nodes.md),不新增 statement,只收窄生命周期能力。
4
+
5
+ ## `<InstantCtrlFlow>` definition
6
+
7
+ 根 `[]` 直接保存有序 statements;没有结构 wrapper:
8
+
9
+ ```xnl
10
+ <InstantCtrlFlow #depa.flows.demo.PriceQuote apiVersion="depa.flows/v1" version="1.0.0" [
11
+ <Run #load-quote {
12
+ src = "vfs://./flow-code/quote.ts#loadQuote"
13
+ }>
14
+ <If #route-quote (
15
+ <Branches [
16
+ <Branch #accepted {
17
+ when = "vfs://./flow-code/quote.ts#isAccepted"
18
+ } [
19
+ <Return #accepted-result { value = { outcome = "accepted" } }>
20
+ ]>
21
+ <Otherwise [
22
+ <Return #review-result { value = { outcome = "review" } }>
23
+ ]>
24
+ ]>
25
+ )>
26
+ ]>
27
+ ```
28
+
29
+ `loadQuote`、`isAccepted` 及其他 code ref 都必须使用 `output = fn(runtime, input, config)`;predicate output 必须是 boolean。
30
+
31
+ ## Allowed Statements
32
+
33
+ | statement | InstantCtrlFlow 语义 |
34
+ |---|---|
35
+ | `Run` | 在当前调用内完成,output 传给下一条 statement |
36
+ | `If` | 按序选择首个为 true 的 Branch,或选择末尾 Otherwise |
37
+ | `Fallback` | 仅在 strategy 发生技术 fault 时尝试下一项 |
38
+ | `Until` | 在当前调用内迭代,受 `maxIterations` guard 约束 |
39
+ | `Return` | 立即结束整个 flow 并返回 output |
40
+
41
+ ## Lifecycle Rejections
42
+
43
+ - `ExternalJob`、`Timer`、`TaskStep`:加载期错误,因为它们需要持久挂起。
44
+ - snapshot、WaitHandle、ResumeSignal、`state.*`、`task.space`:不属于 InstantCtrlFlow 实例模型。
45
+ - `Tree`、`Sequence`、`Selector`、`Condition`、动作类型节点:不是公开 statements;出现即拒绝。
46
+
47
+ 普通业务 data 即使包含 `refused` 或 `declined` 也仍是正常 output。只有 throw/fault 进入技术失败通道;InstantCtrlFlow 不把业务值或持久 Waiting 伪装成 Failure。
@@ -0,0 +1,29 @@
1
+ # L3 · WorkCtrlFlow 事实与域
2
+
3
+ > 公共 definition/config/layout 见 [flow-core 事实与域](../flow-core/domains.md)。WorkCtrlFlow 只增加持久实例 state facet;snapshot 和 WaitHandle 是 runtime facts,不是 authoring topology。
4
+
5
+ ## Authoring Facts
6
+
7
+ | fact / domain | file | root / scheme | 说明 |
8
+ |---|---|---|---|
9
+ | `<WorkCtrlFlow>` definition | 单文件或 `manifest.xnl` | 根 `[]` | 共享 CtrlFlow statements,可使用 `ExternalJob` / `Timer` |
10
+ | `state.def` | `state.def.xnl` | `<StateDef>` / `state-def://` | 可选;声明受版本契约保护的实例 state shape |
11
+ | `state.seed` | `state.seed.xnl` | `<StateSeed>` / `state-seed://` | 可选;新实例的只读初始 state |
12
+ | `task.space` | - | - | 禁用;人工任务事实只属于 BPCtrlFlow |
13
+
14
+ `StateDef` 与 `StateSeed` 通过相同 `#id` 关联。seed 只用于创建新实例,运行期 state 只写 snapshot/store,绝不回写 definition 或 seed。动态代码若访问实例 state,必须经 `runtime` 显式提供的 state effect,函数签名仍是 `output = fn(runtime, input, config)`。
15
+
16
+ ## Runtime Facts
17
+
18
+ | fact | owner | 持久化约束 |
19
+ |---|---|---|
20
+ | snapshot | WorkCtrlFlow instance store | 保存恢复位置、当前 data、state、decisions、等待与幂等事实 |
21
+ | WaitHandle | snapshot/instance store | 以 statement path + token 定位 open/closed wait |
22
+ | ResumeSignal | runtime ingress | 消费后只记录标识与 payload/fault 结果,不进入 definition |
23
+ | branch decision | snapshot | 在进入 Branch body 前记录,恢复时复用 |
24
+
25
+ 实例物化可以冻结 definition bundle 以保证 code 与 topology 版本稳定,但冻结副本仍不是新的 authoring 入口。运行状态可以投影到 editor/runtime overlay;不得向 XNL definition 注入 `status`、执行游标或 decision 作为语义事实。
26
+
27
+ ## Rejected Authoring Facts
28
+
29
+ `tree.xnl`、`action.types.xnl`、`Tree` 根、独立 `CtrlFlow` 根以及公开 `Sequence` / `Selector` / `Condition` 都必须拒绝。snapshot schema、WaitHandle 列表和 branch decision 也不能被伪装成 definition 子域。
@@ -0,0 +1,90 @@
1
+ # L3 · WorkCtrlFlow statements 与恢复
2
+
3
+ > WorkCtrlFlow 继承[共享 CtrlFlow statements](../flow-core/nodes.md),仅增加 `ExternalJob` 与 `Timer`。持久事实的 owner 见 [WorkCtrlFlow 事实与域](domains.md)。
4
+
5
+ ## `<WorkCtrlFlow>` definition
6
+
7
+ 根 `[]` 与嵌套 body `[]` 都直接保存同一套有序 statements:
8
+
9
+ ```xnl
10
+ <WorkCtrlFlow #depa.flows.demo.OrderFulfillment apiVersion="depa.flows/v1" version="1.0.0" [
11
+ <Run #create-pack-job {
12
+ src = "vfs://./flow-code/order.ts#createPackJob"
13
+ }>
14
+ <ExternalJob #await-pack {
15
+ signalKind = "job.completed"
16
+ signalKey = "pack"
17
+ timeoutMs = 86400000
18
+ }>
19
+ <If #route-pack-result (
20
+ <Branches [
21
+ <Branch #completed {
22
+ when = "vfs://./flow-code/order.ts#isCompleted"
23
+ } [
24
+ <Timer #cool-down { durationMs = 60000 }>
25
+ <Return #done { src = "vfs://./flow-code/order.ts#toResult" }>
26
+ ]>
27
+ <Otherwise [
28
+ <Return #not-completed { value = { outcome = "not-completed" } }>
29
+ ]>
30
+ ]>
31
+ )>
32
+ ]>
33
+ ```
34
+
35
+ ```ts
36
+ export function isCompleted(runtime, input, config) {
37
+ return input.status === 'completed';
38
+ }
39
+ ```
40
+
41
+ `createPackJob`、`isCompleted`、`toResult` 都遵守 `output = fn(runtime, input, config)`。恢复不会增加第四个参数;ExternalJob payload 通过正常 output 数据链进入 `isCompleted`。
42
+
43
+ ## `<ExternalJob>`
44
+
45
+ | 字段 | 必填 | 说明 |
46
+ |---|---:|---|
47
+ | `#id` | 是 | 构成稳定 statement path;在途实例不可无迁移改名 |
48
+ | `signalKind` | 是 | 外部消息类别,例如 `"job.completed"` |
49
+ | `signalKey` | 是 | 业务关联键;与 kind、path 一起定位 wait |
50
+ | `timeoutMs` | 否 | 到期 policy;超时走独立技术 fault 通道 |
51
+ | `config` | 否 | 静态 statement config,缺省 `{}` |
52
+
53
+ 首次进入时引擎登记 WaitHandle、保存 snapshot 并返回 suspension。匹配且有效的 ResumeSignal 被消费后,其 payload 成为 ExternalJob output,执行从下一条 statement 继续。payload 中任何业务状态都是 data;只有 ResumeSignal 明确携带的技术 fault 或 timeout policy 才触发 fault。
54
+
55
+ ## `<Timer>`
56
+
57
+ | 字段 | 必填 | 说明 |
58
+ |---|---:|---|
59
+ | `#id` | 是 | 构成稳定 statement path |
60
+ | `durationMs` | 是 | 非负持久等待时长 |
61
+
62
+ Timer 首次进入时保存其 input、deadline 与 WaitHandle 并挂起。到期恢复后 output 等于保存的 input,随后执行下一条 statement;Timer 不制造业务结果,也不依赖原进程存活。
63
+
64
+ ## Branch Decision Record
65
+
66
+ 每次 `If` invocation 的 decision key 必须稳定区分 statement path 与循环/重入 occurrence。记录值至少区分具体 `Branch #id`、`Otherwise`、无匹配三种情况,并在进入 body 前与 snapshot 原子持久化。
67
+
68
+ 恢复时若 decision 已存在,执行器直接进入记录的 body 或 no-op,不再次调用已经发生的 predicate。只有尚未发生的 invocation 才求值 `when`,且 predicate 仍严格返回 `boolean = fn(runtime, input, config)`。
69
+
70
+ ## `<StateDef>` / `<StateSeed>`
71
+
72
+ ```xnl
73
+ <StateDef #order-fulfillment-state {
74
+ requestId = "string"
75
+ attempt = "number"
76
+ }>
77
+
78
+ <StateSeed #order-fulfillment-state {
79
+ attempt = 0
80
+ }>
81
+ ```
82
+
83
+ 两者同 `#id` 关联。seed 缺少的可选字段以未设置开始;seed 出现 def 未声明字段是校验错误。实例 state 由 runtime 的显式 state effect 读写,不替代 statement input/output 数据链。
84
+
85
+ ## Validation And Rejections
86
+
87
+ - `ExternalJob` / `Timer` 只能出现在 WorkCtrlFlow 或 BPCtrlFlow definition。
88
+ - 可挂起 statement 必须有稳定唯一 `#id`;已有 snapshot 的 path 变化需要显式迁移。
89
+ - authoring 中出现 `Tree`、`Sequence`、`Selector`、`Condition`、`action.types` 或 `assignTo` 数据旁路必须拒绝。
90
+ - suspension、业务 data 与技术 fault 必须使用不同 runtime 通道;Fallback 只能消费 fault。
@@ -0,0 +1,31 @@
1
+ # L2 · AICtrlWorkflow axioms
2
+
3
+ `AICtrlWorkflow` is a WorkCtrlFlow-backed AI workflow profile. It uses the same CtrlFlow statement grammar as WorkCtrlFlow and inherits durable waiting, snapshot and resume semantics.
4
+
5
+ ## Substrate
6
+
7
+ - Root tag: `<AICtrlWorkflow>`.
8
+ - Root `[]`: ordered CtrlFlow statements.
9
+ - Root `()`: `FlowContract` plus optional AI workflow resource references.
10
+ - Runtime substrate: WorkCtrlFlow.
11
+
12
+ The definition is still XNL authoring. Runtime messages, material bindings, state store entries and effect results are run facts, not definition facts.
13
+
14
+ ## Runtime context
15
+
16
+ The host wrapper injects:
17
+
18
+ - global AI workflow state root;
19
+ - workspace AI workflow state root;
20
+ - state store;
21
+ - embedded effect provider.
22
+
23
+ The workflow definition must not derive these roots from process cwd, environment variables or hidden authoring directories.
24
+
25
+ ## Effects
26
+
27
+ AI/tool effects are invoked through the embedded provider in runtime context. A statement may call code with `vfs://./...#Export`; that code may use `runtime.ai.effects` or the shared invocation helper. The definition does not name a CLI.
28
+
29
+ ## State projection
30
+
31
+ WorkCtrlFlow snapshots remain the durable execution substrate. AI Ctrl Workflow run records are projections over snapshots plus AI node/material metadata. Adding or changing projection fields must not rewrite historical WorkCtrlFlow snapshots.