# 执行尝试与证据查询 v1 更新:2026-09-17。四个只读接口及独立 Go SDK 已实现;对应 [可运行示例](../../examples/history/main.go) 和 [回归记录](../reports/phase-2-execution-history.md)。 ## 1. 用途与权限 任务代表一次受理的工作,尝试代表其中一次执行代次。领取后未获开始授权就过期的尝试也会保留,并消耗尝试预算。重连恢复同一次尝试,不创建新的尝试记录。 证据保存 Worker 的迟到、未开始或冲突报告。`outcome=SUCCEEDED` 只是原报告的声明;`disposition=EVIDENCE_ONLY` 表示采集时仅作为证据保存,不能解释为任务成功。权威任务状态与结果使用 [GetTask](tasks.md) 查询。当前只读接口不执行人工裁定、恢复或重试。平台自动重试保留每次失败结果;其规则及任务 effect_uncertain 见 [安全重试](retries.md)。 四个接口均要求 `Authorization: Bearer `、`tasks:read` 动作及任务所属队列范围。凭据确定命名空间,每次调用都重新校验有效性。ID 是 32 位小写十六进制字符串,全部父子关系都校验;知道尝试 ID 或证据 ID 不代表有权读取。 响应为 `application/json`,含 `Cache-Control: no-store`、`X-Content-Type-Options: nosniff`;追踪 ID 同时出现在 `X-Request-ID` 和正文 `request_id`。这些 JSON 供解析使用,不能直接嵌入 HTML。SDK 保留结果中的数字文本,不先转换为 float64。 ## 2. 请求与分页 | 方法和路径 | data 对象 | SDK 方法 | | --- | --- | --- | | `GET /v1/tasks/{task_id}/attempts` | AttemptPage | `ListTaskAttempts(ctx, taskID, page)` | | `GET /v1/tasks/{task_id}/attempts/{attempt_id}` | Attempt | `GetTaskAttempt(ctx, taskID, attemptID)` | | `GET /v1/tasks/{task_id}/attempts/{attempt_id}/evidence` | AttemptEvidencePage | `ListAttemptEvidence(ctx, taskID, attemptID, page)` | | `GET /v1/tasks/{task_id}/attempts/{attempt_id}/evidence/{evidence_id}` | AttemptEvidence | `GetAttemptEvidence(ctx, taskID, attemptID, evidenceID)` | 没有请求体,不需要 Idempotency-Key。仅两个列表接受查询参数: | 参数 | 类型 / 默认 | 限制 | | --- | --- | --- | | limit | 整数,默认 20 | 1–100;SDK 的 0 表示不传、采用默认值,HTTP 显式 0 被拒绝 | | cursor | 字符串,默认空 | 最长 1024 字节;原样使用前一页的 next_cursor,并进行 URL 编码 | 参数只能出现一次;未知字段、重复参数、错误 URL 编码、非法游标均返回 400。详情接口不接受查询参数。游标绑定命名空间、任务、尝试和列表类型,不能跨资源复用,也不能作为授权证明。 尝试按 `epoch DESC`,证据按 `(created_at DESC, id DESC)` 分页,相同微秒时间以 ID 区分。使用索引和位置条件,不使用 offset 或全量 count。`items` 始终为数组,空时为 `[]`;没有下一页时省略 next_cursor。列表不带业务结果正文。 分页不承诺跨请求快照。读取期间尝试状态可能更新、可能出现新记录;刷新最新记录应从空游标重新读取。limit 可以调整,父资源不可改变。 ```sh curl --get "$ORBIT_URL/v1/tasks/$TASK_ID/attempts" \ -H "Authorization: Bearer $ORBIT_TOKEN" --data-urlencode 'limit=20' curl "$ORBIT_URL/v1/tasks/$TASK_ID/attempts/$ATTEMPT_ID" \ -H "Authorization: Bearer $ORBIT_TOKEN" curl --get "$ORBIT_URL/v1/tasks/$TASK_ID/attempts/$ATTEMPT_ID/evidence" \ -H "Authorization: Bearer $ORBIT_TOKEN" \ --data-urlencode 'limit=20' --data-urlencode "cursor=$CURSOR" curl "$ORBIT_URL/v1/tasks/$TASK_ID/attempts/$ATTEMPT_ID/evidence/$EVIDENCE_ID" \ -H "Authorization: Bearer $ORBIT_TOKEN" ``` 变量使用实际资源 ID,首次证据查询的 CURSOR 设为空。成功均为 HTTP 200;响应信封见下方完整示例,ID 和时间为示意值。 ## 3. 尝试字段与响应 | 字段 | 类型 / 是否始终返回 | 含义 | | --- | --- | --- | | id、task_id | string / 是 | 尝试与父任务标识 | | epoch | 十进制字符串 / 是 | 单任务执行代次;SDK uint64 | | concurrency_token | 十进制字符串 / 否 | 有显式资源键时返回跨任务单调许可序号;SDK uint64,无键时为零并省略;历史查询不能授权执行,见 [资源键契约](keyed-concurrency.md) | | state | string / 是 | LEASED、RUNNING、SUCCEEDED、FAILED、CANCELLED、EXPIRED、UNKNOWN;枚举不表示全部状态转换已实现 | | revision | 十进制字符串 / 是 | 记录版本,续租及归属变化可递增;SDK uint64 | | lease_until | UTC RFC 3339 / 是 | 数据库记录的租约期限,**查询不提供执行授权** | | authorized_at | UTC RFC 3339 / 否 | 获批开始时间;省略表示尚未获批,不证明外部效果是否发生 | | ended_at | UTC RFC 3339 / 否 | 尝试结束时间;尚未结束时省略 | | error_code | string / 否 | 稳定错误分类,无错误时省略 | | retryable | bool / 否 | Worker 对明确失败的可安全重试声明,false 时省略;不证明平台实际安排了重试 | | created_at、updated_at | UTC RFC 3339 / 是 | 创建和最近更新时间,最多微秒精度 | | session_id、worker_instance_id | string / 仅详情 | 当前或最后归属会话及进程身份;会话可能因恢复改变,不是完整归属变更日志 | | result | JSON / 仅详情,可省略 | 此尝试已保存的结果;无结果时省略,与追加证据分开 | 列表响应: ```json { "request_id":"44444444444444444444444444444444", "data":{"items":[{ "id":"22222222222222222222222222222222", "task_id":"11111111111111111111111111111111", "epoch":"1","state":"SUCCEEDED","revision":"3", "lease_until":"2026-09-17T08:00:30Z", "authorized_at":"2026-09-17T08:00:01Z","ended_at":"2026-09-17T08:00:02Z", "created_at":"2026-09-17T08:00:00Z","updated_at":"2026-09-17T08:00:02Z" }]} } ``` 详情响应为展开对象: ```json { "request_id":"44444444444444444444444444444444", "data":{ "id":"22222222222222222222222222222222", "task_id":"11111111111111111111111111111111", "epoch":"1","state":"SUCCEEDED","revision":"3", "lease_until":"2026-09-17T08:00:30Z", "authorized_at":"2026-09-17T08:00:01Z","ended_at":"2026-09-17T08:00:02Z", "created_at":"2026-09-17T08:00:00Z","updated_at":"2026-09-17T08:00:02Z", "session_id":"33333333333333333333333333333333", "worker_instance_id":"55555555555555555555555555555555", "result":{"version":"v1","sequence":9007199254740993} } } ``` 不返回 lease_secret、instance_secret、凭据或内部摘要。执行权限必须经过 [Worker 开始/恢复与当前租约确认](worker.md),不能通过历史详情推导。 ## 4. 证据字段与响应 | 字段 | 类型 / 是否始终返回 | 含义 | | --- | --- | --- | | id、task_id、attempt_id | string / 是 | 证据及已校验的父资源标识 | | outcome | string / 是 | 原报告的 SUCCEEDED、FAILED 或 UNKNOWN | | error_code | string / 否 | 原报告的错误分类,空时省略 | | retryable | bool / 否 | 原失败报告的重试声明,false 时省略;证据不触发执行 | | reason | string / 是 | LEASE_LOST(授权失效)、NOT_STARTED(未获批开始)、RESULT_CONFLICT(与已保存结果冲突) | | disposition | string / 是 | 固定 EVIDENCE_ONLY,描述采集处理方式 | | created_at | UTC RFC 3339 / 是 | 首次保存时间,相同身份的重复报告不刷新 | | message_id | string / 仅详情 | 原报告身份,便于追踪同一次重报 | | payload | JSON / 仅详情 | 原报告结果或证据引用,最大 256 KiB,保留精确数字文本 | 列表响应: ```json { "request_id":"44444444444444444444444444444444", "data":{"items":[{ "id":"66666666666666666666666666666666", "task_id":"11111111111111111111111111111111", "attempt_id":"22222222222222222222222222222222", "outcome":"SUCCEEDED","reason":"RESULT_CONFLICT","disposition":"EVIDENCE_ONLY", "created_at":"2026-09-17T08:00:03Z" }]} } ``` 详情响应: ```json { "request_id":"44444444444444444444444444444444", "data":{ "id":"66666666666666666666666666666666", "task_id":"11111111111111111111111111111111", "attempt_id":"22222222222222222222222222222222", "outcome":"SUCCEEDED","reason":"RESULT_CONFLICT","disposition":"EVIDENCE_ONLY", "created_at":"2026-09-17T08:00:03Z", "message_id":"77777777777777777777777777777777","payload":{"version":"v2"} } } ``` 保存 v2 证据不会覆盖尝试中的 v1 结果。查询没有状态变更或去重写入;人工裁定、证据采纳与审计管理属于后续能力。 ## 5. 错误、超时与兼容 | HTTP / code | 处理 | | --- | --- | | 400 INVALID_ARGUMENT | 修正 ID、limit、游标及查询参数;不可盲目重试 | | 401 UNAUTHENTICATED | 核对凭据撤销/到期、应用及命名空间状态 | | 403 PERMISSION_DENIED | 凭据缺少 tasks:read | | 404 NOT_FOUND | 资源不存在、父子不匹配、跨命名空间或不在队列范围内;不区分具体原因 | | 503 UNAVAILABLE | 只读查询失败,可在总体截止内有限退避重试 | ```json {"request_id":"44444444444444444444444444444444","error":{"code":"NOT_FOUND","message":"resource not found"}} ``` 服务端操作期限 8 秒;SDK 默认 HTTP 超时 10 秒,可用 context 缩短。SDK 不自动重试查询;取消查询不取消任务。SDK 业务响应上限 1 MiB,列表通过省略大正文和最多 100 条保持有界。每次重读获得当次数据,不保证与前次完全相同。 当前开发契约为 v1,SDK 尚未发布版本,接入方式见 [SDK 手册](../sdk/README.md)。SDK 忽略新增响应字段;已有字段含义改变需升级契约并回归。跨租户/队列、父子错配、重复证据、同时间戳分页、精确数字和大载荷均有实际回归,见 [验证记录](../reports/phase-2-execution-history.md)。