Files

9.3 KiB
Raw Permalink Blame History

SaaS ↔ Dispatcher:任务清单、控制与临时状态 v0.4(项目内目标草案)

项目内 v0.4 Schema、隔离 Mock、运行代码及本地验收已完成(见 dispatcher-v04-local-acceptance.md);真实 SaaS 尚未签收或联调。 已发布外部合同仍以 contracts/upstream/v1/ 为基线;v0.3 历史发现见 v0.3,其余历史规则见第三方对接顺序 v0.1。本文件不授权真实呼叫或部署。实施步骤与待冻字段见 plan-dispatcher-state-v0.1.md。

1. 不变的两类 SaaS → D 队列

  • 每个 Dispatcher 一条 SaaS 预建、独占的控制队列,接收 task.control 的 pause/resume/stop;每个归属任务另有一条 SaaS 预建任务队列,接收 call.execute。D 只消费,不能创建、绑定或删除。D→SaaS 的控制/命令回执和 call.result 仍走既有 per-D 结果路由,不能把结果队列误认为入站任务队列。
  • 控制须先于任务新接纳生效,SaaS 先持久任务状态再按每任务顺序发布控制;控制回执是应用事实,RabbitMQ publisher confirm 不是 SaaS 已处理。不可将控制积压按 task 只保留最后一条:中间挂断、stop 排空及逐条回执仍须执行。
  • SaaS 先停止向被 stop 的任务发布,D 持久屏障、处理在途执行并静默 ACK 所有未接纳积压;仅在原任务队列排空后回 stopped/applied,SaaS 确认回执后退役任务队列。无回执不得提前删队列。resume 不得重新启用本地已 stopped 的同一 task ID。

2. 重启全量、运行中增量(项目内已替换 v0.3 §2.5)

  • 每次 D 进程启动/重启,在关闭新执行的状态下读取 SaaS 对此 D 的完整归属清单;如需多页,各页必须属同一个有界、一致的快照。清单包含仍需排空的 stopped 任务,不能仅列 running;明确撤销后的任务不得被当成仍归属。全量页不完整、身份冲突、归属缺失或列表不可用时保持关闭,不能拿旧 SQLite 游标跳过全量。所有页核验完成后才应用任务归属,继续处理重启期间积压的控制;控制队列在发现失败时也不得静默停摆。
  • 项目内拟定同一路径 GET /internal/v1/dispatcher/tasks?mode=snapshot 返回 schema_version=task-discovery.v0.4-proposal、mode=snapshot、dispatcher_id、UUID v4 snapshot_id、十进制事件 watermark、tasks[]、next_page_token(最后一页 null)。后续用 ?snapshot_id=<snapshot_id>&page_token=<token> 取同一快照下一页;每页 ≤256、全 D 当前归属/待退役任务合计 ≤256(不能重复/跳项),各页 snapshot_id/watermark 不得变化;空页有非空 token 或有新 token 却零任务都按不完整失败。快照不可继续时返回 HTTP 409 + snapshot_unavailable,丢弃整个未提交快照并从头重取,不回退旧游标;page token 不受客户端解析。起始快照的水位覆盖快照生成前所有任务归属事件,不用任何旧 v0.3 SQLite 游标。
  • 在线 GET /internal/v1/dispatcher/tasks?after=<watermark-or-current_cursor> 返回 schema_version=task-discovery.v0.4-proposal、mode=changes、dispatcher_id、tasks[] 和 next_cursor。非空页严格前进,空页等于本次请求游标;SaaS 保证每 D 事件连续、分页完整、有序、不得提前丢失未消费增量,无法满足即显式报错并关闭新执行、重新全量。HTTP 400 不合法请求、403 D 无归属、503 服务不可用;错误响应严格见 Schema,不复用 v0.2 changes[]/410。具体身份验证仍按现有只读 HTTP 配置合同。
  • 仅在本次进程运行期间按发现水位定时查询增量,用于新增任务归属、撤销/退役和必要身份校验。水位不是最大 task_id;异常页/缺页不得推进游标或视为空变更。重启重新全量,不要求从上一次进程的永久事件游标续读;旧 v0.3 的 after=0 事件回放和 SQLite 持久游标不得被当作新全量响应。
  • 任务列表的任务状态可以作为启动快照的初始状态及增量身份/一致性校验,运行中 pause/resume/stop 由独立 MQ 控制队列生效;增量页 running 不能自动解除暂停或不可逆停止。若列表状态与已应用的 MQ 控制矛盾,关闭该任务新接纳并报错、等待受控恢复,不按 HTTP 到达顺序偷偷切换状态。GET /internal/v1/dispatcher/task/:task_id 的授权配置和 resume 的新鲜状态核验仍保留,不等同于恢复“发现页控制状态”机制。
  • 项目内发现字段已在 task-discovery-v0.4-proposal.schema.json 独立严格声明,任务条目与游标等通用定义在 v0.4 Schema 内完整声明,不再依赖历史 v0.3 Schema;控制入站严格格式见 task-control-v0.4-proposal.schema.json。机器 Schema 只约束消息结构;多页相同水位、完整性和快照与 MQ 积压的交接顺序须另由 Mock/代码验证。真实 SaaS 的这些字段、应用收讫、增量保留期限仍未签收,不能以项目内 Schema/Mock 自证兼容;不直接引用 v0.2 的 changes/410 或原地复用 v0.3 的严格 Schema。

3. 控制、通话与积压命令边界

  • 新控制入站使用 schema_version=task-control.v0.4-proposal、原始信封 dispatcher_id/tenant_id/tenant_key/trace_id/issued_at/command_type 与严格 payload={task_id,action,reason};不再携带 active_call_policy,逐条回执格式沿用现行 command.result v0.1,不能把旧 v0.1 控制请求误认为新请求。有效 pause:立即持久关闭该任务新接纳,停止消费任务队列并退回已交付但未接纳消息;向该任务所有已接纳且仍在途的执行发挂断。有效 stop:不可逆关闭新接纳,挂断全部在途执行,同时按 §1 排空未接纳积压;已接纳呼叫按原身份形成最终结果。两者不再提供 drain 行为;resume 仅在新鲜任务状态为 running 且授权有效、本地未 stopped 时恢复原任务队列,不挂断。
  • 在途挂断的“已发命令”“Agent 已应用”和“实际通话终结”是三个不同事实;不因 RPC 成功伪称已终结。失败或终态未知时维持关闭、保留未知占用与可追查错误,何时回控制的 applied/failed、终结最长等待及 retry 边界须由新控制合同与 Agent 能力验证后冻结。不得因自动重投二次 originate。
  • 两类 SaaS→D 入站命令 task.control、call.execute 均不带 not_after,不因积压时间拒绝。历史 pause/resume/stop 逐条按控制队列顺序处理,不合并、延迟或悄悄丢弃;stop 依 §1 排空未接纳积压并回逐条结果。新版外呼请求严格见 call-execute-v0.4-proposal.schema.json,旧 v0.1 入站请求不能当作新版请求;已有出站 command.result 仍按其原合同校验。
  • 未来 issued_at 的 call.execute 不得提前接纳,这是时间先后校验而不是命令到期。历史外呼仍须在持久接纳及实际拨号前核对当前任务运行状态、原值号码白名单、任务及选中线路允许时段、SaaS 授权与额度、租户及供应商份额、任务与 AI 中较小通话时限;任何条件缺失、过期或不确定均拒绝新执行,不等下一窗口、不换线、不自动重拨。删除 MQ 消息期限不放宽这些独立授权期限。

4. Dispatcher SQLite 与日志

  • SQLite 是单 D 临时可靠事务账本,不要求多节点高可用,也不是 SaaS 的永久业务库。执行中仍需短期保存命令幂等、未知占用、执行固定快照、上传/最终结果以及未交付 outbox;文件日志只能排查,不能取代这些用于恢复与防重复拨号的事实。
  • 本地只提供显式且有条件的已终止任务配置副本删除:仍有未知执行/额度、待上传或未发布 outbox 时拒绝;保留任务归属、执行快照、幂等命令、终结事实、上传、占用及 outbox。无自动扫描或迁移删除现有 SQLite 数据。SaaS 应用层回执/可查询恢复事实与最长重投期限尚未冻结;MQ publisher confirm 不等于 SaaS 收讫,不能据此删除依赖应用收讫的历史和防重证据。阻断原因、实际删除数量及 SQLite 错误可追查。
  • 文件系统日志记录原值任务 ID、执行 ID、号码、状态、时间、错误及清理阶段;不写入密钥、密码、私钥、完整用户音频或完整对话。用户另提“全部内容无需脱敏”,与项目现行日志禁令冲突,不作为本版本合同已批准项。

5. 版本与验收边界

项目内 F07 的发现、控制与外呼严格 Schema、正反例、来源与 SHA-256 已校验;隔离 Mock C 与 TDD 回归已覆盖重启多页、积压控制/外呼、挂断失败、stop 排空、未来 issued_at、独立拨号门禁、条件清理及复投。已发布外部合同、真实单任务配置字段、SaaS 可恢复/应用回执与重投期限仍待 F01/F07 外部核对;v0.3 和 v0.1 历史证据不自动升级成 v0.4。真实 SaaS、生产、云和拨号仍须单独授权与验证。