# 工作流

创建、修改和验证工作流，说明节点类型、连线规则、启动和执行记录。

工作流用于把多个业务步骤串成可追踪、可重试的自动化流程。它适合审批、线索跟进、报表生成、消息通知、跨系统同步，以及需要把智能体、模块方法和人工确认组合起来的场景。

## 机器可读入口

本页同时发布为 [Markdown](https://docs.baijimu.com/features/workflows.md)。不要从 HTML 内嵌数据反推结构。以下链接只用于读取历史版本，不是当前 CLI 作者输入格式。当前引用结构以本页为准；人工节点请使用[IssueDefinition 开发教程](/development/bundle-development/issue-definition-development/)的定义和节点示例，不要混用旧 Schema：

- [Workflow Definition JSON Schema 5.0.0](https://docs.baijimu.com/contracts/workflow-definition/5.0.0/schema.json)
- [历史完整工作流 JSON 示例](https://docs.baijimu.com/contracts/workflow-definition/5.0.0/examples/complete-workflow.json)
- [历史 `module_method` 节点 JSON 示例](https://docs.baijimu.com/contracts/workflow-definition/5.0.0/examples/module-method-node.json)
- [历史 `agent` 节点 JSON 示例](https://docs.baijimu.com/contracts/workflow-definition/5.0.0/examples/agent-node.json)
- [历史 `wait.signal` 节点 JSON 示例](https://docs.baijimu.com/contracts/workflow-definition/5.0.0/examples/signal-wait-node.json)
- [历史 5.0.0 `roleKey` 人工候选节点 JSON 示例](https://docs.baijimu.com/contracts/workflow-definition/5.0.0/examples/human-role-candidate-node.json)
- [全站 AI 索引](https://docs.baijimu.com/llms.txt) 与 [结构化页面清单](https://docs.baijimu.com/docs-manifest.json)

当前作者定义通过领域目录选择对象：Module 使用 `module: {bundleId, moduleId}`，Agent 使用 `agent: {bundleId, agentKey}`，子流程使用 `workflow: {bundleId, workflowKey}`。这些身份必须直接使用目录返回值，不能从显示名称推导。引用必须位于当前 Bundle 的源清单或显式依赖闭包内；源清单为对象选择精确版本。CLI 自动读取 Bundle 绑定项目的 Git 提交，服务端按这一快照校验和编译引用，作者无需填写源提交或内部资源定位字段。

方法名和参数合同仍从目标工作区当前 Runtime 的 `methodDefinition` 获取。安装物化由平台完成，作者只选择对象和版本。历史 Bundle Resource Locator 属于内部安装合同，不能复制到当前作者定义。创建 Workflow 前只需冻结其实际引用的对象；Bundle 中尚未引用的应用或模块不会阻塞这一步。

同一 Bundle 中，每个稳定 `workflowCode` 只有一份可变作者定义。服务端 `revision` 只用于乐观并发控制和审计，不是作者字段、资源版本或 CLI 查询选择器；不可变发布使用严格 SemVer：

```bash
baijimu bundle workflow list --workspace-id <WORKSPACE_ID> <bundle> --json
baijimu bundle workflow get --workspace-id <WORKSPACE_ID> <bundle> <workflowCode> --json
baijimu bundle workflow create --workspace-id <WORKSPACE_ID> <bundle> --definition @workflow.json --json
baijimu bundle workflow update --workspace-id <WORKSPACE_ID> <bundle> --definition @workflow.json --json
baijimu bundle workflow publish --workspace-id <WORKSPACE_ID> <bundle> <workflowCode> <semanticVersion> --json
```

`get --json` 返回标准 CModel 响应，完整定义位于顶层 `data` 字段中的 `definition`；同层的 `object` 包含 `type: "WORKFLOW"` 与 Owner 返回的 `workflowKey`。本页示例描述 `create/update --definition` 接受的可写文档，不包含响应 envelope 以及 `id`、`bundleId`、时间戳、当前 Plan 等只读字段；从 `get` 结果生成更新文件时，只复制 `definition` 中的作者字段，不复制 envelope 或内部 ID。

## 创建工作流

创建工作流时，先确定流程的输入、输出和触发方式，再设计节点。

1. 进入目标工作区，确认当前账号具备工作流管理权限。
2. 新建工作流，填写名称、稳定编码和描述。
3. 定义启动输入，例如客户信息、表单数据、订单 ID、触发来源。
4. 添加 `start` 节点和业务节点。
5. 使用连线连接节点，并在需要分支的位置设置连线条件。
6. 设置各节点的输出合同和写入路径；Agent 使用 `result.type + result.path`，其他节点按各自合同配置。
7. 保存后启动一次测试实例，查看执行记录。

> **条件写在连线上**
>
> 工作流不再使用独立的 `condition` 节点表达分支。分支判断应写在节点之间的连线条件里，避免流程图出现只负责转发的判断节点。

## 节点类型

| 节点类型            | 用途                                     | 关键配置                                                       |
| --------------- | -------------------------------------- | ---------------------------------------------------------- |
| `start`         | 流程入口。                                  | 节点 ID、名称、启动输入约定。                                           |
| `end`           | 流程结束并整理输出。                             | 输出字段、输出路径。                                                 |
| `http`          | 调用外部 HTTP 接口。                          | 请求方法、URL、请求头、请求体、超时、重试。                                    |
| `wait`          | 等待外部 signal（推荐）或按计划轮询 HTTP/Runtime 状态。 | `signal` 或 `state + until` 二选一、超时、输出路径。                    |
| `module_method` | 调用已安装 Bundle Module 的方法。               | `module.bundleId + module.moduleId`、方法名、参数、超时、重试、输出路径。     |
| `emit_event`    | 调用已安装 Bundle Module 声明的事件方法。           | `module.bundleId + module.moduleId`、事件名、事件体、幂等键。           |
| `agent`         | 调用 Bundle 中的智能体资源。                     | `agent.bundleId + agent.agentKey`、任务消息、结构化结果合同、完成等待策略。     |
| `human`         | 按 IssueDefinition 创建并等待人工事项。           | IssueDefinition 精确资源版本、显式输入、候选主体、`result.path`。            |
| `subflow`       | 调用并等待子流程完成，使用子流程结果。                    | `workflow.bundleId + workflow.workflowKey`、输入、元数据、超时、输出路径。 |
| `join`          | 汇合并发分支。                                | 汇合策略、输出路径。                                                 |
| `for_each`      | 顺序遍历数组并运行内嵌节点。                         | 数组路径、迭代变量、上限、失败策略、内嵌节点。                                    |

### 类型、配置与输出合同

节点的 `type` 表示处理或执行类型，例如 `human`、`http`、`agent`；它不等于节点的业务输出类型。4.0.0 删除了 `runtimeKind` 和 `scope`，4.1.0 为公开 `wait` 增加了 signal 模式，5.0.0 把 Agent 节点统一为 `message + result + executionPolicy`；合同继续使用封闭的强类型节点集合，未知节点类型和未知字段会被 CLI、workflow-engine 与 workflow-worker 拒绝。`signal_wait` 仅存在于编译后的内部 Plan，作者定义和管理界面都不得直接创建它。

多数节点使用 `outputPath` 指定结果位置；Agent 使用 `result.type + result.path`，human 使用
IssueDefinition 的 `outputType` 和节点的 `result.path`。结果类型属于实际调用合同，不能由下游猜测。

### `subflow`：等待子流程结果

`subflow` 是流程内的组合调用：子流程完成后，父流程才继续该节点的后续连线，`outputPath` 接收子流程结果。
子流程包含 `human` 时，父流程也必须等待人工处理结束。`timeoutSecs` 控制等待超时，不表示后台执行。
节点不接受 `waitForCompletion`，不论值是 `true` 还是 `false`。

```json
{
  "type": "subflow",
  "id": "review_report",
  "workflow": {"bundleId": "operations", "workflowKey": "report-review"},
  "input": {"reportId": "{{input.reportId}}"},
  "outputPath": "reportReview"
}
```

示例中的 Bundle 和工作流身份必须替换为领域目录返回值。

如果主检查流程在报告落库后就应结束，应在报告落库后发布业务事件，由 Event Trigger 启动独立的人工处理流程。
完整配置、输入映射和安装步骤见 [Event Trigger 绑定工作流与输入映射](/development/bundle-development/event-trigger-development/)。
发布节点成功表示事件发布调用成功，不表示人工待办已经创建或处理完成。人工处理失败由其独立流程记录和处置。

迁移旧定义时，显式 `waitForCompletion: true` 可移除；`false` 必须先改成事件触发的独立流程。
已发布资源应从作者源修改后重新发布和安装，不直接改写不可变定义或运行中的快照。

### `human`：先创建业务事项定义，再引用

`human` 创建事项后异步等待人工提交；异步表示等待状态可以持久化和恢复，并不表示节点或所在 Workflow 已完成。
如果业务要求报告生成后当前 Workflow 就结束，人工处理应由业务事件触发独立流程。并发分支、`join` 或 `wait.signal` 都不能替代这一业务边界。

**没有合适的定义时，开发者应在自己的 Bundle 中创建 `ISSUE_DEFINITION`，无需等待平台提供专用定义。**
完整步骤和配套 JSON 见[人工事项定义开发](/development/bundle-development/issue-definition-development/)：
声明 `inputType/outputType` → 创建并发布资源精确版本 → 配置 human → 将 IssueDefinition 和 Workflow
加入 Bundle → 发布并安装 → 验证人工提交与下游结果。

`workflow.human_task` 不是默认依赖。通用定义的输出合同不可见，不应阻塞创建自己的业务定义。

- `issueDefinition` 指定 `bundleId + issueDefinitionId + semanticVersion`，精确版本必须与 Bundle 源清单或依赖闭包一致。
- `input` 显式映射到事项输入，不会隐式发送整个 Workflow 输入和上下文。
- `assignment.mode` 为 `candidates` 时，`assignment.candidates` 必须非空。对工作区成员开放领取须显式使用 `workspace_members`。
- 候选主体支持 `user / department / group / role`。`identityType: "user"` 的 `identityId` 来自有效用户目录；`identityType: "role"` 使用稳定 `roleKey`，角色成员按当前有效关系解析。部门候选不自动包含子部门。
- 候选池决定谁可领取，领取或转交后的唯一处理者记录在 `Issue.assignee`。
- 输出结构由所引用 IssueDefinition 的 `outputType` 拥有。`result.path` 只配置落点，不配置 `result.type` 或节点级 `outputSchema`。
- 不使用旧的 `formSchema`、`role`、`instructions`、`plannerProjection`、顶层 `candidates/outputPath` 字段。
- 人工等待期限使用 `executionPolicy.completionTimeoutSecs`，与 HTTP 超时不同。

`assignment.candidates` 当前必须是显式 JSON 数组；每项 `identityId` 可以用
`{{context.ownerLookup.reviewerUserId}}` 引用前置节点的单个用户 ID，但不能把整个候选数组写成表达式。
单人候选仍需领取，human 当前没有直接设置 `Issue.assignee` 的分配模式。
完整示例及错误说明见[从前置节点读取候选人](/development/bundle-development/issue-definition-development/#从前置节点读取候选人)。

下面展示角色候选节点；实际领域身份和版本应替换为业务资源发布结果：

```json
{
  "type": "human",
  "id": "approve_order",
  "input": {
    "orderId": "{{input.orderId}}"
  },
  "assignment": {
    "mode": "candidates",
    "candidates": [
      {
        "identityType": "role",
        "identityId": "crm.sales"
      }
    ]
  },
  "result": {
    "path": "approval"
  },
  "issueDefinition": {
    "bundleId": "example-crm",
    "issueDefinitionId": "order.approval",
    "semanticVersion": "1.0.0"
  }
}
```

Issue 服务按资源版本的 `inputType` 校验输入、按 `outputType` 校验人工提交的 `resultPayload`。
校验通过后由平台回传结果，写入 `context.approval` 并推进节点；下游消费该定义实际声明的字段。
不存在通用的“批准/拒绝”输出约定，不通过公开 `wait.signal` 接口绕过人工事项。

### `wait` 的两种模式

公开的 `wait` 节点保留一个类型，但配置必须二选一：

- signal 模式（推荐）：配置 `signal` 和可选 `timeoutSecs`。worker 持久化等待状态后释放执行资源，由有权限的业务动作提交 signal 唤醒，不持续占用线程，也不产生周期性 HTTP 请求。
- 轮询模式：配置 `state`、`until`、可选 `failWhen` 与 `schedule`。只用于目标系统不能主动通知、也不能可靠产生事件的兼容场景；每次探测都会形成实际执行成本。

signal 名称分为成功、失败和取消三组，同一个名称不能跨组重复。`successSignalNames` 为空表示任何发往该节点的 signal 都成功完成等待；生产定义通常应填写明确名称，避免业务事件含义不清。signal payload 会成为等待节点的输出，并按 `outputPath` 写入上下文。

```json
{
  "type": "wait",
  "id": "wait_for_inspection_review",
  "signal": {
    "successSignalNames": ["COMPLETED"],
    "failureSignalNames": ["FAILED"],
    "cancellationSignalNames": ["CANCELLED", "STOPPED"]
  },
  "timeoutSecs": 3600,
  "outputPath": "inspection.review"
}
```

向公开 signal 等待节点提交消息时，调用当前工作区的 `POST /workflow-engine/workspaces/{workspaceId}/workflow/signals`，不要填写或保存 worker 主机地址：

```json
{
  "namespace": "workflow.node",
  "correlationKey": "instance:{instanceId}:node:{nodeId}",
  "signalName": "COMPLETED",
  "payload": {
    "decision": "approved"
  },
  "dedupeKey": "inspection-review:{businessEventId}"
}
```

`workspaceId` 来自当前授权工作区，`instanceId` 和 `nodeId` 来自实例执行记录，`dedupeKey` 必须稳定标识同一次业务提交。服务端会校验实例属于该工作区、目标确实是作者定义中的 `wait.signal`，并拒绝借此唤醒 Agent、Human 或其他平台内部等待。调用方不能自选内网地址、内部 namespace 或伪造其他工作区目标。

Agent 节点也使用同一持久化等待原语，但其 signal 由 agent-session 的事务 outbox 自动投递。workflow-engine 在编译时只生成平台内部逻辑节点；agent-session 到 workflow-worker 的地址来自环境资源登记和服务依赖注入，不写入 Workflow 定义，也不在编译时固化某台主机。Agent 完成、失败、停止或取消后都会触发对应终态 signal，worker 恢复流程并只读取一次最终消息。Capability Signal 合同 1.1.0 使用 `nodeId` 定位节点、`signalName` 表示事件名称；旧调用未传 `nodeId` 时仍按原合同解释。

### `agent` 配置合同

| 字段                                      | 必填 | 含义                                                    |
| --------------------------------------- | -- | ----------------------------------------------------- |
| `type`                                  | 是  | 固定为 `agent`。                                          |
| `id`                                    | 是  | 工作流定义内唯一且稳定的节点 ID；运行时用它与实例 ID 派生内部会话 ID。              |
| `agent`                                 | 是  | 从目录选择的 `{bundleId, agentKey}`。                        |
| `message`                               | 是  | 发给 Agent 的任务消息，可引用 `input` 和 `context`。               |
| `result.type`                           | 是  | 平台统一的低代码 Type；可使用 `RefType` 引用命名类型，也可内联匿名 `DataType`。 |
| `result.path`                           | 否  | 结果写入 `context` 的路径；省略时使用节点 ID。                        |
| `executionPolicy.completionTimeoutSecs` | 否  | 等待 Agent 会话进入终态的最长秒数，默认 300；不表示单次 HTTP 请求超时。          |

`result.type` 与模块 Interface 使用的是同一个平台 Type 合同，不是 Workflow 自定义 Schema。
创建 Runtime Projection 时，平台使用统一类型解析器将 `RefType` 物化为具体 `DataType`；
Agent 只接收物化后的 Type，并由适配层转换为模型厂商的
结构化输出参数及执行返回后的本地校验规则。解析结果属于 Workflow Runtime Projection，
不会再写入 Bundle Runtime Plan，也不会引入第二套类型定义。

`workspaceId`、`userId` 和 `sessionId` 均由运行时从受信上下文确定，不是工作流作者参数。
Agent 节点只创建工作区级会话，不支持 `projectId` 或 `projectIdPath`。项目 ID 如属于任务业务
数据，可以在 `message` 中引用，但不会改变会话归属、身份、计费主体或授权边界。

4.x Schema 中的 `promptTemplate`、`outputFormat`、`projectIdPath`、`workspaceIdPath`、`userIdPath`、
`sessionIdTemplate` 和节点级 `timeoutSecs` 已被 5.0.0 删除，不存在双读、别名或兼容优先级。
Agent 资源的创建、发布和 Manifest 引用见
[Bundle Agent 定义、发布与 Workflow 引用](/development/bundle-development/agent-development/)。

```json
{
  "type": "agent",
  "id": "review_order",
  "message": "审核订单 {{input.orderId}}",
  "result": {
    "path": "reviews.order",
    "type": {
      "@type": "DataType",
      "type": "object",
      "properties": {
        "approved": {
          "@type": "DataType",
          "type": "boolean"
        },
        "reason": {
          "@type": "DataType",
          "type": "string"
        }
      }
    }
  },
  "executionPolicy": {
    "completionTimeoutSecs": 600
  },
  "agent": {
    "bundleId": "example",
    "agentKey": "order-reviewer"
  }
}
```

### `module_method` 配置合同

| 字段            | 必填 | 含义                                |
| ------------- | -- | --------------------------------- |
| `type`        | 是  | 固定为 `module_method`。              |
| `id`          | 是  | 工作流定义内唯一且稳定的节点 ID。                |
| `module`      | 是  | 从目录选择的 `{bundleId, moduleId}`。    |
| `method`      | 是  | 该服务当前 `methodDefinition` 中声明的方法名。 |
| `params`      | 否  | 与当前方法参数合同一致的 JSON；可引用运行时数据。       |
| `timeoutSecs` | 否  | 非负整数超时秒数。                         |
| `retryPolicy` | 否  | `maxAttempts`、初始/最大延迟和退避倍数。       |
| `outputPath`  | 否  | 节点结果写入 `context` 的路径。             |

下面是可保存为 `workflow.json` 的完整作者定义。示例对象身份、方法和参数均为占位值；真正提交前必须替换为目录返回的对象身份和目标 Runtime 返回的精确方法合同。旧 5.0.0 Schema 不适用于此作者文档。

```json
{
  "code": "operations-analysis",
  "name": "运营分析示例",
  "description": "演示 module_method 整理输入、Agent 生成结构化分析报告并由 end 输出的完整流程。",
  "status": "draft",
  "startNodeId": "start",
  "inputSchema": [
    {
      "name": "period",
      "type": {
        "@type": "DataType",
        "type": "string",
        "nullable": false
      },
      "description": "分析周期"
    }
  ],
  "outputSchema": {
    "@type": "DataType",
    "type": "object",
    "properties": {
      "analysis": {
        "@type": "DataType",
        "type": "object"
      }
    },
    "required": [
      "analysis"
    ],
    "nullable": false
  },
  "nodes": [
    {
      "type": "start",
      "id": "start",
      "name": "开始"
    },
    {
      "type": "module_method",
      "id": "collect_analysis_input",
      "name": "获取并整理分析输入",
      "method": "buildAnalysisInput",
      "params": {
        "period": "{{input.period}}"
      },
      "timeoutSecs": 30,
      "retryPolicy": {
        "maxAttempts": 3,
        "initialDelayMs": 1000,
        "maxDelayMs": 5000,
        "backoffMultiplier": 2
      },
      "outputPath": "analysisInput",
      "module": {
        "bundleId": "example-operations",
        "moduleId": "operations-data"
      }
    },
    {
      "type": "agent",
      "id": "analyze_operations",
      "name": "生成分析、建议和报告",
      "message": "请基于 {{context.analysisInput}} 完成分析，给出建议并生成可供后续节点消费的报告。",
      "result": {
        "path": "analysisReport",
        "type": {
          "@type": "DataType",
          "type": "object",
          "properties": {
            "summary": {
              "@type": "DataType",
              "type": "string"
            },
            "recommendations": {
              "@type": "DataType",
              "type": "array",
              "items": {
                "@type": "DataType",
                "type": "string"
              }
            },
            "report": {
              "@type": "DataType",
              "type": "string"
            }
          },
          "required": [
            "summary",
            "recommendations",
            "report"
          ]
        }
      },
      "executionPolicy": {
        "completionTimeoutSecs": 600
      },
      "agent": {
        "bundleId": "example-operations",
        "agentKey": "operations-analyst"
      }
    },
    {
      "type": "end",
      "id": "end",
      "name": "结束",
      "output": {
        "analysis": "{{context.analysisReport}}"
      }
    }
  ],
  "edges": [
    {
      "from": "start",
      "to": "collect_analysis_input"
    },
    {
      "from": "collect_analysis_input",
      "to": "analyze_operations"
    },
    {
      "from": "analyze_operations",
      "to": "end"
    }
  ],
  "tags": [
    "example",
    "agent"
  ]
}
```

### `emit_event` 配置合同

`emit_event` 发布已安装 Module 声明的类型化事件。它与模块后端使用的是同一个 Runtime 事件方法，不保存
或调用固定主机地址：

| 字段               | 必填 | 含义                                        |
| ---------------- | -- | ----------------------------------------- |
| `type`           | 是  | 固定为 `emit_event`。                         |
| `id`             | 是  | 工作流定义内唯一且稳定的节点 ID。                        |
| `module`         | 是  | 从目录选择的 `{bundleId, moduleId}`。            |
| `eventName`      | 是  | 目标 Module 当前版本声明的事件名。                     |
| `payload`        | 否  | 与事件 `paramDefinitions` 一致的 JSON，可引用运行时数据。 |
| `idempotencyKey` | 否  | 同一次业务发布的稳定幂等键。                            |
| `timeoutSecs`    | 否  | 事件方法调用的超时秒数。                              |

```json
{
  "type": "emit_event",
  "id": "emit_inspection_submitted",
  "eventName": "inspectionTaskSubmitted",
  "payload": {
    "taskId": "{{input.taskId}}",
    "submittedAt": "{{context.inspection.submittedAt}}"
  },
  "idempotencyKey": "inspection:{{input.taskId}}:submitted",
  "timeoutSecs": 30,
  "module": {
    "bundleId": "example-supervision",
    "moduleId": "supervision"
  }
}
```

Workflow 作者不得填写 Runtime `businessId`、HTTP URL、内部主机或 Authorization。安装物化会从当前
Runtime 的 Bundle 安装资源解析服务并生成授权；通用 `http` 节点不能替代这一步。Module 事件声明、独立
后端回调发布和订阅触发的完整边界见
[模块事件与发布机制](/development/bundle-development/module-development/event-development/)。

## 节点数据引用

节点配置可以引用运行时根对象中的数据：

| 引用         | 含义                           |
| ---------- | ---------------------------- |
| `input`    | 启动流程实例时传入的数据。                |
| `context`  | 前序节点写入的输出和流程运行状态。            |
| `signal`   | 等待节点收到的运行时提交消息；它不是输出结构的定义来源。 |
| `instance` | 当前流程实例元信息。                   |
| `node`     | 当前节点元信息，例如节点 ID 和类型。         |

例如模块方法节点可以把 `input.customerName` 传给创建线索方法，再把结果写入 `context.crm.createLead`，后续节点再读取该路径。

## 配置连线

连线决定节点执行顺序。普通顺序流只需要连接前后节点；分支流需要设置条件；并发流需要在多个分支后使用 `join` 汇合。

设计连线时注意：

- 每个流程必须有且只有一个清晰的起点。
- 除 `end` 节点外，业务节点应有明确后继节点。
- 分支条件要互斥或有默认路径，避免流程停在无匹配路径。
- 并发分支需要明确汇合策略，避免部分分支失败后状态不清。

## 修改工作流

修改工作流前，先确认变更是否影响已经运行中的实例。

- 只改名称、描述、节点展示文案，通常可以直接保存。
- 改节点 ID、输出路径、方法名、参数结构，会影响后续节点读取数据，应重新跑完整测试。
- 改分支条件、人工节点引用的 IssueDefinition 或外部调用，必须覆盖成功、拒绝、超时、失败重试等路径。
- 已经有线上实例运行时，不要直接删除它们正在等待的 `human` 或 `join` 节点。

完成修改并验证后，以新的精确 SemVer 发布不可变资源版本，由后续安装或升级引用新版本；已启动实例继续使用其固定的执行快照，不回读后来修改的作者定义。

## 启动和推进实例

工作流保存后，可以从页面、后端服务、模块方法、定时任务、Webhook 或外部 API 启动实例。启动时传入的 `input` 应包含业务主键、工作区上下文和触发来源，方便排查日志。

手动启动和查询示例：

```bash
baijimu runtime workflow start --workspace-id <WORKSPACE_ID> \
  <APPLICATION_RUNTIME_ID> <environmentKey/bundleId/WORKFLOW/workflowCode> \
  --input @input.json --metadata '{"source":"manual"}' --json
baijimu runtime workflow list --workspace-id <WORKSPACE_ID> \
  --application-runtime-id <APPLICATION_RUNTIME_ID> --json
baijimu runtime workflow get --workspace-id <WORKSPACE_ID> <INSTANCE_ID> --json
baijimu runtime workflow executions --workspace-id <WORKSPACE_ID> <INSTANCE_ID> --json
```

执行用户来自平台验证后的可信请求上下文，并作为 `executionSubjectUserId` 固定在 Workflow 实例上。
Timer 链路中，这个用户来自安装时生成的 ServiceReference 授权绑定；后续 `module_method` 调用继续
使用实例保存的执行用户。`--metadata` 只传递触发来源等可观测信息，其中的
`metadata.requestUserId` 会被删除，不能声明或覆盖执行用户。

当流程停在 `human` 节点时，在对应人工事项中提交符合精确版本 `IssueDefinition.outputType` 的结果。平台校验后回传 signal，并按 human 的 `result.path` 写入 `context`；用户不直接调用公开 signal 接口推进 human。

## 查看执行记录

每次实例运行都会生成节点执行记录。排查问题时按这个顺序看：

1. 实例状态：运行中、等待人工、失败、完成或取消。
2. 当前节点或失败节点。
3. 节点入参和输出。
4. HTTP、模块方法、事件或智能体调用日志。
5. 重试记录和错误信息。

失败实例应从失败节点重试，而不是重新启动一个无关联的新实例。等待人工的实例必须通过 signal 推进，不能用普通恢复动作绕过人工决策。

## 查询权限

| 查询对象                       | CLI                                   | 权限规则                                                                  |
| -------------------------- | ------------------------------------- | --------------------------------------------------------------------- |
| Bundle Workflow 作者定义       | `bundle workflow list/get`            | 目标工作区的有效成员可查询；创建、修改、删除和发布仍要求 Bundle 所有者或工作区 `owner` / `admin`         |
| 已安装 Bundle 和 Workflow 资源台账 | `bundle list/get/resources`           | `list` 对工作区有效成员返回其可见的活跃安装；`get` 和 `resources` 要求工作区 `owner` 或 `admin` |
| Workflow 实例                | `runtime workflow list/get`           | 有效签名用户必须是目标工作区成员；实例必须属于该工作区                                           |
| 节点执行记录                     | `runtime workflow executions`         | 与实例查询相同；实例必须属于目标工作区                                                   |
| Timer 状态和执行记录              | `runtime app timer status/executions` | 有效签名用户必须是目标工作区成员；Application Runtime 必须属于该工作区                         |

这些接口不接受调用方自报的 `userId` 作为权限凭据。CLI 登录凭证必须有效，`--workspace-id` 必须
指向当前用户已经加入的工作区；需要查看完整安装详情或资源台账时，由工作区所有者把用户设为
`owner` 或 `admin`。

## 发布前检查

- 每个节点 ID 稳定、可读，不与其他节点重复。
- 所有模块方法对应的模块已经由目标 Bundle 在工作区 Runtime 中物化成功；不要单独安装模块。
- 所有 HTTP 节点的鉴权、超时和错误返回可追踪。
- 所有人工节点都选择了正确且已发布的 `IssueDefinition`，其表单、处理规则和提交结果合同清楚。
- 所有分支至少覆盖成功、失败和默认路径。
- 测试实例能完成一遍真实业务路径，并能在执行记录中看到每个节点的结果。
