[PRD] AI-native Goal Supervisor 与失败自动恢复闭环 #1
Labels
No labels
ready-for-agent
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ivang/ecommerce-tool-monorepo#1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem Statement
用户向 AI 提交 pipeline 任务时,关注的是输入能否转化为最终制品,而不是理解 DataScraping、UPM 映射、LLM 优化、图片处理、聚合或结算中的具体失败步骤。当前系统把某次执行尝试的失败直接投影成用户可见的
failed或partial_failed,并要求用户查看错误、选择失败记录和手动重试。这把内部实现复杂度泄漏给用户,也使飞书 Bot、Web、Codex 和各 pipeline 各自承担一部分恢复逻辑。一次失败本质上只是执行过程中观察到的内部事实。它可能包含网络超时、模型输出异常、源数据不可用、权限不足、程序缺陷或验收不通过等细节,但不应天然等同于用户目标失败。系统需要在保留完整失败事实和审计链的同时,持续尝试确定性恢复或受约束 Agent 修复,直到产生满足验收标准的制品、确实需要用户输入,或耗尽有界恢复预算。
现有 task-hub 已承担飞书渠道、Codex 派发和事件回流,但其 Task 使用 JSON Store,
failed是不可退出终态,部分 watcher 依赖进程内状态;现有 Reliable Task Engine 已具备 Postgres task/item/attempt ledger、lease 和 transactional outbox。两者尚未形成以 Goal 为中心的持久化自动恢复闭环。Solution
把系统升级为 AI-native Goal Supervisor:用户提交的是带验收标准的 Goal,pipeline Task 和每次 Attempt 都只是实现 Goal 的内部执行。任何 Attempt 失败时,由领域执行模块原子记录 Failure Case 并通过 outbox 发布标准化失败事件;task-hub 中新增持久化 Recovery Coordinator,消费这些事件,优先执行领域内确定性恢复,必要时向 Codex 派发带上下文、授权范围、恢复预算和验证规则的结构化 Repair Plan。修复后的结果必须经过独立 Verifier 验证,验证成功才把 Goal 投影为
delivered。用户默认只看到
accepted -> working -> verifying -> delivered。内部失败在恢复预算未耗尽时仍属于working,不要求用户理解具体步骤。只有缺少输入或授权时进入needs_input,只有所有允许的恢复策略和预算均耗尽后进入exhausted。原始失败、后续 Attempts、Repair Plans 和制品版本全部追加保存,不通过覆盖历史记录伪造成功。总体流程:
User Stories
Implementation Decisions
exhaustedis a final Goal failure.working,needs_input,deliveredorexhausted. Classification, budgets, Codex dispatch and verification remain hidden in its implementation.task.failure.recorded,task.attempt.succeeded,task.artifact.createdand related lifecycle events atomically with domain state changes.detailRef; apply sanitization, encryption and retention policies before persistence or Agent dispatch.failureId + repairGenerationas the idempotency identity. Repeated events, HTTP retries and restarts must resolve to the same observable execution.failedtransition. A truly terminal state is namedexhaustedto distinguish it from Attempt failure.working,verifying,needs_input,deliveredandexhausted. While recovery is active they may report counts such as “18/21 generated, 3 recovering” without asking the user to choose repair steps.needs_inputincludes a specific requested action, reason, expiry and continuation command. User input resumes the existing Recovery Case rather than creating an unrelated new Goal.Testing Decisions
FOR UPDATE SKIP LOCKED, lease expiry, immutable Attempts and transactional outbox creation.Out of Scope
Further Notes