# 流程实例、控制、信号与操作审计 状态:下表公共 HTTP 与独立 Go SDK 已接入。定义发布见[定义接口](workflow-definitions.md),人工恢复见[恢复接口](workflow-recovery.md),完整运行例子见[并行作业与回执](../examples/workflow.md)。SDK 尚未发布正式版本,服务端与 SDK 应使用同一开发版本。 实例筛选分页、历史激活/轮次/信号列表及 Pulse 任务的流程来源查询继续开发。旧冻结回执可能不含新增的activation_sequence,应另读当前步骤详情;当前步骤详情只反映当前激活;旧记录保留在数据库,不能把本页的当前视图当作全部历史。 ## 1. 路由、权限与 SDK 下文 `{id}` 为32位小写十六进制流程实例ID,不是定义ID;身份和命名空间来自凭据。所有读取均检查固定定义引用的全部队列。变更还需要 `Content-Type: application/json`、`Authorization: Bearer ` 和一个稳定的 `Idempotency-Key`;键最长128字节,字符规则沿用[任务协议](tasks.md)。请求体最大512 KiB,拒绝重复字段、大小写别名、未声明字段和多余查询参数。 | 方法与路径 | 权限 | Go SDK 方法 | | --- | --- | --- | | `POST /v1/workflows` | `workflows:start`;有任务队列时还需 `tasks:submit` | StartWorkflow | | `GET /v1/workflows/{id}` | `workflows:read` | GetWorkflow | | `GET /v1/workflows/{id}/steps` | `workflows:read` | GetWorkflowSteps | | `GET /v1/workflows/{id}/steps/{key}` | `workflows:read` | GetWorkflowStep | | `POST /v1/workflows/{id}/control` | `workflows:control` | ControlWorkflow | | `POST /v1/workflows/{id}/signals` | `workflows:signal` | SendWorkflowSignal | | `GET /v1/workflows/{id}/signals/{signal}` | `workflows:read` | GetWorkflowSignal | | `GET /v1/workflows/{id}/operations` | `workflows:audit:read` | ListWorkflowOperations | | `GET /v1/workflows/{id}/operations/{operation}` | `workflows:audit:read` | GetWorkflowOperation | GET成功为200;启动及信号首次受理为201,原键回执为200;控制成功为200。控制响应表示意图已保存,取消结清由后台完成。SDK签名、独立类型及各字段中文说明见[调用方法](../../sdk/go/workflow_instances.go)和[协议类型](../../sdk/go/workflow_instance_types.go)。 CLI显式开关分别为:`--workflow-access`(定义读/发布)、`--workflow-run-access`(实例读/启动)、`--workflow-control-access`(实例读/控制)、`--workflow-signal-access`(实例读/信号)、`--workflow-recovery-access`(实例读/恢复)、`--workflow-audit-access`(流程操作审计读)。普通 Worker、定义发布及任务核查权限均不会自动获得流程管理权限。初始化会先验证权限集合再交付凭据,具体命令见[示例](../examples/workflow.md)。 ## 2. 固定版本启动 `StartWorkflow(ctx, key, StartWorkflowRequest)` 的请求: ```json { "definition_id": "11111111111111111111111111111111", "version": "v1", "input": {"n": 9007199254740993}, "business_key": "operation-001 " } ``` | 字段 | 类型与约束 | | --- | --- | | definition_id | 必填,当前命名空间的定义ID | | version | 必填,1–64个ASCII版本字符,首字符字母或数字,之后还可用 `_ . -`;不解析latest | | input | 必填,最多256 KiB JSON,必须符合固定版本输入契约;显式null与缺失不同,数字不经过float64 | | business_key | 可选,默认空字符串,最多191个Unicode字符;尾部空格保留,不能替代幂等键 | 示意完整回执: ```json { "request_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "data": { "instance": { "id": "22222222222222222222222222222222", "namespace_id": "33333333333333333333333333333333", "definition_id": "11111111111111111111111111111111", "definition_version_id": "44444444444444444444444444444444", "version": "v1", "state": "RUNNING", "revision": "2", "paused": false, "control_revision": "1", "input": {"n": 9007199254740993}, "business_key": "operation-001 ", "deadline_at": "2026-09-18T08:01:00Z", "created_at": "2026-09-18T08:00:00Z", "updated_at": "2026-09-18T08:00:00Z" }, "deduplicated": false } } ``` `GetWorkflow`的data直接是instance对象。可能状态为RUNNING、WAITING、CANCELLING、NEEDS_REVIEW、SUCCEEDED、FAILED、CANCELLED;paused是独立标记。`output`在存在结果时返回,成功输出可以为显式null。`cancel_requested_at`、`stop_kind`(CANCEL/FAILURE)、`stop_requested_at`、`completed_at`仅有值时返回。所有时间为UTC RFC3339,revision及control_revision为十进制字符串,SDK使用uint64。 启动固定定义版本和总截止,并在同事务创建门控、步骤和首批任务。原键同内容返回**首次受理快照**,不重算时间,不代表当前状态;同键不同内容返回IDEMPOTENCY_CONFLICT。网络响应丢失时保持原键和原请求核对,再用GetWorkflow读取当前状态。每命名空间最多10000个未终结实例,已保存的原回执在满额时仍可恢复。 ## 3. 步骤及当前激活 GetWorkflowSteps返回 `{instance_id, revision, steps}`,steps按key排序、最多128项,不含内部根步骤。每项含 `id/key/kind/state/revision`;已激活时还含 `activation_id/activation_sequence`,TASK还含直接 `task_id`。未激活步骤没有激活ID和代次。步骤状态包括BLOCKED、ACTIVE、WAITING、SUCCEEDED、FAILED、CANCELLED、NEEDS_REVIEW、SKIPPED。 GetWorkflowStep返回单个步骤详情,实例revision与当前步骤同事务读取: ```json { "request_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "data": { "instance_id": "22222222222222222222222222222222", "revision": "8", "step": { "id": "55555555555555555555555555555555", "key": "receipt", "kind": "SIGNAL", "state": "WAITING", "revision": "2", "activation_id": "66666666666666666666666666666666", "activation_sequence": 1 }, "input": {"name": "done", "payload_version": "v1", "correlation": "operation-001 "}, "activated_at": "2026-09-18T08:00:05Z", "wait": { "id": "77777777777777777777777777777777", "kind": "SIGNAL", "state": "WAITING", "name": "done", "payload_version": "v1", "correlation_key": "operation-001 ", "deadline_at": "2026-09-18T08:00:35Z" } } } ``` - `input/output`属于当前激活,每次只读取一份;未激活或尚无输出时省略,显式null保留。`activated_at/completed_at`属于当前激活,不能据新激活时间重算原预算。 - POLL的 `poll` 包含 used_rounds、first_round、first_round_attempts_used、max_rounds、max_attempts_per_round、interval_ms、deadline_at、last_task_id;current_task_id、next_poll_at、resolved_at在有值时返回。last_task_id指当前激活最后业务轮任务,可再通过GetTask读取其状态/版本。 - SIGNAL、TIMER和有最终信号的POLL返回 `wait`,包含当前等待身份、类型、状态、原截止和关联;name/payload_version不适用于TIMER,旧未核验等待也可能缺失。winner_signal_id和resolved_at在有值时返回。已选中赢家不代表在途任务已结清。 - 时间预算不会随人工换代增加。信号发送者应读取activation_sequence,不能把激活ID、步骤revision或任务尝试epoch当作等待代次。 ## 4. 暂停、继续与取消 `ControlWorkflow(ctx, id, key, WorkflowControlRequest)`: ```json {"operation":"PAUSE","expected_control_revision":"1","reason":"维护期间停止推进新工作"} ``` operation必填,为PAUSE/RESUME/CANCEL;expected_control_revision为读取到的非零control_revision字符串,reason为1–1024个Unicode字符,不允许全空白或NUL。成功data为 `{instance, deduplicated}`,instance字段同启动回执。新决定使用旧控制版本返回STATE_CONFLICT;原键恢复仍返回第一次的冻结决定。 PAUSE关闭新执行授权,在途结果继续收集;RESUME不清除NEEDS_REVIEW,不撤销首次停止目标,不延长原截止。CANCEL保存取消意图并停止后继,保留在途许可直到真实执行结束;未知效果仍进入核查。后台任务结果改变通用revision,不要求操作者追逐每个结果去更新control_revision。详细结清规则见[控制设计](../15-workflow-controls.md)。 ## 5. 有身份的外部信号 `SendWorkflowSignal(ctx, id, key, SendWorkflowSignalRequest)`: ```json { "name":"done", "payload_version":"v1", "target_step_key":"receipt", "target_activation_sequence":1, "correlation_key":"operation-001 ", "payload":{"n":9007199254740993}, "reason":"已核验外部回执", "evidence_ref":"evidence:receipt-001" } ``` name/payload_version/target_step_key必填,分别最多128/32/64个ASCII名称字符;代次为非零uint32数字。correlation_key为1–512字节UTF8、精确匹配并保留尾部空格。payload必填、最多256 KiB,符合固定契约时可显式null。reason规则同控制原因;evidence_ref可选、最多512个Unicode字符,不含空白或控制字符,平台不会访问这个引用。 成功data为 `{signal, deduplicated}`。signal字段:id、namespace_id、workflow_id、revision字符串、name、payload_version、target_step_key、target_activation_sequence、correlation_key、payload、actor_id、state、accepted_at、expires_at;evidence_ref、disposition、consumed_wait_id在有值时返回。actor_id从认证获得。GetWorkflowSignal直接返回当前signal对象。 受理与消费分离:PENDING可以稍后变为CONSUMED、REJECTED或EXPIRED。每实例全部历史受理记录最多1024条,原键回执先于上限检查。早到信号可以指定首次代次1;当前旧代次信号保存为REJECTED/STALE_ACTIVATION,未来代次冲突。恢复为新代次后,原信号原键仍返回旧回执,不能用重报改变目标。最终查询与信号按原事件时间竞争,PENDING查询不争夺业务完成权,见[信号设计](../14-workflow-signals.md)。 ## 6. 操作审计与错误处理 ListWorkflowOperations接受HistoryPageRequest:limit默认20、范围1–100;cursor最大1024字节,绑定命名空间、流程ID和查询种类,不可跨资源复用。data为 `{items, next_cursor?}`;每项含 id、workflow_id、operation_id、actor_id、action、created_at,按时间及ID倒序。GetWorkflowOperation除这些字段外还返回reason、evidence_ref(可空省略)、before、after JSON摘要。单独读取正文,避免列表聚合大结果。 该接口当前查询resource_kind=workflow的启动、推进、控制和恢复审计;独立任务核查审计通过恢复回执的task_audit_id关联。信号自身的受理状态通过GetWorkflowSignal读取,信号资源审计列表及完整激活历史继续开发。 | HTTP/错误码 | 处理方式 | | --- | --- | | 400 INVALID_ARGUMENT | 修正字段、固定契约或查询游标;不要把遗漏声明默认成true | | 401 UNAUTHENTICATED / 403 PERMISSION_DENIED | 核对凭据和显式动作权限,重报不会绕过撤权 | | 404 NOT_FOUND | 资源不存在、跨命名空间或队列不在授权范围 | | 409 STATE_CONFLICT / IDEMPOTENCY_CONFLICT | 当前状态/版本不符或原键请求改变;先读取权威状态 | | 409 WORKFLOW_INSTANCE_LIMIT / WORKFLOW_SIGNAL_LIMIT | 固定资源数量上限,不能通过新键盲目补发 | | 429 QUEUE_FULL / APPLICATION_FULL | 新工作配额不足;保持原请求身份核对,服务端给Retry-After | | 413 BODY_TOO_LARGE / 415 UNSUPPORTED_MEDIA_TYPE | 缩小请求或使用application/json | | 503 UNAVAILABLE / 网络异常 | 提交结果可能不明,保持原键和原命令核对;SDK不自动换键 | 已实现路由之外的路径为404。回归证据和剩余交付范围见[公共接入报告](../reports/phase-5-public-api.md)。