Files
go-sip/docs/plan-config-read-v0.1.md
T

30 KiB
Raw Blame History

Go SIP Agent:配置读取与有界外呼迭代计划 v0.1

当前迭代唯一执行入口。状态:用户已授权 P1 本地迭代;项目内契约冻结与 Mock C、实现及本地验收进行中。 现行 contracts/upstream/v1/ 和代码仍是旧外部基线;本文不授权真实 SaaS、生产部署、拨号或切换。分项设计:有界消费与控制通道;原本地 SaaS 结构契约:第三方对接 v0.1;任务发现单次响应的修订草案 v0.2及独立 Schema不回写 v0.1 历史证据,待新合同及 F03 实现验收后切换。机器校验件:Schema/正反例。分项材料须与本文一起更新,不能继续使用旧 ETag/304、控制 CAS 或即时反馈目标。

1. 范围和完成标准

当前 P1 仍为单 D、单 Agent、单 Asterisk、单 Cell、单租户,允许同租户多任务验收;第二租户/多 D 只可另做明确标注的合同 fixture,不等于业务运行授权。真实 SaaS、OSS、云、供应商消费和外呼均另获授权;真实外呼仍遵守白名单、Asia/Shanghai [09:00,20:00) 及每线路/号码每日次数限制。未经新合同和验收,不替换现行运行规则。

拟定四条只读 GET,共用 X-DISPATCHER-id 和 X-DISPATCHER-SECRET-KEY,无请求体:

路径 用途与状态
/internal/v1/dispatcher/sip 用户指定路径;本 D 获管理面批准的 SIP 全量。
/internal/v1/dispatcher/task/:task_id 用户指定路径;任务归属、路由/主叫、智能体、时段及两项任务级超时。
/internal/v1/dispatcher/tasks(可 ?after=<cursor>) 用户指定路径;启动一致全量快照,运行中每 30 秒按变更游标发现任务。
/internal/v1/dispatcher/tenant/:tenant_id/quota 本地项目定义路径:取得任务后按其 tenant_id 读取该租户分配给本 D 的并发额度;真实 SaaS 路径兼容性未验证。

任务队列及精确绑定只由 SaaS 创建、维护和退役;D 只消费,不建队、不绑定、不删除。 SaaS 先确认持久队列 ready 再发布 persistent 消息,mandatory 无 return 且 confirm 成功才记入队。D 离线时消息可积压;无队列时未成功入队的原消息由 SaaS 保留,就绪后按原身份重新发布,不能靠 D 重启倒灌。任务队列按 D+任务 ID 定位;租户身份保留原值用于核验和额度汇总。

用户明确的消费规则:pause 保留积压,resume 消费原队列积压;stop 持久生效后静默消费并 ACK 所有未接纳积压,不拨号,不向 SaaS 发布这些消息的回执或通话结果。 静默只限定已停止任务的未接纳命令:停止控制本身仍有处理回执;已接纳/在途通话按 drain/hangup 处理并保留其最终结果。D 的错误日志、停止状态和计数不静默,ACK 丢失后重投仍不拨号、不补发被抑制结果。

完成分三层:C:F01/F07 项目内来源、版本、严格 Schema、正反例、SHA-256 对齐并通过 Mock SaaS 端到端验证;不等待外部签收;L:单 D 本地隔离闭环和故障矩阵通过;M:多 D 独占资源/份额为另行授权的后续。Mock C 不代表真实 SaaS 或供应商验收。

2. 权威资料和读法

先读本文并按 §4 选择 F 包,再读架构、现行验收、通信合同、开源复用及 contracts/upstream/v1/。新旧冲突须版本化替换,不向现行严格合同偷偷加字段。页面分析只作页面语义来源,不证明现网字段。原 plan-0918不回写;本计划 §8 是唯一新台账。

3. 冻结目标与处理规则

3.1 配置、路由、时限

  • management 是 SIP 唯一编辑/审批面,SaaS 只分发获批完整版本。SIP 变更先关准入、排空/对账,再核验实际加载;发现变化约 60 秒不等于加载完成约 60 秒。供应商 transport/auth/registration 不明不得给 real 猜默认值。
  • 新 call.execute.payload 仅 task_id/callee;外呼信封仍有 command_id 防重复拨号。任务必须返回 tenant_id/tenant_key,D 核对消息与任务归属后再按 tenant_id 取额度,身份错配/缺失即拒新准入。任务配置不返回 agent.content_sha256;版本不可变,同版本异内容拒绝,已有执行持久快照不漂移。
  • 最小路由约定(本地项目契约,F01 Schema/Mock 验证):allowed_trunk_ids 按列表顺序作为候选优先级,选首条满足时段、已加载状态、供应商/线路额度且支持任务 caller_profile_id 的线路;无满足项不接纳。caller_profile_id 是新增任务级明确引用,必须命中选中线路的获批主叫,不默认取第一个主叫。route_policy_id 只标识这份任务路由,不依赖另一个未定义的查询接口。选定线路/主叫后持久绑定;拨号失败或未知不自动换线重拨。
  • ring_timeout_ms 是任务级振铃上限;通话有效上限是任务 max_call_duration_ms 与已授权 AI conversation.max_duration_ms 的较小值,控制器和执行侧均使用同一值。两值不相同必须记录来源/有效值,不改写智能体原快照或悄悄放宽任何上限。没有逐呼 variables 的新合同不提供联系人变量来源;需要未提供变量的提示词不得以空字符串代替继续执行,须在 F01 明确静态提示词范围或补齐获批来源。
  • SIP/任务配置约 60 秒缓存到期重取完整 200,不使用 ETag/304;过期/失败拒绝新准入,不影响既有执行快照。配置内 status=running 不是恢复许可,状态按 §3.3 独立处理。
  • F02 项目内 Agent 状态校验:使用受部署配置约束的 agent_id/cell_id 查询 Agent status;applied_configs 必须恰有一条 kind="sip",且 state="applied"、十进制 revision 与 config_sha256 分别精确匹配获批 SIP artifact revision/SHA-256、observed_at_unix_ms>0,才可读取新配置/准入。缺失、重复、身份不符或匹配失败均 fail-closed。此为本地 Agent 协议规则,不是 SaaS/management 外部确认;Mock 状态不能证明真实 Asterisk 已加载。

3.2 租户额度

取得有效任务的 tenant_id 后,D 请求拟定 /internal/v1/dispatcher/tenant/:tenant_id/quota。响应包括 D、tenant_id、原值 tenant_key、额度版本、max_concurrent_calls(允许 0)、有效截止时间;该值是 SaaS 分配给此 D 的租户份额,不是每个任务各得一份。相同租户各任务复用同一额度快照/占用账本,SaaS 必须保证 tenant_id 与 tenant_key 一对一。

额度成功核验后最多缓存约 60 秒且不超过响应有效截止时间;缺失、身份错配、过期或刷新失败,关闭该租户所有任务的新准入,不使用无限额/默认额,不阻塞 stop 静默排空。额度调低时不强挂已接通通话、不抹掉已占用/未知执行,直到占用降至上限以下才再接新呼叫。D 以 SQLite 单事务检查并预留租户+任务+Cell/线路/AI 等额度,不能先分别判断后并发超卖。确认通话终结并释放执行资源后释放通话额度,不等待录音上传或 MQ 最终结果确认;未知通话继续占额。多 D 时各份额之和≤租户总额,未经 F05 授权不开放多 D 运行。

3.3 暂停、恢复、停止与状态来源

SaaS 先持久修改权威任务状态,再向独立 D 控制队列发布 task.control。请求不含 command_id/expected_task_revision,本阶段不设计控制去重;D 按任务串行处理控制与接纳,并持久记录生效状态后才 ACK/回执。

  1. **pause:**立即关闭新接纳并保存暂停屏障,停止从该任务队列继续取新执行;已投递但未接纳的有界消息退回原队列,不能 ACK 丢弃或搬进无界 SQLite 待拨队列。已有执行按 drain/hangup 处理。重启仍暂停。
  2. **resume:**重新 GET 单任务配置(不使用约 60 秒旧缓存),只有 SaaS 最新状态为 running、归属/授权/租户额度/时段有效、且本地未 stopped,才解除暂停并恢复消费原积压。无需 SaaS 重新发原消息;已过 not_after 的旧消息仍不可拨,暂停不能冻结或延长有效期。过期/窗口外非 stopped 命令给明确拒绝回执,不等待次日自动拨号。
  3. **stop:**持久化不可逆停止屏障,同任务 ID 不能 resume/重新启用;SaaS 停止新发布。D 不申请通话额度,继续小批量消费未接纳积压,仅计本地处置计数并 ACK,不建外呼结果/outbox,不拨号。已停止任务重投/重启、额度为 0、配置缓存失效时仍可排空;不得借此清掉别的任务、伪造已接纳执行终态或漏掉控制回执/既有通话结果。
  4. **优先级:**本地 stopped 永久高于任何 running;本地 paused 只能由有效 resume 解除。tasks 增量/全量及缓存更新可使状态更严格,不能清除已持久的暂停/停止屏障,且低于已知 task_revision 的状态不得覆盖新状态。冷启动恢复本地屏障与 SaaS 全量后取更严格者;冲突/缺失关闭新准入,不丢已有执行事实。
  5. **无编号乱序:**控制重投可能重复返回回执,不保证按消息身份“只处理一次”。pause/stop 先关闭准入;与 SaaS 最新状态不符、不可核验或接收乱序时保持关闭并返回明确失败,不根据到达先后自动恢复。恢复必须重新发送有效 resume 并核对最新权威状态;不引入替代 command_id 或控制 CAS。SaaS 不可把发布成功视为控制已应用,丢失回执下状态不明不得主动扩量。

3.4 任务发现、发布与期限

D 启动/重启用 /internal/v1/dispatcher/tasks 拉一致全量快照和水位,运行中每 30 秒 ?after=<cursor> 拉本 D 新增/更新/撤销。cursor 是不透明变更水位,不是最大 task_id。新版单次返回完整快照或完整变更集,最多 256 条且不分页;响应不带每个任务的 queue/key,D 按已约定的 D+task ID 命名规则推导并只消费 SaaS 预建队列。全量 cursor、增量 next_cursor 仅在完整校验和原子持久化后推进;空变更的 next_cursor 与请求 after 相同。removed 表示完成退役握手后的撤销归属,不等同于 stop;HTTP 410 cursor_expired(含增量超限)关闭新准入并重拉全量,禁止截断或跳过变更。发现清单/任务响应必须提供 tenant_id/tenant_key 以便取额度。无变化不撤销消费关系。

队列 ready 不等于 D 已开始消费。 首条任务可能等待轮询、配置/额度读取和可用名额;30 秒是轮询间隔,不是端到端发现 SLA。SaaS 设置的 not_after 应覆盖允许的排队和准备时间,不能用固定 30 秒示例承诺离线恢复必拨。D 重启仅恢复原消息:未过期且有效的才接纳;过期明确拒绝(已 stopped 则静默 ACK),绝不顺延期限/自动造新 command_id 重拨。若要求更短首呼时限,必须在 F07 另定就绪通知协议,不能假设已存在。

SaaS 清单须保留已 stopped 但未排空任务;撤销握手按第三方契约执行:SaaS 停止发布,D 持久 stop 屏障、退回/排空未接纳积压、确认无未 ACK 且队列为空后回执,SaaS 收到后删除队列并发送 removed。D 不创建/删除队列;task_id 为 [A-Za-z0-9_-]{1,128},每 D 最多 256 个未退役任务队列,routing key/queue name 上限见 MQ topology。

3.5 最终结果与无录音

保留呼叫/控制回执及一种最终 call.result,不保留对外 query/replay、实时文字/拒联/录音拆分事件。用户已批准仅最终反馈,本轮实现与验收按此更新;真实 SaaS 消费兼容性另行验证。最终结果的身份在本地持久化,MQ 重投仍是同一份事实,不重新拨号或上传。

  • 已产生录音:上传 OSS 成功后 recording.status=uploaded、携带路径;上传永久失败/到有限期限后 unavailable、明确错误与 null 路径。明确上传/授权失败立即以 unavailable 收口,无确定结果最晚于 call.ended_at + 15m 收口。
  • 通话已尝试但忙线/无应答等未产生录音:终结已确认后即可发唯一结果,recording.status=not_created、身份/路径等资产值为 null,原因如 no_answer;不申请上传、不假称上传失败。录音本应生成却失败用 unavailable 和明确阶段原因,不伪装正常无录音。
  • 未接纳且被停止屏障吞掉:无命令回执、无最终结果;其他未接纳拒绝只有命令回执,不能伪造通话。已接纳取消/失败/挂断仍按其事实形成最终结果。
  • outcome 反映通话本身,录音错误写 recording 不改成呼叫失败。通话额度释放与上传/通知独立;日志只保留脱敏事实,不输出完整音频/文本/密钥。
  • 最终文字合并后的消息大小与现行 MQ 上限可能冲突,项目内 JSON 正文上限为 8,388,608 bytes,超限保留 outbox 并显式阻塞,不截断完整转写、不拆成用户已移除的实时事件来掩盖。

4. 依赖顺序与工作包

执行顺序:F00 → F01(HTTP/配置/额度)与 F07(MQ/发现/控制/结果)并行冻结 → 项目内 Mock C → F02 → F03 → F04 → F08 → F09 → F06。F05 是另获授权的后续。 F01/F07 可按各自边界并行;严格 Schema、正反例与来源/hash 对齐,并由 Mock SaaS 端到端通过后即为本地 C,不等待外部签收/连通。F03 单独负责新队列消费/状态屏障,F08 只集成结果交付和受控切换,不重复开发同一消费路径。

工作包 输入、责任与交付 门禁
F00 草案整理 集成负责人同步本文、分项设计、对接文档、配置 Schema/示例;标明用户给定路径与项目新增额度/路由字段。 正反例可验证,不冒充 SaaS 现网。
F01 HTTP 与配置/额度合同 按第三方文档冻结四条 GET、两 Header、身份映射、任务主叫/候选优先级、两时限较小值、授权/缓存/配置不可变及租户额度份额/版本/有效期。 项目内严格 Schema、来源/版本/哈希、正反例;静态提示词或变量来源明确;Mock 验证,不等待外部签收。
F07 MQ、发现及控制/结果合同 历史 F07 先冻结 v0.1 分页发现;仅任务发现随后由 F03 v0.2 单次响应修订取代。其余 SaaS 独占队列生命周期、v3 routing、精简 call.execute、无编号控制、pause/resume/stop、回执/唯一最终结果、录音边界及消息大小/期限维持原合同。 项目内严格 Schema、拓扑、正反例、来源/hash;与 F01 一致并由 Mock 端到端验证后 C 通过。移除旧 query/replay/配置 MQ/拆分事件;外部兼容另记未验证。
F02 配置与额度读取(C 后) 接入四条已冻结 GET(本地先由 Mock 提供);D 读取并校验 SIP 实际加载、任务租户映射、按 tenant_id 的额度,完整 200 缓存;有期限拒绝与持久快照。 断服务、降额、同租户多任务、过期/错身份、新旧配置竞态不超额/不漂移;真实 SaaS 未联调不冒称通过。
F03 消费/发现/控制(F02 后) D 移除旧 --tenant-key 自建租户队列路径,按 SaaS 已建任务队列消费;发现游标/暂停恢复/停止静默ACK/独立控制与原子额度;未接纳仍留 MQ。旧分页发现结果仅属历史。 §5 的队列/控制矩阵通过;D 无建队权限仍可工作,stop静默但可排查。
F03 v0.2 任务发现修订(F04 前) 每 D 单次完整响应≤256,正文无 queue/key;失效游标 410 恢复全量,空变更原游标,退役 removed;完整响应、任务归属、游标原子持久化,发现失败关准入/停任务消费但不中断控制。 v0.2 Schema/示例/hash 与 Mock/本地 RabbitMQ 再验;只运行新协议,不把旧 F03 证据当作新版通过。
F04 时段及最后拨号屏障(F03 后) 仅 Dispatcher 在持久接纳与发出呼出指令前复核任务×已绑定线路时段、任务排除日期、白名单、有效期及任务/AI 时限,持久化唯一签发/拒绝决定;Agent 只核验会话及 Dispatcher 签发期限。 本地 Mock 验证窗口边界/跨日/更新/暂停竞态不拨号、不等待或自动重试;真实路径固定时段只在外部合同、F09/F06 验收及授权后替换。
F08 结果与受控切换(F04 后) 组装 uploaded/unavailable/not_created 的最终结果与既有命令/控制回执;通话释放独立于上传;旧新版本互斥,恢复原身份 outbox。 本地全流程无重复拨号/PUT,停止积压不产生回传,已有执行结果不丢失。
F09 本地验收(F08 后) 集成负责人运行 §5 全矩阵;单 D 单租户多任务为 L,扩展 fixture 标为非 P1。 gofmt、go vet ./...、go test -race ./...、go build ./...、本模块覆盖率≥65%,脱敏证据。
F06 发布/切换(F09 后) 单写 §8 状态,核对合同/制品/队列实际版本;真实 SaaS/OSS/云/线路另外授权。 旧本地证据不代签;回退不能并行旧新写入/额度或引起重拨。
F05 多 D(后续另授权) SaaS 固定任务归属、分配各 D 有界租户/供应商份额;D 独占 Agent/Asterisk/持久目录。 各份额总和≤总额,未知执行不跨 D 迁移,不用 fixture 冒称双 D 业务。

5. 必测输入与预期结果

用例 输入/故障 必须观察到的结果
配置结构 缺身份 Header、task/消息/额度 tenant_id 或 tenant_key 不一致;agent.content_sha256/旧逐呼字段回流 拒绝新准入,不能猜默认/覆盖;call.execute.payload 仅 task_id/callee,task含两超时与明确主叫。
配置/路由 第一候选不可用、第二可用;无主叫映射;任务120秒/AI90秒;提示词缺变量 首个满足条件的候选并固定;主叫不可解/变量缺失不拨;有效时限90秒,两个控制点一致,拨后失败不自动换线。
租户共享额度 同 tenant 两任务额度各10、租户上限3,同时请求4次 合计最多3个占用;不同任务不各得3。未知占用计入。
降额/失效 已占3时从3降为1;额度0、有效期到、HTTP故障 现有不强挂、不清未知;新准入关闭,占用低于新上限且授权有效才接新;控制/stop排空不被额度阻塞。
pause/resume 暂停时队列100条、D已有有界未接纳交付;重启后恢复 暂停不丢消息/不新拨;未接纳退回原队列;重启仍暂停;有效resume继续消费原100条且无需SaaS重投,已过期的明确拒绝。
stop 静默 未接纳积压100条、在途2通、stop;ACK丢失/重启/额度0 100条最终ACK,originate=0、新回执/最终结果outbox=0;本地计数可核查。stop控制有回执,2通按策略终结并各有最终结果;其他任务不受影响。
状态优先级 pause/stop后收到旧running快照或低版本tasks;旧resume迟到/控制重复/HTTP断连 不自动恢复;resume未获最新running/未过屏障即明确失败;stopped不可逆。控制不按消息身份去重,不保证只回一次;回执不明不当成功。
新任务/离线期限 刚过轮询点新建队列;离线超过not_after;首条期限不足准备时间 消息先入已建队列;恢复只消费仍有效者,过期不拨不顺延,不自动新建外呼命令;30秒只是发请求周期。
发现/退役 较小ID任务变更、空变更、重复/超过256条、游标失效、removed 退役、SaaS创建前误发、stopped仍有积压 不漏旧任务变更;不接收分页或响应内队列字段,不截断超限结果,失效后重拉全量且只在原子持久化后推进游标;未入队原消息由SaaS保留;stopped保留清单直到静默排空,无未ACK/未知执行再退役。
队列权限/配额 D禁止create/bind/delete、队列满、SQLite满盘、租户满额 D只消费,不补建;SaaS保留未成功发布消息;事务失败不ACK已接纳;不会搬全部积压进SQLite,不阻塞控制/stop清理。
无录音/失败 无应答/忙线且无录音;应有录音却失败;OSS超时;停止未接纳命令 正常无录音not_created且不等待上传;明确授权/PUT失败立即unavailable,未知最晚15分钟收口;停止未接纳无回传;不能伪造call_id/成功路径。
释放与结果 已确认结束但上传慢、MQ confirm丢失或重启、完整转写超过8 MiB 通话额度已释放、未知仍占额;原结果身份重投不重拨/PUT;超限 outbox 显式阻塞,不截断/拆分/丢弃。
时间及真实边界 任务/线路交集、空日、排除日、左闭右开、最后许可前控制到达 不跨窗或被暂停/停止后新拨,不等待次日自动执行;Mock时钟不等于real放行。

6. 写入与实施边界

项目设计与本地目标契约在自身 docs 维护。contracts/upstream/v1 保持现行外部运行基线,不擅改;原 v0.1 本地合同与 F03 证据保留为历史;docs/thirds/v0.2.md §2.5 中任务发现单次响应已作为本地运行修订合同完成实现和 Mock 校验,独立 v0.2 Schema、正反例和来源哈希见新版 F03 证据;这不代表真实 SaaS 已发布或签收。其他业务合同沿用已有本地 v0.1 机器校验件,须记录规范文件与机器文件 SHA-256。该本地契约不冒称 SaaS/management 已发布,外部签收和连通不阻塞本地 C。本文/分项/guide/字段提案必须同步;源码、截图、真实凭据、无关父仓库不改动。TDD 先失败后实施,复用现有库,禁止隐藏错误、HTTP/MQ配置回退、重复外呼。大改另开分支,未获得子 Agent 授权由当前负责人执行。

7. I/M/G 前置

I:本地实施按本文件与第三方对接文档冻结的项目内契约;F01/F07 的严格 Schema、正反例、来源/hash 对齐以及 Mock SaaS 端到端 C 通过后即可进入 F02,不等待 SaaS/management 外部签收或连通。M:旧 W 的通过不能代替新 F02–F09;仅本地隔离验证不代表真线路/OSS通过。G:部署版本、网络/ECS只读核验、SHA-256、systemd enabled+active、Asterisk/ARI/PJSIP、媒体监听和非生产诊断门禁全部保留;实际云/生产/拨号另获授权。

8. 当前事实总台账

项目 当前事实 下一门禁
历史计划 plan-0918保留原文,只作历史。 不回写旧W台账。
F00 已对齐计划、分项设计、第三方对接、字段提案、架构/验收入口;三条用户给定路径与新增租户额度路径、项目路由字段来源均有标识,均属项目内目标,非现网合同。 Draft 2020-12 本地校验:4 个有效响应示例通过,1 个额外字段非法样例按预期拒绝;文档链接检查通过。下一门禁为 F01/F07 项目内 Schema/正反例/来源哈希冻结及 Mock C。
F01 四条只读 GET 的身份/归属、路由/主叫、缓存/版本、额度/有效期已按第三方对接文档冻结为项目内规则;resource_not_found/租户额度等 HTTP 错误映射有正向 fixture。contracts/upstream/v1 仍是现行外部基线,真实兼容性未验证。 python3 scripts/validate-local-contracts.py 通过:4 个本地 Schema、17 个配置读取正向例、HTTP 状态映射及负例;manifest SHA-256 校验通过。C 通过见下行;不代表真实 SaaS 兼容性。
F07 项目内任务发现/队列所有权与生命周期、MQ v3 控制/回执、单份 call.result、大小/期限/退役规则已按第三方文档冻结;本地正反例已校验。contracts/upstream/v1 仍是现行外部基线,真实兼容性未验证。 python3 scripts/validate-local-contracts.py 通过:发现 13 个正例、命令 6 个、结果 4 个,各 Schema 负例均拒绝;source 与 18 项产物共 19 个 SHA-256 文件通过。F03 运行时本地交付见下行;外部兼容性仍未验证。
C 本地 Mock SaaS 通过四条只读 GET、call.execute、command.result 与 synthetic call.result 的 Dispatcher 端到端交互;缺少 result queue 时 outbox 保留并在恢复后交付。 证据:local-mock-saas-c-v0.1.md。契约验证、包测试及 bash scripts/mq-integration-local.sh 通过。仅属项目内 Mock;没有真实执行、拨号、录音上传或外部验收。
F02 本地配置与额度读取模块完成:四条 GET 严格校验,四份完整响应按版本/hash/有效期持久化,任务/租户身份绑定,task+tenant 配额与 call.execute reservation 原子接纳;SIP Agent applied-config 核验、断连/过期/不匹配 fail-closed、同租户多任务和配置竞态均有 Mock 覆盖。F02 涉及四包覆盖率为 65.1%–75.0%。 证据:f02-local-config-read-v0.1.md。包测试、race、go test ./...、vet、build 和契约校验通过。F09 按用户确认的本轮 P1 业务模块 ≥65% 口径另验;CLI/历史包低覆盖率单列;F03 应用启动/消费现有本地证据见下行,真实 SaaS/Asterisk 加载仍未验证。
F03(历史分页证据) 单 D/单租户 v3 运行时曾在本地交付:只被动消费 SaaS 预建队列,持久发现游标/任务归属,暂停保留积压,恢复使用原队列,停止先持久屏障与权威状态、后静默排空并 ACK,排空完成后才写控制回执。RabbitMQ ACL Mock 证明 Dispatcher 无 configure 权限仍可消费、排空和发布;旧 tenant-queue consumer、旧 per-call control worker、CLI 旧消费参数及 MQ-only v1 acceptance runner 已移除。 证据:f03-local-task-runtime-v0.1.md。本地 acceptance、Race、vet、build、契约与无 configure 权限的 RabbitMQ 集成测试通过;internal/dispatcher 覆盖率 66.2%。仅是本地隔离验证,外部 SaaS/management、云、线路和生产均未验证;F09 新版本地矩阵见下行,历史分页证据不代签。
F04 本地隔离 Mock 已将任务×已选线路时段、任务排除日期、白名单/有效期、绑定快照及任务/AI 较小通话时限接入接纳与发起前门禁;执行身份只有一次持久 issued/refused 决定,队列消费后由 D 经版本化 Unary 向 Mock Agent 下发,Agent 不重算业务策略、不发送 SIP。V3 mixed/real 启动拒绝,原真实固定门禁未放宽。 证据:f04-local-dial-policy-v0.1.md。Proto/合同、本地 Mock、race、vet、build、RabbitMQ 无 configure 权限及 scripts/acceptance-local.sh 通过;外部合同/真实拨号未验证。F08 后续本地结果见 f08-local-final-result-v0.1.md;F09 本地矩阵与覆盖率见 f09-local-acceptance-v0.2.md。
F08 单份最终 call.result、确认终态后独立释放额度、uploaded/unavailable/not_created、本地 Agent→D 录音失败事实与原身份 outbox 已完成隔离 Mock 验证;V3 Mock 不并行写旧分散事件,V3 mixed/real 启动拒绝。证据:f08-local-final-result-v0.1.md。 scripts/acceptance-local.sh(含 race、vet、构建及受限 RabbitMQ)通过;Mock 录音成功/失败由合成事实注入,默认 Mock 只模拟无应答,无实际媒体/OSS PUT,publisher confirm 不等于 SaaS 应用签收。F09 本地验证见 f09-local-acceptance-v0.2.md;F06 真实部署/切换仍未获授权。
F09 任务发现 v0.2 的 ≤256 单次完整返回、空变更/removed/410 恢复及计划 §5 单节点/单租户适用矩阵均已重新进行本地 Mock 验证;stop 前两条已发起执行的 Agent 归属与一次性拨号决定现由同一事务持久化,stop 可对两条发 hangup 且旧执行仍返回结果。证据:f09-local-acceptance-v0.2.md。 scripts/acceptance-local.sh(格式/合同/Proto/hash、race、vet、构建及受限 RabbitMQ)通过;本轮 P1 业务模块均 ≥65%,MQ 仅带 integration tag 时为 66.4%。CLI 29.6% 和历史 callruntime 61.7% 未达线,按用户确认口径单列技术债,不声称全仓达标。队列满真实 RabbitMQ Mock 拒绝;SQLite 满盘仅作写入错误注入,未物理填盘。外部/真实验收未完成。
F06 本地发布准备与切换阻断已核对:Go 1.27.1 一次性制品/校验和、v0.1 其他协议+v0.2 任务发现+项目 v3 MQ 队列及 Proto manifest 的版本/hash 写入制品清单;已有 release/package 输出及归档拒绝覆盖,mixed/real V3 执行在触碰 DB/MQ 前 fail-closed,旧消费 CLI 和旧分散事件不能并行写入新路径。证据:f06-local-release-gates-v0.2.md。 make release-check-local 与本地 acceptance 通过;来源 dirty,制品仅 local-development、production_approval=false。未获真实部署/拨号/切换授权,旧 Python 资源移交、ECS/systemd/Asterisk 实际加载和生产签收均未执行;本地阻断不代替真实切换。
F05 多D/第二租户不在本轮运行范围。 另获阶段与额度/资源授权。

9. 协作与版本记录

仅集成负责人更新本文 §8、公共合同和合并状态;有并行授权时一 lane 一工作区/独占写集合、每批回归,不假定未跟踪文件在 HEAD。v0.1 是项目规划及字段草案,不是 W01/SaaS 正式发布版本。真实环境的资源、拨号和生产权限不因文档改动增加。