Failure Classification#

本页是 Perago task attempt 结果状态的精确参考。它回答两个问题:某类失败会回写什么 Conductor status,以及失败结果是否会携带 workspace output。

Perago 的运行时结果只有三个状态:

状态

载荷形状

Conductor 语义

COMPLETED

output required; reasonForIncompletion forbidden

attempt 成功完成。workspace task 已发布 workspace output;workspace-free task 已返回业务 result

FAILED

reasonForIncompletion required; output forbidden

attempt 失败,但不是 Perago 判定的 terminal input-workspace 契约错误。

FAILED_WITH_TERMINAL_ERROR

reasonForIncompletion required; output forbidden

pre guardrail 失败,表示上游提供的 workspace input 不满足任务声明的输入文件契约。

RuntimeTaskResult 会拒绝不一致的载荷形状:完成状态必须有 output,失败状态必须有 reasonForIncompletion,失败状态不能携带 output

Classification Rule#

result_for_exception(...) 目前只有一条特殊规则:

异常类型

Result status

说明

PreGuardrailViolation

FAILED_WITH_TERMINAL_ERROR

task body 尚未运行,输入 workspace 未满足 task 的 pre guardrail。

其他异常

FAILED

包括 bad input、Pydantic 校验失败、业务异常、post guardrail、attempt fence、publish fence 和 LakeFS 操作失败。

这意味着 FAILED_WITH_TERMINAL_ERROR 不是通用的“不可重试”桶。Perago MVP 只把 pre guardrail 放进这个状态;其他失败都保持普通 FAILED,由 Conductor 按生成 TaskDef 中的 retry policy 决定是否重试。

Workspace Task Attempt#

Workspace task 的 attempt 生命周期中,失败分类如下。

阶段

典型原因

Result status

是否发布 workspace output

input validation

input 顶层字段不是 workspaceparamsWorkspaceInput 无效;params 额外字段或类型错误

FAILED

download

LakeFS repository/ref 不存在、连接失败、本机 workspace 写入失败

FAILED

pre guardrails

输入 workspace 缺少必需文件/目录/glob,或命中 forbidden glob

FAILED_WITH_TERMINAL_ERROR

task body

用户函数抛异常,或返回值不能通过 output Pydantic model 校验

FAILED

post guardrails

输出 workspace 文件形状不满足 task 的 post guardrail

FAILED

first attempt fence

task body 后、stage 前发现 Conductor attempt 已不再是当前 attempt

FAILED

stage

workspace 含 symlink、上传/删除/commit 失败

FAILED

second attempt fence

stage 后、publish 前发现 attempt 已失效

FAILED

publish fence / merge

target branch 被无关提交推进、merge 失败或 merge timeout

FAILED

staging cleanup

staging branch 删除失败

保留原始 result

保留原始 result

local cleanup

attempt-local workspace 删除失败

保留原始 result

保留原始 result

Workspace task 只有在 body 成功、post guardrail 通过、两次 attempt fence 都通过、stage 成功且 publish 成功后才返回 COMPLETED。完成 output 会包含 workspaceresult;失败 output 不会带 workspace,也不会把未发布的 attempt-local workspace 暴露给下游。

Workspace-Free Task Attempt#

Workspace-free task 不下载、不发布 workspace,也没有 guardrail 或 publish fence。

阶段

典型原因

Result status

input validation

input 顶层字段不是仅有 paramsparams 额外字段或类型错误

FAILED

task body

用户函数抛异常

FAILED

result validation

返回值不能通过 output Pydantic model 校验

FAILED

success

业务函数返回值通过 output model 校验

COMPLETED

Workspace-free task 的 COMPLETED output 只包含 result。它不会生成 workspace output,也不能通过 TaskControls.publish_budget 配置发布预算。

Conductor Result Payload#

Perago 内部先构造 RuntimeTaskResult,再转换成 Conductor SDK 的 TaskResult

COMPLETED 会写入:

{
  "status": "COMPLETED",
  "output": {
    "result": {
      "valid": true
    }
  }
}

FAILED 会写入:

{
  "status": "FAILED",
  "reasonForIncompletion": "workspace task input must contain only workspace and params"
}

FAILED_WITH_TERMINAL_ERROR 会写入:

{
  "status": "FAILED_WITH_TERMINAL_ERROR",
  "reasonForIncompletion": "pre guardrail require_glob('raw/**/*.parquet') matched 0 files; min_count=1"
}

worker_id 不属于 RuntimeTaskResult payload。worker 向 Conductor 回写结果时会把 worker_id 写入 SDK TaskResult 字段,用于从 Conductor attempt 反查本机 worker 日志目录。

Recovery Boundary#

Perago 的失败分类是 fail-closed 的:

  • publish fence、stale attempt 和 LakeFS merge 错误不会被包装成成功。

  • staging cleanup 和 local cleanup 的错误只写日志,不覆盖原始 task result。

  • merge timeout 或 result update 失败后,不应直接假设 publish 没发生;运维恢复需要检查目标 branch commit metadata。

MVP 不提供严格 exactly-once publication 证明。Reference 中的失败分类只描述 worker 如何回写当前 attempt result;跨 attempt 的恢复判断需要结合 perago.logical_task_keyperago.task_idperago.staging_commit 等发布 metadata。