Task Pipeline Architecture Addendum
Historical design input(2026-07-23 校准):本文保留 2026-05 的问题发现和 Task Orchestrator 思路,但不是现行 implementation specification。当前 Task V2 parity 和 Task V2+ 工程路线见 工程审计与实施基线;V3 proposal 不能自动覆盖本文记录的 V2 行为。
日期: 2026-05-31
用途: 对 Task Pipeline 设计产出 的补充说明。
背景: 2026-05-30 的 task pipeline 设计方向基本成立;2026-05-31 做了全系统 pipeline 调研后,需要把 task 放回contacts / calls / messages / leads / contact_timeline / future AI tools的整体架构里看。
结论
Task V2 的主方向没有问题,但它不能作为一个孤立 feature 落地。
应该保留的核心判断:
- Task 是 actual work object。
- Task lifecycle 应该是
open / closed,当前 DBpending / closed可作为 implementation mapping。 no_answer、left_voicemail、callback_later这类值是 progress,不是 final outcome。- AI 可以提出 task action proposal,但状态转换、幂等、权限、DNC、audit 必须由 code 执行。
- Task Orchestrator 是必要的。
需要补强的地方:
Task Orchestrator 不是 task feature 内部的小 helper,而是 unified pipeline architecture 里的 shared mutation module。
也就是说,它应该服务:
contacts-analyzerlead-processorstudio-api- SMS meaningful reply flow
- retry / reprocess / onboarding backfill
- future AI agent / tool calling
Task V2 和 Unified Pipeline 的关系
旧理解
现在应该升级为
Task Orchestrator 是 shared mutation layer 的一部分,不是单独为 Tasks 页面服务的后端逻辑。
Task V2 需要修正/强调的点
1. task_progress_events 和 contact_timeline 的关系
Task deliverable 里说 task_progress_events 是 progress source of truth,这个判断仍然成立。
需要更明确:
它们可以同时写,但不能互相替代。
原因:
contact_timeline是用户可见的 contact feed。- task detail / attempt count / retry history 更适合从 task-level events 重建。
- 现在
tasks/list.ts用 closed sibling tasks 推attempt_count,这是当前 schema 不足的表现。
2. closeResult 的 current state 和 target state 要分开写
当前代码事实:
TASK_CLOSE_RESULT 有 18 个值,其中包括 progress-like 值:
attemptedno_answerleft_voicemailcallback_later
Target architecture:
- 这些值不应该继续作为 final outcome 使用。
- 新 API 应该用
record_progress表达。 - 旧 API / 旧数据可以 compatibility 保留一段时间。
因此 task-enums.md 应继续记录 current code truth;task design doc 负责说明 target semantics。
3. contacts.actionNeeded 和 tasks.actionNeeded 要定义 source of truth
调研后更明确:
否则 contacts-analyzer prompt 会同时生成 contact-level action 和 task-level action,长期会让 UI/API 不知道谁说了算。
Task V2 应该显式要求:
- 任何需要前台执行的 human work 都必须变成 task。
- contact-level action 只用于 summary / ranking / legacy compatibility。
- 后续设计要决定是否 deprecate contact-level action fields。
4. Task Orchestrator 应该接受 code-only action
不要把 Task Orchestrator 理解成“AI taskDecisions 的执行器”。
它也应该处理 deterministic action:
也就是说:
5. Studio API close behavior 是 Phase 1 必查点
当前 PATCH /v2/tasks/close 在 closeResult = no_answer / left_voicemail 时:
- close 当前 task。
- 自动创建一个 follow-up task。
这和 Task V2 target model 冲突。
Target:
这个不一定第一步就改代码,但 Phase 1 design 必须把 API contract 改清楚。
6. Lead retry / backfill 必须走同一个 task contract
lead happy path 通过 LeadCreated event 创建 contact/task/timeline 是合理的。
但 retry/backfill path 不能只补 leads,漏掉 downstream task。
Task Orchestrator 的价值之一就是让这些入口可以 idempotently 调同一套 task creation contract。
Phase 1 推荐顺序
Phase 1A: Task Orchestrator contract
先不急着改所有代码,先把 contract 写清楚:
必须定义:
identity:contactPhone + storeId + franchiseId + accountIdactor:staff | contact_analysis | lead_webhook | system | ai_agentaction: mutation typepayload: typed per actionidempotencyKey: retry/backfill/tool safety- side effects:
tasks+task_progress_events+contact_timeline
Phase 1B: Progress vs close API
定义两个不同 API:
不要再用 close API 承担 progress update。
Phase 1C: contacts-analyzer prompt output cleanup
当前 taskDecisions[] 只有:
createupdateclose
Target 应该补:
record_progresscreate_closed或等价 outcome action
但这个要在 Orchestrator contract 定下来之后再改 prompt。
Phase 1D: timeline projection
每个 task action 都应该生成 contact-level timeline projection,但 source of truth 不一定是 contact_timeline。
建议:
文档处理建议
保留
新增/使用
不建议现在做
不要直接把 task-enums.md 改成 future enum。
原因:
- 它是 current code source-of-truth doc。
- 当前 DB 仍然允许 18 个
closeResult。 - 如果在这里直接删/改 progress-like close results,会让工程读者误以为代码已经改了。
正确做法: