feat: expose bounded workflow activation and signal history

This commit is contained in:
2026-09-18 07:56:18 +08:00
parent ae0d08584a
commit 17a8e0126c
35 changed files with 1756 additions and 59 deletions

View File

@@ -226,3 +226,7 @@ PollState新增FirstRound和FirstRoundAttemptsUsed,记录当前激活的首个
## 流程任务直接来源
[WORKFLOW来源](api/task-source.md#5-流程固定来源)复用实例固定版本、步骤、激活、查询轮次及Task.RetryOf;不增加迁移、表、持久化字段或外键。响应模型和独立SDK新增字段均有中文注释,仍为35个持久化实体/305个直接字段声明。沿已有任务唯一索引和步骤代次唯一键核验正反向归属,只返回直接父任务;人工恢复不改写旧任务的历史激活来源。
## 流程历史查询索引
000023_workflow_signal_history只为weave_signals增加(namespace_id,workflow_id,accepted_at,id)分页索引,保留全部原信号数据和状态。仍为35个持久化实体/305个直接字段声明,无新增字段或外键;HTTP/SDK的摘要和详情字段均有中文注释。[历史查询](api/workflow-history.md)明确区分当前逻辑步骤与指定历史激活,不以当前代次替换旧来源。基础测试禁止000008之后再次引入数据库引用约束,真实MySQL升级及readiness验证外键为0。

View File

@@ -28,30 +28,30 @@
| P1 任务受理闭环 | 应用凭据与作用域权限、队列、幂等提交、查询、待执行取消、受理事件;SDK 客户端 | API/SDK 创建查询闭环;重复键与内容冲突、响应未确认重报、跨命名空间拒绝、参数边界 | 已完成并通过阶段回归(见 P1 报告;真实断路/提交 ACK 丢失注入留后续故障阶段) |
| P2 Worker 执行闭环 | WSS 接入、能力/容量、领取与开始、租约、续租、结果确认、排空与恢复;Worker SDK | 真 Worker 执行;失联/重连/重复确认/旧尝试拒绝;业务效果未知转核查;节点故障接管 | 已完成并通过阶段回归:服务端、自动 SDK、历史查询、完整 Schema 与真实进程强杀恢复;测试拓扑和剩余生产故障矩阵见 P2 验收报告 |
| P3 Pulse 完整能力 | 安全重试、延时、Cron/固定间隔、漏跑策略、计划版本、运行中取消、并发许可、配额/背压、可靠结果订阅、批量受理、独立任务核查/人工重试、查询筛选与事务Outbox接入 | 多实例领取/触发竞争、重试上限、取消竞争、队列隔离、积压恢复、事件重复交付 | 已完成平台功能阶段验收:[原范围逐项核对](reports/phase-3.md)、[本轮完整回归](reports/phase-3-delay-recovery.md)。补齐相对延迟、改参数关联示例和四种重试全停恢复场景;20个可运行示例全部通过。全平台生产门槛及SDK首版交付剩余项仍按P6–P7推进 |
| P4 Weave 主流程 | SDK 定义构建与发布校验、实例、顺序/分支/结构化并行汇合、信号/定时等待、版本绑定 | 重启接续、早到/重复信号、并行竞争、内部事件重放、发布版本兼容;端到端通用流程 | 定义格式/词法类型校验、不可变发布、独立SDK及六类节点定义例子已实现,已通过[子项验收](reports/phase-4-definitions.md);已补[有限决策器及内部结果交付](reports/phase-4-engine-core.md);[实例受理及首批事务](reports/phase-4-admission.md)已实现;[结果消费和根接续](reports/phase-4-runtime.md)已接入后台,顺序/分支/并行及真实进程恢复已验证;[TIMER与后续POLL轮次](13-workflow-clock.md)已接入;[信号消费和最终查询竞争](14-workflow-signals.md)已接入内部运行器;[内部控制与停止结清](15-workflow-controls.md)已接入;[内部核查与TASK新激活](16-workflow-recovery.md)已接入;等待恢复已接入内部服务;实例公共API/SDK与基础可运行场景已接入;流程任务来源已接入;完整历史与更多场景继续开发 |
| P5 Weave 恢复与查询 | 有界查询、暂停继续、取消、人工核查恢复、控制门控与审计 | 轮次与尝试独立预算;暂停/开始/回执/超时竞争;恢复保留预算;未知结果不盲目重复 | 有界查询轮次/尝试独立预算及原截止恢复已接入内部运行器;最终信号竞争及在途查询结清已接入;内部暂停/继续/取消与失败结清已接入;执行核查、步骤结论、解除核查及TASK新激活已接入;[POLL跨激活恢复](17-workflow-poll-recovery.md)已接入;等待恢复已接入内部服务;公共API/SDK已接入;流程任务来源已接入;完整历史与更多场景继续开发 |
| P4 Weave 主流程 | SDK 定义构建与发布校验、实例、顺序/分支/结构化并行汇合、信号/定时等待、版本绑定 | 重启接续、早到/重复信号、并行竞争、内部事件重放、发布版本兼容;端到端通用流程 | 定义格式/词法类型校验、不可变发布、独立SDK及六类节点定义例子已实现,已通过[子项验收](reports/phase-4-definitions.md);已补[有限决策器及内部结果交付](reports/phase-4-engine-core.md);[实例受理及首批事务](reports/phase-4-admission.md)已实现;[结果消费和根接续](reports/phase-4-runtime.md)已接入后台,顺序/分支/并行及真实进程恢复已验证;[TIMER与后续POLL轮次](13-workflow-clock.md)已接入;[信号消费和最终查询竞争](14-workflow-signals.md)已接入内部运行器;[内部控制与停止结清](15-workflow-controls.md)已接入;[内部核查与TASK新激活](16-workflow-recovery.md)已接入;等待恢复已接入内部服务;实例公共API/SDK与基础可运行场景已接入;流程任务来源已接入;历史激活/轮次/信号与信号审计已接入;实例列表、统一事件时间线范围核对与更多场景继续开发 |
| P5 Weave 恢复与查询 | 有界查询、暂停继续、取消、人工核查恢复、控制门控与审计 | 轮次与尝试独立预算;暂停/开始/回执/超时竞争;恢复保留预算;未知结果不盲目重复 | 有界查询轮次/尝试独立预算及原截止恢复已接入内部运行器;最终信号竞争及在途查询结清已接入;内部暂停/继续/取消与失败结清已接入;执行核查、步骤结论、解除核查及TASK新激活已接入;[POLL跨激活恢复](17-workflow-poll-recovery.md)已接入;等待恢复已接入内部服务;公共API/SDK已接入;流程任务来源已接入;历史激活/轮次/信号与信号审计已接入;实例列表、统一事件时间线范围核对与更多场景继续开发 |
| P6 生产验证与运维 | 完整监控、凭据轮换、备份恢复、滚动升级、运行手册、可复现负载和故障工具 | 对照生产验收清单执行,报告环境/指标/遗留项;容量、RPO/RTO 按真实拓扑验证 | 待开发 |
| P7 首版交付核对 | SDK 兼容与发布准备、完整 API 手册、场景示例、全量回归及交付清单 | 新接入者按文档跑通全部示例;所有首版能力可追溯到实现与测试;报告实际生产边界 | 待开发 |
SDK、文档与示例随 P1–P5 同步开发,P7 是全量核对,不是最后才开始补文档。
P4/P5定时等待与后续查询轮次的实现及回归记录见[时钟报告](reports/phase-4-clock.md)。外部信号与最终查询竞争见[信号报告](reports/phase-4-signals.md)。公共实例、控制、信号、六类恢复和操作审计已接入HTTP与独立SDK,见[公共接入报告](reports/phase-5-public-api.md)。流程任务来源已接入,完整历史仍须完成。
P4/P5定时等待与后续查询轮次的实现及回归记录见[时钟报告](reports/phase-4-clock.md)。外部信号与最终查询竞争见[信号报告](reports/phase-4-signals.md)。公共实例、控制、信号、六类恢复和操作审计已接入HTTP与独立SDK,见[公共接入报告](reports/phase-5-public-api.md)。流程任务来源及[历史查询](api/workflow-history.md)已接入,实例列表、统一事件时间线及更多恢复示例仍须核对交付。
### P4/P5 下一步实施顺序
1. 已实现FAIL_AFTER_SETTLED与显式取消的内部分支结清,见[控制报告](reports/phase-5-controls.md):持久取消意图、复用Pulse取消、收集已发出查询/任务结果、等待全部已激活工作结清后才进入失败或取消终态。效果未知仍保留核查。
2. 已实现实例暂停/继续/取消内部操作,以control_revision、操作幂等身份、明确原因及审计保护控制决定;暂停不延长原截止,继续不覆盖核查或取消状态。
3. 已实现内部执行核查、步骤结论、解除核查及TASK新激活和旧激活隔离,见[核查报告](reports/phase-5-recovery.md)。POLL跨激活恢复已实现(见[查询恢复](17-workflow-poll-recovery.md));[核查后PENDING接续和独立等待重建](18-workflow-wait-recovery.md)也已接入内部服务,保留原预算、轮次、结果和证据。
4. 实例/当前步骤/信号/控制/六类恢复及流程操作审计HTTP和独立SDK已接入,步骤查询返回实际激活代次;并行执行与信号回执场景已有可运行示例。继续补齐实例筛选分页、完整激活/轮次/信号历史及信号资源审计,并提供独立轮询及恢复示例;[Pulse任务流程来源](api/task-source.md#5-流程固定来源)已交付。逐项验证原键恢复、权限、版本冲突、竞争与进程全停。
4. 实例/当前步骤/信号/控制/六类恢复及流程操作审计HTTP和独立SDK已接入,步骤查询返回实际激活代次;并行执行与信号回执场景已有可运行示例。激活/轮次/信号历史及信号资源审计已接入;继续补齐实例筛选分页、核对统一状态事件时间线,并提供独立轮询及恢复示例;[Pulse任务流程来源](api/task-source.md#5-流程固定来源)已交付。逐项验证原键恢复、权限、版本冲突、竞争与进程全停。
5. 转入P6/P7的生产故障、容量、运维、发布与全部文档核对。内部存储阶段通过不会提前勾选公共接口或生产验收。
公共接入按以下调用链推进;本批已接入启动/当前详情、控制、信号、六类恢复和流程操作审计,并提供独立SDK及基础示例。任务流程来源也已接入。以下完整历史、分页和更多独立场景继续交付:
公共接入按以下调用链推进;本批已接入启动/当前详情、控制、信号、六类恢复和流程操作审计,并提供独立SDK及基础示例。任务流程来源和有界历史查询也已接入。以下实例分页、统一事件时间线范围核对和更多独立场景继续交付:
| 调用链 | 需要补齐的内容 | 验收重点 |
| --- | --- | --- |
| 启动与读取 | 显式固定版本启动、当前实例、步骤及当前激活代次;后续补筛选分页和单次有界历史读取 | 原键丢回执恢复、当前权限、读取快照一致性、未激活步骤语义 |
| 启动与读取 | 显式固定版本启动、当前实例、步骤及当前激活代次;已补有界历史读取,后续补筛选分页 | 原键丢回执恢复、当前权限、读取快照一致性、未激活步骤语义 |
| 控制与信号 | 暂停/继续/取消、固定步骤和代次的信号提交及原受理回执 | control_revision与通用revision区分、迟到/旧代次、暂停期间结果收集 |
| 核查与追踪 | 六类人工恢复操作、完整激活/轮次/等待/信号历史读取及信号管理审计;Pulse任务流程来源已交付 | 当前实例/步骤/任务版本、证据和显式声明、旧历史保留、有界响应和权限隔离 |
| 核查与追踪 | 六类恢复、激活/轮次/等待/信号历史读取及信号管理审计已接入;统一状态事件时间线待核对;Pulse任务流程来源已交付 | 当前实例/步骤/任务版本、证据和显式声明、旧历史保留、有界响应和权限隔离 |
| 通用接入场景 | 并行汇合、外部回执、有限轮询、暂停核查恢复的可运行SDK示例 | 真实Worker执行、完整进程退出后接续、未知效果保留、全链路回归 |
接口只使用已经落地的内部事务规则;SDK保持独立module,不能引用服务端模型或数据库实现。生产故障及容量结论仍由P6专门验收。
@@ -130,6 +130,8 @@ P4/P5定时等待与后续查询轮次的实现及回归记录见[时钟报告](
## 7. 文档入口
- [流程历史查询与SDK](api/workflow-history.md)
- [历史查询验证记录](reports/phase-5-history.md)
- [流程实例公共API](api/workflows.md)
- [流程恢复API及SDK](api/workflow-recovery.md)
- [并行作业与回执示例](examples/workflow.md)

View File

@@ -22,6 +22,7 @@
| [11 Weave实例受理](11-workflow-admission.md) | 固定版本、初始图和首批任务事务 |
| [12 Weave结果消费与推进](12-workflow-runtime.md) | 后台消费、根接续、事务与进程恢复,及尚未完成的等待/控制边界 |
| [13 Weave定时等待与查询轮次](13-workflow-clock.md) | 原截止、轮次/尝试预算、时钟检查点、升级与全停恢复 |
| [流程历史查询](api/workflow-history.md) | 指定历史激活、查询轮次、信号摘要与信号资源审计 |
| [接口手册](api/README.md) | 实际接口状态、调用说明与后续接口规划 |
| [SDK 与场景](sdk/README.md) | 可运行示例、接入方法及分阶段 SDK 交付 |

View File

@@ -28,6 +28,7 @@
| `/v1/events/connect` | 已实现 WSS、消息 Schema、连接 SDK 和自动消费器 | [消息协议](subscriptions.md#5-websocket-建连与边界) / [消费 SDK](../sdk/event-consumer.md) |
| `/v1/workflow-definitions` 创建、发布与固定版本读取 | P4定义子项已实现,实例另用启动接口 | [定义接口](workflow-definitions.md)、[格式规范](workflow-definition-format.md) |
| `/v1/workflows`、步骤详情、控制、信号及操作审计 | 已接入HTTP与独立SDK | [实例接口](workflows.md) |
| 历史激活/轮次/信号列表、历史激活详情及信号资源审计 | 已接入有界分页HTTP与独立SDK | [历史查询](workflow-history.md) |
| `/v1/workflows/{id}/recovery/*` 六类人工恢复 | 已接入有证据恢复及独立SDK | [恢复接口](workflow-recovery.md) |
未实现路由返回 404。健康检查就绪不表示任务执行、定时调度或流程引擎已经可用。

View File

@@ -0,0 +1,164 @@
# 流程激活、查询轮次、信号与信号审计
状态:HTTP与独立Go SDK已接入;本页查询明确指定的历史激活,不跟随逻辑步骤的当前激活。实例筛选分页、统一状态事件时间线及更多独立恢复场景仍按[开发计划](../08-development-plan.md)核对与交付。测试与范围见[本批报告](../reports/phase-5-history.md)。
## 1. 路由与调用规则
所有接口为GET,成功200,使用`Authorization: Bearer <token>`,不需要请求体或幂等键。`{id}`是流程实例ID,`{activation}`是激活ID,`{signal}`是信号ID,`{operation}`是审计记录ID;均为32位小写十六进制。`{key}`是固定定义中的步骤键,1–64个ASCII字符,首位字母或数字,之后允许字母、数字、`_ . -`,禁止内部`$root`。操作审计的operation_id不是查询路径中的审计ID。
| 路径 | 权限 | SDK方法 |
| --- | --- | --- |
| `/v1/workflows/{id}/steps/{key}/activations` | workflows:read | ListWorkflowActivations(ctx, id, key, page) |
| `/v1/workflows/{id}/steps/{key}/activations/{activation}` | workflows:read | GetWorkflowActivation(ctx, id, key, activation) |
| `/v1/workflows/{id}/steps/{key}/activations/{activation}/rounds` | workflows:read | ListWorkflowPollRounds(ctx, id, key, activation, page) |
| `/v1/workflows/{id}/signals` | workflows:read | ListWorkflowSignals(ctx, id, page) |
| `/v1/workflows/{id}/signals/{signal}/operations` | workflows:audit:read | ListWorkflowSignalOperations(ctx, id, signal, page) |
| `/v1/workflows/{id}/signals/{signal}/operations/{operation}` | workflows:audit:read | GetWorkflowSignalOperation(ctx, id, signal, operation) |
服务端先校验命名空间和固定流程引用的全部队列,再读取子资源。普通流程读取权限不包含审计权限;bootstrap用`--workflow-audit-access`显式签发审计权限。知道激活、任务、信号或审计ID不能绕过父资源权限。
四个列表只接受可选`limit`、`cursor`。limit为十进制整数1–100,省略默认20;SDK的`HistoryPageRequest.Limit=0`表示省略。cursor最多1024字节,按URL查询参数编码,必须来自相同查询种类、实例以及对应步骤/激活/信号。未知、重复或非法参数返回400;详情不接受查询参数。
每页最多读取limit+1条判断后续,空列表返回`items: []`,没有下一页时省略next_cursor。游标不是授权凭据;改权限后继续分页仍重新授权。翻页之间不是固定数据库快照,状态可能变化、新记录可能产生;要看最新记录需重新从第一页开始,不能把游标用于执行或确认操作。
## 2. 激活列表和单次详情
列表按sequence倒序,不聚合input、output、查询预算或等待正文。返回类型是[WorkflowActivationPage](../../sdk/go/workflow_history_types.go):
| 字段 | 类型与含义 |
| --- | --- |
| instance_id、step_id | 字符串,已验证父实例与逻辑步骤 |
| revision | 十进制字符串,本页读取时的实例版本;SDK为uint64 |
| current_activation_id | 可选字符串,本页读取时的当前激活;尚未激活时省略 |
| items | 激活摘要数组,未激活步骤为[] |
| next_cursor | 可选字符串,后续位置 |
每项含id、step_id、sequence(正uint32)、state、revision(uint64字符串)、created_at、updated_at;task_id仅用于TASK直接任务,completed_at仅已保存结束时间时返回。时间均为UTC RFC3339。state反映这条激活当前保存的状态,不代表整个实例状态;核查可能改变记录状态,列表不是每次状态变化的事件流水。
下面是恢复后的第二页,当前激活已经是第2代,本页仍读取第1代:
```json
{
"request_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"data": {
"instance_id": "11111111111111111111111111111111",
"revision": "12",
"step_id": "22222222222222222222222222222222",
"current_activation_id": "44444444444444444444444444444444",
"items": [{
"id": "33333333333333333333333333333333",
"step_id": "22222222222222222222222222222222",
"sequence": 1,
"state": "FAILED",
"revision": "3",
"task_id": "55555555555555555555555555555555",
"created_at": "2026-09-18T08:00:00Z",
"updated_at": "2026-09-18T08:00:01Z",
"completed_at": "2026-09-18T08:00:01Z"
}]
}
}
```
详情的data为`{instance_id, revision, step, activation, input, output?, poll?, wait?}`:
- `step`是[逻辑步骤当前视图](workflows.md#3-步骤及当前激活),`activation`是明确请求的历史激活摘要,两者的激活ID和代次允许不同。
- `input/output`只属于指定激活。缺失output与显式null不同,精确JSON数字由SDK的json.RawMessage保留;不会展开其他激活大正文。
- POLL的`poll`返回这一激活的first_round、first_round_attempts_used、used_rounds、冻结上限、原截止和最后任务。字段与[当前查询详情](workflows.md#3-步骤及当前激活)一致,范围改为指定激活。
- SIGNAL、TIMER和有最终信号的POLL返回该激活的wait,包含原等待ID、原截止、状态和已有赢家。恢复后旧等待仍可读,新激活不能延长原截止或替换旧winner。
- TASK尝试、未知结果和迟到证据通过task_id继续查询[执行历史](execution-history.md)。人工决定的前后摘要通过[流程操作审计](workflows.md#6-操作审计与错误处理)读取。
## 3. POLL轮次列表
data为`{instance_id, revision, activation_id, items, next_cursor?}`,items按业务轮round倒序。每项为`{id, activation_id, round, task_id, created_at}`;round是正uint32,其他身份为字符串。
必须明确指定一个POLL激活;TASK或其他节点调用返回400。人工恢复同一业务轮会新建激活和任务,因此“第1代的业务第1轮”和“第2代的业务第1轮”可以同时存在。先遍历激活,再遍历每个激活的轮次,不能把激活序号、业务轮次和Pulse尝试epoch混为一谈。
```json
{
"request_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"data": {
"instance_id": "11111111111111111111111111111111",
"revision": "20",
"activation_id": "44444444444444444444444444444444",
"items": [{
"id": "66666666666666666666666666666666",
"activation_id": "44444444444444444444444444444444",
"round": 1,
"task_id": "77777777777777777777777777777777",
"created_at": "2026-09-18T08:00:02Z"
}]
}
}
```
列表显式验证每轮任务属于该命名空间、激活、固定队列和门控。关联损坏不返回部分成功,也不利用外键推断归属。GetTaskSource可以反向核对[固定来源](task-source.md#5-流程固定来源)。
## 4. 信号与信号资源审计
信号列表data为`{workflow_id, revision, items, next_cursor?}`,按accepted_at和id倒序。每项含id、workflow_id、revision、name、payload_version、target_step_key、target_activation_sequence、state、accepted_at、expires_at,有处置原因时增加disposition。列表不携带payload、correlation_key、actor_id或evidence_ref;完整原信号使用[GetWorkflowSignal](workflows.md)读取。
早期未核验历史可能payload_version为空、target_activation_sequence为0,列表保留这些事实,不补造可执行身份。CONSUMED表示该信号已消费,单条详情的consumed_wait_id与指定历史激活的wait.winner_signal_id可以交叉核对。
信号操作列表data为`{items, next_cursor?}`,按created_at和id倒序,每项含id、workflow_id、signal_id、operation_id、actor_id、action、created_at。当前受理动作action为`workflow.signal`。操作详情的data直接是该摘要,再增加reason、可选evidence_ref、before和after:
```json
{
"request_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"data": {
"id": "88888888888888888888888888888888",
"workflow_id": "11111111111111111111111111111111",
"signal_id": "99999999999999999999999999999999",
"operation_id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"actor_id": "cccccccccccccccccccccccccccccccc",
"action": "workflow.signal",
"created_at": "2026-09-18T08:00:02Z",
"reason": "verified external completion",
"evidence_ref": "proof:event-1",
"before": null,
"after": {"signal_id": "99999999999999999999999999999999", "state": "PENDING"}
}
}
```
上例after省略其他受理身份字段,完整内容以原操作保存的JSON为准。after是原受理审计,之后信号已消费也不能把其中PENDING改成CONSUMED。此接口只查`workflow_signal`资源,流程推进/控制/恢复操作在流程审计中。普通信号消费状态通过Get/List查看,不能将本接口解释成所有内部状态事件的统一时间线。
## 5. SDK调用场景
以下代码接在已配置client与ctx、已知workflowID及stepKey的调用方中;page使用SDK类型,与服务端模型无依赖:
```go
cursor := ""
for {
page, err := client.ListWorkflowActivations(ctx, workflowID, stepKey,
orbit.HistoryPageRequest{Limit: 20, Cursor: cursor})
if err != nil { return err }
for _, activation := range page.Items {
detail, err := client.GetWorkflowActivation(ctx, workflowID, stepKey, activation.ID)
if err != nil { return err }
fmt.Printf("activation=%s sequence=%d state=%s\n",
detail.Activation.ID, detail.Activation.Sequence, detail.Activation.State)
// 按需读取单次结果;禁止拿当前step的代次冒充历史激活代次。
}
if page.NextCursor == "" { break }
cursor = page.NextCursor
}
```
POLL继续用ListWorkflowPollRounds(ctx, workflowID, stepKey, activation.ID, page)分页获取该次激活的任务,再按任务查询尝试和证据。信号场景用ListWorkflowSignals定位旧代次和当前代次的信号;具备审计权限后用ListWorkflowSignalOperations和GetWorkflowSignalOperation读取原因与原受理证据。
[可运行并行作业示例](../examples/workflow.md)会核对已完成等待的历史赢家与CONSUMED信号。[SDK真实链路测试](../../sdk/go/workflow_instances_integration_test.go)另外覆盖TASK恢复、SIGNAL换代、POLL同轮恢复及下一业务轮分页;入口为`make integration`。调用方法见[SDK源码](../../sdk/go/workflow_history.go),各字段中文注释见[独立类型](../../sdk/go/workflow_history_types.go)。
## 6. 错误、部署与兼容
| HTTP / 错误码 | 含义与处理 |
| --- | --- |
| 400 INVALID_ARGUMENT | 身份、步骤键、分页参数或游标范围错误;或非POLL读取轮次。修正查询,不能丢掉筛选继续 |
| 401 UNAUTHENTICATED | 凭据无效或过期,按[认证协议](authentication.md)处理 |
| 403 PERMISSION_DENIED | 缺少读取或显式审计权限 |
| 404 NOT_FOUND | 父/子资源不属于该作用域、不存在或队列不可访问;不跨资源查找 |
| 503 UNAVAILABLE | 关联损坏或数据库暂不可用;保留资源身份并检查服务记录,不能将空列表当作成功 |
所有查询只读,不重算截止、重置预算、消耗轮次或触发恢复。SDK拒绝非法路径/分页及响应父资源不匹配;不自动创建新身份。读操作网络失败可以按原资源重读,状态可能已经前进。
服务端需先应用`000023_workflow_signal_history`,只增加(namespace_id,workflow_id,accepted_at,id)索引;原数据、迁移历史、模型字段和零外键要求保持。维护窗口和DDL锁需按目标数据库演练。当前SDK仍为开发版,使用与服务端匹配的开发提交;P4/P5整体和生产验收尚未完成。

View File

@@ -2,7 +2,7 @@
状态:下表公共 HTTP 与独立 Go SDK 已接入。定义发布见[定义接口](workflow-definitions.md),人工恢复见[恢复接口](workflow-recovery.md),完整运行例子见[并行作业与回执](../examples/workflow.md)。SDK 尚未发布正式版本,服务端与 SDK 应使用同一开发版本。
实例筛选分页及历史激活/轮次/信号列表继续开发;[Pulse任务流程来源](task-source.md#5-流程固定来源)已接入。旧冻结回执可能不含新增的activation_sequence,应另读当前步骤详情;当前步骤详情只反映当前激活;旧记录保留在数据库,不能把本页的当前视图当作全部历史。
实例筛选分页继续开发;[历史激活、轮次、信号和信号资源审计](workflow-history.md)已接入;[Pulse任务流程来源](task-source.md#5-流程固定来源)已接入。旧冻结回执可能不含新增的activation_sequence,应另读当前步骤详情;当前步骤详情只反映当前激活;旧记录保留在数据库,不能把本页的当前视图当作全部历史。
## 1. 路由、权限与 SDK
@@ -155,7 +155,7 @@ name/payload_version/target_step_key必填,分别最多128/32/64个ASCII名称
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读取,信号资源审计列表及完整激活历史继续开发。
该接口当前查询resource_kind=workflow的启动、推进、控制和恢复审计;独立任务核查审计通过恢复回执的task_audit_id关联。信号自身的受理状态通过GetWorkflowSignal读取;[信号资源审计及历史激活查询](workflow-history.md)使用独立路由,统一状态事件时间线仍待核对交付。
| HTTP/错误码 | 处理方式 |
| --- | --- |

View File

@@ -185,5 +185,5 @@
- [来源接口与SDK](../api/task-source.md)随现有tasks、schedules、recovery和workflow四个示例运行,无额外服务或数据库表。
- 步骤:取得任务ID → GetTaskSource → 区分普通提交/人工重试/计划触发 → 按权限读取父任务或固定计划版本。
- 预期:source_kind分别为DIRECT、MANUAL_RETRY、SCHEDULE;人工重试关联原任务,计划任务保留实际触发版本。
- workflow示例逐项核对三个任务所属流程、固定版本、逻辑步骤及创建激活,输出workflow_sources_verified=3;恢复旧激活和POLL轮次由SDK集成测试覆盖。
- workflow示例逐项核对三个任务所属流程、固定版本、逻辑步骤及创建激活,输出workflow_sources_verified=3;示例同时查询历史等待赢家与已消费信号;恢复旧激活、原等待截止和POLL轮次分页由SDK集成测试覆盖。
- 异常:来源缺失或归属不匹配返回503,不能降级为DIRECT;新版本不覆盖历史版本,引用查询不授予完整计划或流程读取权限。

View File

@@ -38,6 +38,7 @@ CreateWorkflowDefinition → PublishWorkflowVersion(v1) → StartWorkflow →
```text
workflow=<32位实例ID> state=SUCCEEDED result={"text":"HELLO ORBIT"} start_deduplicated=true signal_deduplicated=true
workflow_sources_verified=3 fixed_version=v1
workflow_history_verified=true signal_state=CONSUMED
worker_drained=true started=3 confirmed=3
```
@@ -55,4 +56,4 @@ worker_drained=true started=3 confirmed=3
[公共SDK集成测试](../../sdk/go/workflow_instances_integration_test.go)还实际运行:启动响应丢失的原键恢复;暂停/继续、定时等待、信号消费和取消;UNKNOWN执行核查、步骤结论及解除核查;剩余尝试内TASK重试与SIGNAL换代;确认PENDING后沿原查询预算继续。使用`make integration`在一次性环境复现。
历史激活列表、更多独立业务示例及生产验收仍按[计划](../08-development-plan.md)推进。
历史激活和信号列表已接入,示例核对指定历史等待的winner与信号CONSUMED状态。实例筛选分页、更多独立业务示例及生产验收仍按[计划](../08-development-plan.md)推进。

View File

@@ -0,0 +1,34 @@
# P4/P5 流程历史查询回归
日期:2026-09-18。本批交付指定历史激活、POLL轮次、信号摘要及信号资源操作审计的HTTP与独立SDK;不将这些列表等同于统一状态事件时间线,P4/P5仍保留实例筛选分页和独立恢复场景等剩余项。
## 实现与验证边界
- 六条只读路由:激活列表/详情、单激活的查询轮次列表、信号列表、信号操作审计列表/详情。所有父资源按命名空间与固定流程全部队列授权,审计使用显式workflows:audit:read。
- 列表默认20、最多100,游标绑定查询类型及父资源,数据库limit+1判断下一页;不聚合输入/结果/信号正文。单条详情保留精确JSON,区分当前逻辑步骤和明确请求的历史激活。
- 人工恢复后的旧TASK、POLL和SIGNAL/TIMER等待可读,原截止、轮次与尝试预算不重算;POLL同轮恢复跨激活,后续新业务轮仍单独编号。旧等待赢家须对应原消费信号和原代次。
- 信号列表保留早期未核验身份,不补造契约或激活序号。信号受理审计的原PENDING快照与后来CONSUMED状态分开。没有新增状态推进、恢复授权或业务副作用。
- 迁移000023只添加信号历史分页索引,无新模型字段、表或外键。历史迁移不回改;基础测试禁止000008之后重新引入引用约束,readiness继续拒绝实际数据库中的外键。
## 验证记录
环境:darwin/arm64、Go 1.27.1、Docker MySQL 8.4.10;一次性隔离数据库、真实Orbit服务与Worker协议,SDK不引用服务端代码。
| 验证 | 实际结果 |
| --- | --- |
| 基础检查 | make fmt/test/vet/build通过,覆盖主模块、独立SDK及两个业务模块 |
| 存储专项 | 17.546秒通过;包括五组历史场景、v22索引升级、历史70外键移除及无外键应用层归属校验 |
| HTTP与SDK专项 | 包24.637秒通过;五组实例场景23.23秒,覆盖六条新增历史路由及原有六类恢复 |
| 可运行示例 | 流程SUCCEEDED,workflow_sources_verified=3、workflow_history_verified=true、signal_state=CONSUMED,三个任务确认并排空 |
| 全量隔离回归 | scripts/test-mysql.sh退出0;存储223.344秒、流程进程恢复49.047秒、流程SDK23.868秒(五组实例22.52秒)、最终进程故障组95.473秒;20个SDK示例及2个独立业务模块全部通过,一次性环境已清理 |
| 模型与文档检查 | 305个直接持久化字段和122个新增协议字段均有中文注释;实际MySQL为v23,外键0、业务字段缺COMMENT为0;1045个本地链接、65段JSON及git diff --check通过 |
存储测试覆盖TASK第2代→第1代分页、原输入/缺失输出、未激活空页、不同步骤/种类游标拒绝、不存在历史身份、TASK误读POLL轮次拒绝、旧任务所有者漂移后不返回部分页;POLL恢复第1轮→第2轮分页与旧预算;SIGNAL/TIMER第1代等待保留原截止;同一受理时刻信号按ID稳定排序、200 KiB正文不进入摘要、旧NULL契约保留、信号资源与操作审计隔离。真实SDK覆盖历史等待winner、恢复前后激活、同轮恢复与下一轮的任务身份,以及原信号审计原因。SDK单元检查非法路径/分页不发送请求及响应父资源不匹配。
v22→当前迁移逐字段比较信号、精确数字、旧身份与时间,检查新增索引及重复迁移;v7→当前验证70外键全部移除、323个既有索引组成项保留、原任务不变,手工注入违规外键会被CheckSchema拒绝。初次历史专项发现两处测试断言不匹配既有契约(缺失output不能作为JSON比较、权限错误码为PERMISSION_DENIED),修正断言后重跑通过。首轮全量发现v9额度升级测试的人工降级夹具未移除本轮新增索引,导致再次升级时报重复索引;已补齐夹具的结构还原,不改正式迁移。最终全量结果在上表记录。
源码:[历史存储](../../internal/storage/mysql/workflow_history.go)、[信号历史与审计](../../internal/storage/mysql/workflow_signal_history.go)、[专项回归](../../internal/storage/mysql/workflow_history_integration_test.go)、[索引升级](../../internal/storage/mysql/workflow_history_upgrade_integration_test.go)、[零外键升级](../../internal/storage/mysql/no_foreign_keys_integration_test.go)、[迁移约束检查](../../internal/storage/mysql/no_foreign_keys_test.go)、[HTTP路由](../../internal/transport/httpserver/workflow_history.go)、[独立SDK](../../sdk/go/workflow_history.go)、[真实SDK链路](../../sdk/go/workflow_instances_integration_test.go)。完整复现入口为`make integration`,见[脚本](../../scripts/test-mysql.sh)。
## 继续交付
实例筛选分页、统一状态事件时间线的原范围核对,以及独立POLL、核查和暂停恢复示例继续推进;再逐项核对P4/P5原功能与异常矩阵,开展P6/P7监控、凭据轮换、运维、容量及生产故障验收。本地回归没有证明生产复制、跨故障域部署、目标容量或实际RPO/RTO;列表跨页也不提供固定数据库快照。

View File

@@ -6,6 +6,8 @@ module:`git.yuntuo.hk/k2safe/orbit/sdk/go`。SDK 使用独立 go.mod,依赖
任务相对延迟使用SubmitTaskRequest.DelayMS,由数据库首次受理时间计算,原键重报不重新计时;[完整延迟示例](../examples/delayed-task.md)包含Worker执行和历史核对。非零DelayMS不能与AvailableAt同用,旧服务须先升级。
[流程历史查询](../api/workflow-history.md)已提供激活/轮次/信号有界分页、历史等待与预算详情及显式权限的信号操作审计;当前视图与指定历史激活分开。
## 1. 从初始化到运行示例
需要 Go 1.27.1、MySQL 8.4+。在仓库根目录,通过环境设置专用 ORBIT_MYSQL_DSN: