Files

277 lines
56 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SIP Go Agent 项目开发计划与需求阅读索引(plan-0918)
## 1. 用途、状态与优先级
**本文件是后续 Agent 的开发任务入口:先确认需求及来源,再按依赖开发,最后用证据更新状态。** `0918` 是文件标识,不代表工期或上线日期承诺。本文件不替代权威契约、详细设计或验收用例,不重复维护 Schema。
当前基线:总体架构、P1/P2 边界、D01–D10 方案方向及内部隔离 PoC 初始参数已获用户确认;项目已按用户本次授权自行建立并嵌入 W01 项目内契约基线和 W02 Unary Proto/stubs。**旧基线的项目内 G0/W04、单节点/单 Cell/单租户本地验收曾按范围签收;本轮 MQ-only 修订重新打开受影响的契约、实现和验收项,见 §1.2、§8.2**。真实供应商/云/拨号/生产 receipt/容量及切换仍属于第二阶段;旧本地通过不等于新设计通过、外部权威发布或生产放行。
已确认的 OSS 分工:**OSS 配置存于 Dispatcher 配置文件;Agent 向 Dispatcher 领取临时上传 TOKEN 后直传 OSS,不保存长期凭据;Dispatcher 不接收/缓存/转发文件**。TOKEN 有效期固定 15 分钟,过期由 Agent 显式向 D 重新申请,不向 SaaS 取配置/TOKEN。Agent 直传成功后由 D 持久保存原上传事实及 `recording.uploaded` outbox;持久消息进入指定持久队列、mandatory 无 return 且 publisher confirm 成功后完成通知交付。不申请 SaaS 上传会话,不等待 verified、OSS ID 或 SaaS 消费回复,不新增 VERIFYING;SaaS 后续处理不属于本项目。
### 1.1 2026-09-20 本轮范围修订
用户已明确将本轮收敛为**项目自行制定第一版契约并完成单节点/单 Cell/单租户本地闭环**;双节点、第二 Cell、双租户及真实 SaaS/MQ 联调延期第二阶段:
- D01/D02/D03/D06 第一版项目契约由本项目制定、版本化、生成并自校验;不再等待外部第一版发布才能开始实现,但必须明确标记为 project-owned v1,不能冒充 SaaS 已发布合同。
- Static Cell 制品由本项目按 v1 Schema 自动生成、批准并在单 Cell 隔离环境验证;本轮采用单节点、单活 Dispatcher、单 Agent/Cell/Asterisk 路径,双节点和第二 Cell 延后,不作为本轮开发或验收门禁。
- `~/.zshenv` 中已提供并由用户直接授权使用的 `VOLC_*``BAILIAN_*` 运行凭据可直接注入,不再因凭据本身重复确认;密钥仍不得写入代码、文档、日志、证据或聊天。
- 本轮必须完成单节点/单 Cell 的 PCMA/RTP、录音、ASR、LLM、TTS、播放回流和业务事实本地/隔离验收;真实外呼/ECS 联调属于第二阶段,不作为本轮前置。
- 本轮不执行生产切换、真实外呼或 ECS 创建;本地恢复/回滚和安全检查按隔离环境验证。未来真实外呼仍须在当前会话展示通道、原始号码和抓包方案并取得该次确认;每条 SIP trunk 对每个原始手机号每天最多 3 次,线路失败可在额度内经当前会话确认后改测另一条线路;不自动重试、超额或静默换线。
- Mock/mixed/real 不再拥有三套业务流程:`internal/callflow` 统一执行开场、媒体收集、ASR、LLM、TTS、播放和事实统计,`ai.Pipeline`/媒体适配器仅按 mode 注入;CLI 使用通用 `--call-once``AGENT_CALL_*` 配置,不再使用 `REAL` 专用入口。真实 real 环境属于第二阶段,不能作为本地通过的隐式前置。
需求依据顺序:
1. 当前适用的用户确认和 [项目约束](../AGENTS.md)。已确认方向不重复索要审批;缺失字段、预算及偏离方案的变更不能自行补成“已批准”。
2. 外部字段/路径/状态在外部权威闭包可用时来自上游版本化契约包;早期项目内 W01 基线不再属于当前工作树,当前代码只使用项目内唯一的 `contracts/upstream/v1` 契约包;未发生契约迁移前不新增或合并契约。内部接口来自项目内 `agent.v1` Proto;不能将未进入当前契约包的说明文字当作 Schema。
3. [G0确认方案](G0开发准备与契约冻结提案_v0.1.md)记录最新确认和待交付门禁;总体、通信、组件和验收文档补充实施细则。
4. 本计划只编排任务和阅读入口。若发现来源冲突,列明两个出处并暂停受影响部分;不得用计划、旧实现或 SDK 默认值覆盖权威合同。
### 1.2 本轮 MQ-only 架构纠正(用户已确认)
1. **SaaS↔Dispatcher 的所有交互只走 RabbitMQ**:执行、控制、查询、整体补传、AI 配置/授权及上传完成事实通知都通过专用 Topic 订阅;禁止双方任何 HTTP 请求、回调、兼容入口或故障回退。
2. **每个 Dispatcher 有全局唯一、不重复的 ID 和独立接收 Topic/队列**。消息必须定向到指定 D,响应回原 D,来源可追溯;不能多个 D 共用一条队列竞争消费或广播后过滤。Dispatcher 身份不等于 tenant/Agent/Cell ID 或 `dispatcher_epoch`,租户独立队列与原值 `tenant_key` 仍保留。
3. 精确 ID 生成/持久化/重复身份处理、Topic/队列/绑定命名、信封关联/错误/超时以及新 routing key 的完整字节预算须由 W01 冻结;方向已经确认,但不能自行往严格旧 Schema 加字段。P1仍是单活 D,D1/D2 路由隔离只作本地契约/消息 fixture,不新增多 D 调度、HA、共享额度或生产资源。
4. **D↔A 仍为 UnaryA→OSS 仍直传**。MQ-only 不禁止 OSS/ARI/供应商 HTTP(S) 或 gRPC HTTP/2。OSS 配置由 D 配置文件提供,临时 TOKEN 由 D 向 A 提供,不再由 SaaS 下发;保留 D 签发能力。R12 提供原请求绑定的临时授权;R13 持久保存上传事实及原通知身份,并以指定队列可靠入队作为本项目完成条件。不等待 SaaS 处理,也不把本地 outbox 写入等同 MQ 入队。
5. 旧 AI GET、控制/查询/补传 HTTP 和上传 HTTP 方案被本修订替代;`contracts/upstream/v1/` 是当前代码唯一使用的项目内 V1 合同包;未使用的旧快照和 OpenAPI 不属于当前工作树,不能在包外另造兼容合同或绕过其哈希。未发生契约迁移前不新增或合并契约;禁止先实现猜测消息再补合同。
6. 文档修订阶段已结束;当前目标已获批准实施本项目契约、代码、配置和测试,由当前Agent独立执行,不启动子Agent。已确认细节见[MQ-only V1冻结方案](contracts/mq-only-v1-freeze-proposal.md),不重开已批准方向;仍不访问真实SaaS/供应商/云/拨号,本地隔离broker可用于合同测试。文档或局部代码完成不关闭§8.2联合门禁。
目标语义见 R8,当前内部实现事实与差异见 R9,完整 MQ 目标时序见 R10。R1–R6 或历史证据中与本修订冲突的旧传输、路由及通过结论,不得继续作为新接入依据;只读来源包的变更必须走新版本发布。
## 2. 后续 Agent 的开工与收尾流程
### 2.1 每次任务的必做顺序
1. 读取 `AGENTS.md`、本计划 §1–§4 和 §8 当前状态;检查实际文件、Git 工作区及既有改动,不覆盖别人的工作。项目已有独立 Git;先同步远程,不重新 init/submodule/移动历史。
2. 将本次请求映射到 §5 的 W 编号和 §4 的需求行;按 §3 找到对应详细章节,**读取正文后再决定修改点**。索引、记忆或先前摘要不能替代本次涉及的合同/代码正文。
3. 核验前置证据及当前合同/工具版本:区分“方向已确认”“源已发布”“实现完成”“测试通过”。前置缺失就标 blocked,不猜 Schema、不用临时协议偷跑。
4. 给出本次范围、完成条件和明确不做项,再在当前授权范围内执行。用户明确要求开始本地开发后不重复询问已确认设计;修改上游唯一来源、真实业务网络/付费/拨号/切换等依旧按权限边界处理。
5. 优先复用标准库、成熟开源库/官方 SDK;先查已有实现再改,禁止自写替代协议栈。仅围绕本次任务增加必要代码和检查,不预建后续功能空壳。
6. 执行相应检查并保存脱敏证据,更新§8及阻塞/下一步。回报代码、模拟、真实验证分别完成了什么;失败和未执行不得记为通过。
### 2.2 开工确认格式
```text
任务:Wxx(本次子范围)
需求依据:文档相对路径+章节;契约/制品版本及哈希(适用时)
已确认要求:本次实际遵循的条目,不重新审批既定架构
前置证据:满足哪些;缺什么、由谁补齐
修改范围:本项目具体路径;是否涉及上游/真实资源
完成条件:接口I/模块M/合并集成G分别需要的可执行检查及期望事实
不做:明确排除的后续功能或未授权操作
```
只做文档任务时不伪造代码测试命令;进入代码任务后,先读相关代码/调用链再改。发现代码已存在时先核验再更新本计划基线,不能永久照搬“当前无实现”。
## 3. 参考文档索引与按需阅读
| 索引 | 文档 | 先读内容及使用方式 |
| --- | --- | --- |
| R0 | [AGENTS.md](../AGENTS.md) | 全文:独立项目、P1/P2、复用、安全和执行权限;每次开工先读 |
| R1 | [Go重写方案 v0.3](Go重写方案_v0.3.md) | 总体职责、数据/执行流程、工程结构、分期与切换;W00 通读,具体任务重读涉及章节 |
| R2 | [通信与事件数据交互 v0.1](通信与事件数据交互_v0.1.md) | 7条业务交互、8种事件、R01–R13 Unary、幂等/事实/控制、文件/OSS、GAP清单;做协议边界必读 |
| R3 | [G0开发准备与契约冻结方案 v0.1](G0开发准备与契约冻结提案_v0.1.md) | §1–2状态/解锁;§3事件;§4 AI;§5许可/会话/恢复;§6静态/OSS/profile;§7契约包;§8 PoC;§9确认结果。文件名保留“提案”,方向已经确认 |
| R4 | [验证与切换验收 v0.3](验证与切换验收_v0.3.md) | §1.2首发适用范围、§5.1 AI参数子场景、§9/§9.1基线及对应详细用例;当前88项是跨阶段清单,不是88项已通过 |
| R5 | [开源组件选型与复用清单 v0.2](开源组件选型与复用清单_v0.2.md) | §1.3首发基础栈/SDK、§4.3参数能力;全文复用禁区、许可证/锁版/PoC门禁;采用依赖前必读 |
| R6 | [OpenAPI与MQ字段索引 v0.1](OpenAPI与MQ字段索引_v0.1.md) | 来源指纹、实际操作/组件、严格Schema约束;只读生成索引,不能手改;42操作/115组件不等于本项目全量实现任务 |
| R7 | [README.md](../README.md) | 项目入口、当前范围及未来实际运行/验证入口;命令只能以届时真实存在的脚本/配置为准 |
| R8 | [SaaS↔Dispatcher 契约](contracts/saas-dispatcher.md) | MQ-only、D唯一身份/专用Topic、请求响应及旧实现差异;不是已发布新Schema |
| R9 | [Dispatcher↔Agent 契约](contracts/dispatcher-agent.md) | 当前Proto/handler事实;R12/R13与MQ异步协调的待改项;不能把本地上传或 MQ 入队等同 SaaS 已消费、处理 |
| R10 | [SaaS/MQ/D/A/OSS时间泳道图](contracts/saas-rabbitmq-oss-dispatcher-agent-timeline.md) | 目标全MQ时序、独立D订阅和新旧差异;所有中文新消息名仅为语义标签 |
### 3.1 按任务定位必读章节
| 当前要做什么 | 最小详细阅读范围 | 要取得的关键依据 |
| --- | --- | --- |
| 改外部MQ消息/拓扑或升级源包 | 本计划§1.2;R8全文/R10R3 §3/§4/§6.2/§7R2及R6实际源 | D身份/专用Topic、租户/请求关联、错误/期限、版本/哈希及正反例;旧HTTP只作语义对照,不继续实现 |
| 配置两种AI模式、缓存或传参 | R3 §4R1 AI章节;R5 §1.3/§4.3R4 §5.1 | mode兼容、原摘要、有效授权、参数到SDK映射、0/false、取消/自动重试 |
| 写SQLite、inbox/outbox或MQ接入 | R1持久化/调度章节;R2可靠性/事件;R3 §3/§5/§6.3;R4相关用例 | 持久后ACK、同事务outbox、原值tenant_key、复合幂等、有界窗口、恢复占用 |
| 做gRPC、会话、配额、拨号或控制 | R2 R01–R13及错误语义;R3 §5全文;R1控制/租约;R4故障用例 | 最后许可、共享证书的节点绑定、CAS、屏障、实际CPS、未知执行不重拨 |
| 做SIP静态配置、ARI/RTP/录音 | R1 Cell/媒体/配置;R2静态制品/加载;R3 §6.1;R5对应库;R4媒体用例 | 单 Cell 授权 fixture、唯一写入面、隔离实际加载、PCMA/PCM、原语义取消/清理 |
| 做OSS上传与恢复 | R2录音/R12/R13R3 §6.2/§6.3R4 E12/E19 | D配置文件→临时TOKEN→A直传;不向SaaS取OSS配置/TOKEN;显式重申请、原事实/通知幂等、可靠入队与文件恢复 |
| 调参数、上线或迁移/回退 | R3 §5.5/§6.3R4 §1.2/§9/§9.1及切换用例;R1切换章节 | profile来源、真实预算、证书/所有权隔离、单活备份、未知占用与回退条件 |
| 开第二真实租户/后续治理 | R0分期;R1租户/后续阶段;R4 §1.2及公平性用例 | P2门禁,不能仅把tenant数量从1改成2 |
普通构建/测试/运行只使用本项目内导入的只读契约包和自身文件,不读父项目目录。维护者查阅/导入上游发布物是明确的维护动作,不能变成运行依赖。
## 4. 已确认需求基线与任务映射
此表只索引约束,不复制字段Schema或供应商参数范围。
| 需求 | 已确认边界 | 主要任务/依据 |
| --- | --- | --- |
| Q01 独立工程 | Go 1.27.1、单module/二进制、Cobra显式agent/dispatcher;无Python运行依赖、不合并management | W00/W03R0/R1/R5 |
| Q02 P1拓扑 | 1个单活D/SQLite、1个Agent/1套Asterisk、至少3家独立SIP trunk 的配置/协议 fixture、1个启用租户;双节点/第二 Cell/第二租户不在本轮 | W05/W06/W09/W14R1/R4 |
| Q03 持久化 | D持有任务/配额/inbox/outbox;A无业务DB,执行/文字/录音/上传恢复落文件;不接PG/NFS双活 | W05/W06/W08/W13R1/R2/R3 §5 |
| Q04 MQ/身份/租户 | SaaS↔D全部交互只走RabbitMQ,禁双方HTTP;每个D全局唯一ID及独立接收Topic/队列,响应回原D;保留租户独立队列/原值key/复合幂等/有界窗口,完整新路由预算须重算,超限停发保留 | W01/W05/W08/W12;§1.2、R8/R10 |
| Q05 内部可靠性 | Unary gRPC、D预配Endpoint、共用A证书但独立会话;单 Cell 最后许可、控制屏障和未知占用按本地故障注入验收;跨 Cell 协调延期 | W02/W06/W08/W13R3 §5 |
| Q06 双AI模式 | ASR-only和完整AI均为P1D经MQ取得SaaS不可变AI配置/授权后给A,不再调用AI GET;不加任务mode字段、不靠CLI/env覆盖、不复用旧LLM/TTS | W01/W07/W10R8 §6.2/R3 §4/R5 |
| Q07 SIP唯一写面 | management批准静态快照,维护窗口关准入/排空/实际加载确认;不逐呼改共享配置、不虚构备用线路 | W01/W09/W14R3 §6.1 |
| Q08 OSS直传 | D配置文件保存OSS配置,A经Unary向D领临时TOKEN后直传;SaaS不下发OSS配置/TOKEND可靠发布recording.uploaded后完成通知,不申请业务会话、不等待verified或OSS IDSaaS后续处理不属本项目 | W01/W02/W11/W12R8 §6.1/R9 §6/R10 |
| Q09 复用与安全 | 使用成熟库/SDKmock/mixed/real显式隔离、Mock默认隔离真实外网;密钥/音频/对话不进代码文档日志 | 全部;R0/R5/R4 |
| Q10 真实验证与切换 | 每次真实拨号/云/费用另授权;只用原始白名单号码;旧新不双写、不双发额度;未知执行不自动重拨 | W14/W15R0/R1/R4 |
| Q11 分期 | P1执行单租户/单 Cell 原子额度、控制和恢复;双节点、第二 Cell、第二租户公平/背压/恢复、真实 SaaS/MQ 联调及动态发布、1000路/N+1、多D均为后续阶段 | W08/W16R1/R4 §1.2 |
## 5. 开发步骤、依赖与完成条件
W编号是本计划的工作分解,不是新增协议、需求或验收编号。沿用总体方案的P0、P1a–P1d、P2分期;下表为父任务,§5.4细化工作包和产物依赖。**先按门禁解锁,再按证据签收**,不按预计日期虚报完成。
就绪标记:**I(接口就绪)**=源/Proto或模块接口已冻结并合入共同基线,附版本/哈希及合法/非法样例;**M(模块就绪)**=该子任务实现并通过本地检查;**G(合并集成通过)**=合入指定共同提交后通过相关联合回归。文档方向确认不是I,分支测试绿不是G;运行安全要求不因M就绪而放行。非代码任务可标不适用,但须说明理由。
### 5.1 P0:合同、工程准备与关键PoC
| 步骤 | 开发内容与预期产物 | 前置/可并行关系 | 完成条件与阅读依据 |
| --- | --- | --- | --- |
| W00 开工核对 | 按§2映射请求,核对实际工具链/文件/工作区;登记范围、源版本、责任角色、外部阻塞 | 后续明确安排开发时开始;本轮只建计划 | 有开工记录和可验证前置清单;无误认已实现内容。读R0/R1/R3 §12/R4 §1.2 |
| W01 项目合同与P1交接冻结 | 在旧闭包之上发布MQ-only新版本:D唯一身份/生命周期、专用Topic/队列/绑定、所有请求/响应/来源/关联/错误/期限、完整路由长度;复用既有事件/AI/上传语义,不改旧不可变包 | W00;与W02及不依赖业务字段的W03 PoC并行;不得借此修改/冒充上游权威发布 | MQ-only新包自包含、来源/版本/哈希及严格Schema/拓扑正反例通过;旧2026-09-18/19包不能代签,真实预算/授权/外部签收分开。读§1.2/R8/R10及R2/R3/R6 |
| W02 内部协议定稿 | 保留已建立的 `agent.v1.AgentControlService`;核验MQ异步配置/上传结果与Unary的衔接、D逻辑身份与epoch边界;冻结R12/R13 pending/恢复/最终响应,确需变更才更新Proto/stubs,不编造当前能力 | W00;与W01并行;后续业务字段必须引用 W01 版本 | `buf lint/build/generate`、生成包测试、错误/幂等/状态合同可检验;不建R04/R06在线发布空壳。读R2 Unary章节/R3 §5 |
| W03 最小工程、契约包与复用PoC | 按§5.4拆W03-ae:先建最小单module/Cobra/构建基线,再独立验证生成工具、存储/消息、gRPC/媒体和AI/上传SDK | W03-a基线合入后,其余按各自接口依赖并行;源生成须等W01/W02对应产物,原理PoC不猜业务字段;共享依赖由集成负责人统一修改 | 精确版本/许可/漏洞及各子任务PoC证据,生成确定性与隔离构建通过;各子任务分别验收,边界和依赖清晰。W13-a另负责后续可部署完整候选制品。读R3 §7–8/R5 |
| W04 G0证据汇总 | 将D01D10逐项关联项目内契约、Proto、关键本地PoC及未决项,给出本阶段单节点 P1 放行范围 | W01/W02/W03的P1适用产物 | 项目内契约和必需本地PoC有证据即可标本阶段 G0;真实供应商/容量/生产验收列第二阶段,不用Mock代签生产。读R3 §2/§9、R4门禁 |
PoC可以提前排除库/工具风险,不意味着允许未冻结的业务实现。若某模块具备完整前置可独立推进,须在W04记录其解锁范围;不得因此宣称整体G0通过。
### 5.2 P1:持久控制面、执行面与完整业务闭环
W04整体或已记录的对应模块放行是本节共同前置;I/M并行只解除等待其它模块整包完工的约束,不跳过G0合同/PoC门禁,也不授权真实拨号。
| 步骤 | 开发内容与预期产物 | 前置/可并行关系 | 完成条件与阅读依据 |
| --- | --- | --- | --- |
| W05 Dispatcher持久控制面 | D唯一身份、专用Topic与租户隔离;所有SaaS请求/响应经MQ inbox/outbox持久接收/关联,控制/查询也经MQ;移除旧SaaS HTTP入口,不留兼容或回退 | W04放行 | 重复命令/commit前后故障不丢任务、不造第二执行;队列与持久待发起窗口有界;控制接收不伪装applied。读R1持久化/R2消息/R3 §3/§5 |
| W06 Agent运行与文件恢复 | 无业务DBgRPC/mTLS、受控激活/boot/session、健康/版本报告、原子文件与崩溃恢复;只接获授权任务 | W04放行;与W05并行 | 错SAN、错节点、重放、旧会话拒绝;新boot保留旧未知占用/资产;文件损坏隔离、敏感信息不泄露。读R2内部协议/文件/R3 §5.15.2 |
| W07 AI配置快照与授权 | W07-d经MQ获取SaaS不可变版本/授权,响应回原D并持久绑定;W07-a校验/执行快照;禁止开发旧AI GET client,覆盖重复/迟到/撤销/重启恢复 | 两端接口I及AI源已发布后可各自实现;联合G需W05/W06的相关模块M,不等对端全部功能完工才写适配 | 旧完整模式兼容、新模式明确;跨租户/同版本异内容/无授权拒绝;在途不漂移;0/false保真。W10继续验证SDK实际行为。读R3 §4/R5 §4.3/R4 §5.1 |
| W08 调度、单 Cell 额度和控制屏障 | W08-d负责D单 Cell 原子额度/许可/CAS,W08-a负责A发起串行区/控制/未知恢复;共享合同单写 | I就绪后两端及W09适配可并行;联合G需要W05–W07相关模块M和W09媒体模块M,一起验证后合入;不是先要求W08.G再允许编写W09 | 不超额、不因超时/过期/boot变化重拨或释放未知占用;单 Cell 屏障事实满足、且 `09:00``20:00` Asia/Shanghai 时间门禁通过才可发起;本地故障注入覆盖窗口边界和恢复。读R3 §5全文/R2/R4 |
| W09 静态SIP、ARI/RTP与录音 | 静态加载、SDK/ExternalMedia、PCMA/PCM、录音封口/清理;媒体适配独占写入,不改调度许可逻辑 | 静态/媒体接口I、W03库PoC就绪即可在本地适配开发,不等W08.G;接入业务发起必须等W08控制模块M,W08/W09联合G前禁止业务准入 | 隔离 Asterisk 22.10.1/ARI runtime 已证明内部 Stasis channel、mixing bridge、PCMA ExternalMedia、RTP 地址/端口和 `StasisEnd` 生命周期,并以双 ExternalMedia 合成流验证 RTP v2/PT=8 经 bridge 转发(证据:`docs/evidence/20260918-w09-ari-runtime.md`);仍需真实同通道/完整媒体会话、录音 retention/OSS handoff、重连、精确静态加载和控制竞态/CPS;不为并行绕过许可,真实供应商留W14。读R1/R3 §6.1/R5/R4 |
| W10 双模式AI执行 | ASR-only再完整AI;参数/取消/打断/背压、final/播放证据、获批opt-out;仅写AI适配边界 | AI快照/音频/事实接口I与SDK PoC就绪即可用协议Mock独立开发;G需W07和W09相关模块M,并通过W08发起屏障联测 | 按模式留证据;ASR-only不启LLM/TTS,完整模式不用旧实现;不支持参数拒绝;实时opt-out不等OSS。真实供应商属于第二阶段。读R3 §4/R5 §4.3/R4 §5.1 |
| W11 Agent→OSS直传与恢复 | W11-d核验D配置文件→临时TOKEN及显式重申请,保留SDK签发能力;实现R12/R13原授权请求、上传事实和recording.uploaded持久通知关联,W11-a保留直传/恢复;D不转发文件,不删除签发职责,也不新增SaaS会话/verified等待 | 上传合同、封口文件元信息/生命周期接口I即可用合法测试文件开发,不等整套W09;G需W05/W06相关模块M并接W09实际封口产物联测 | D/gRPC不传文件;有效授权在15分钟内完成一次PUT;过期/失败保留文件并等待显式重新申请;成功PUT后报告原上传事实;以persistent、durable队列/绑定、mandatory无return及confirm完成通知;只恢复原通知,不重PUT、新建资产或等待OSS ID。读R3 §6.2/R2/R4 E12/E19 |
| W12 事件、整体补传及运行可观测性 | D负责人维护MQ来源身份/响应关联、事件/outbox及MQ整体结果补传;移除HTTP补传和重发call.execute当补传的旧行为;A事实/指标及公共Schema保持单写 | 按事件接口I和所属模块推进;最终G需W10/W11联合证据;禁止另起Agent同时重写前序模块的事件代码 | confirm不等于应用收讫;无task/execution补传;域版本不互盖;水位/错误阻止不安全准入。日志/指标随模块实现。读R2/R3 §3/§6.3/R4 |
### 5.3 P1验收、切换与P2入口
| 步骤 | 开发/验收内容 | 前置 | 完成条件与阅读依据 |
| --- | --- | --- | --- |
| W13 单节点部署候选与故障集成 | 先W13-a:可复现构建制品、digest/清单、非root分角色权限/目录、配置样例及运行手册;再用同一制品在隔离 DB/broker/单 Asterisk 环境注入重启、丢包、证书、磁盘、额度和 OSS 故障 | W13-a可随前序完善,完整候选冻结需W08–W12联合G;禁止以真实 ECS 或手工外部环境作为本轮前置 | 验证单 Cell 重启/断连/证书轮换/磁盘使用 unknown/容量失败语义/额度屏障/OSS恢复/备份;记录候选代码commit和制品digest。P1适用用例逐项签收,Mock/mixed明确标注。读R1部署/R4/R3 §56 |
| W14 单节点本地集成验收 | 用W13候选在本地/隔离环境验证单 Agent/单 Asterisk、至少3家SIP fixture、1租户、双AI、MQ/OSS契约、PCMA/RTP、控制/恢复、本地CPS及 `09:00``20:00` 时间门禁 | W13通过;契约/fixture、隔离 DB/broker、AI/OSS协议 Mock、本地故障注入和窗口边界测试齐备;真实 ECS/供应商/生产 receipt 延期第二阶段 | P1-01–P1-10适用子场景通过;不能把 fixture 写成真实联调。真实 SaaS/MQ、真实外呼、双节点/第二 Cell/第二租户不阻塞本轮。读R0/R4/R3 §6 |
| W15 第二阶段生产切换(本轮不适用) | 真实联调完成后,另行执行排空、唯一写入/调度所有权交接、备份及未知执行核对;本轮只保留本地恢复证据 | 第二阶段另行授权、真实维护窗口和生产回迁方案 | 不把未执行的生产切换写成通过;本轮由 scope amendment 记录不适用。读R1切换/R4/R3 §6.3 |
| W16 第二阶段多租户公平(本轮不适用) | 双租户、等权轮询、配额不足跳过、完整背压、轮转恢复、死信/重试归原租户和公平验收 | 第二阶段另行安排;本轮只验证单租户窗口/配额 | 不开放第二真实租户;本轮不把双租户测试缺失列为阻塞。读R0分期/R1租户/R4公平性 |
交付主线:`W00 → W01/W02/W03按产物推进 → W04(项目内契约范围)→ W05/W06基础 → W07W12按I/M并行及联合G → W13单节点候选/故障 → W14本地集成`。W15生产切换、W16双租户公平为第二阶段,不阻塞本轮;此箭头表示交付关口,不要求模块编写整包串行,精确依赖以下表为准。
### 5.4 工作包与产物依赖
以下是逻辑工作包和产物依赖,按实际范围安排;不存在接口/测试资源时不以想象中的模块目录启动工作。
| 工作包 | 负责角色/边界 | 开始条件及交付 |
| --- | --- | --- |
| W01 / W02 | 契约负责人;外部来源与内部Proto分清权威,业务实现不得手改源 | W00;产出已发布外部包/正式Proto及I金样;上游修改仍须授权 |
| W03-a | 集成负责人 | 先合最小工程、构建/测试入口、锁工具链和依赖,发布共同基线B0;不建无用途空壳 |
| W03-b | 生成工具负责人;生成结果仍由公共产物负责人合入 | B0;验证真实源方言/引用闭包/生成确定性,需W01/W02相应源 |
| W03-c | 存储/消息PoC负责人 | B0;独立SQLite/文件/broker环境验证持久/恢复,不定义业务协议 |
| W03-d | gRPC/媒体PoC负责人 | B0;原理PoC可先做,业务协议测试需W02.I;固定本地Asterisk/SDK |
| W03-e | SDK PoC负责人;确有独立边界可再拆ASR/LLM/TTS/OSS子任务 | B0;参数映射和取消/重试;本地协议Mock不等于供应商实测 |
| W05、W07-d、W08-d、W11-d、W12-d | Dispatcher负责人 | 依父任务前置按顺序交付;SQLite迁移/服务端业务/事件outbox统一维护 |
| W06、W07-a、W08-a、W12-a | Agent核心负责人 | 依父任务前置交付;会话/文件生命周期/本地发起门闩同一写入者 |
| W09-media | 媒体负责人 | 静态/媒体接口I及库PoC;独立适配M,与W08-a/d联合G;不能绕过许可接业务拨号 |
| W10-ai | AI负责人 | 模式/快照/音频/事实接口I及SDK PoC;用批准样例实现M,再与控制/媒体联合G |
| W11-a | 上传负责人 | 上传/文件生命周期接口I及SDK PoC;合成合法测试文件实现M,再与D/封口产物联合G;不自行修改D或A核心 |
| W13-a | 部署负责人(可由集成负责人兼任) | 早期维护真实可运行入口;相关G完成后冻结完整制品/配置/手册;W13-b必须使用它 |
| W13-b / W14 / W15 | 集成/验收负责人;本地/隔离环境单一调度 | 顺序执行候选集成和本地验收;W15生产交接延期第二阶段;只读审查可并行,不能并行改同一环境 |
联合G不互相等待另一任务的G:例如W08/W09各自M及依赖到齐后,一次合并候选联合测试,再分别记G。W10/W11的接口样例必须来自I;生产依赖未就绪时用协议Mock完成M,不能把Mock变成生产回退。契约负责人更新I版本后,受影响任务必须重新对齐和验证,不能混用新旧基线。
## 6. 门禁、阻塞和明确不做项
### 6.1 各阶段状态不能混用
| 关口 | 放行什么 | 不能据此宣称什么 |
| --- | --- | --- |
| 方案确认(已完成) | 按既定方向准备合同与PoC,不重复架构审批 | 不等于Schema已发布、Proto已生成、库兼容或实现完成 |
| G0/对应模块前置(受影响部分重开) | 旧基线曾完成;MQ-only新版本须按§8.2重新取得I与本地证据再放行 | 旧通过不等于新MQ契约通过,也不等于第二 Cell、真实供应商或生产验收 |
| 本地P1验证(本轮) | 完成单节点/单 Cell/单租户契约、协议 fixture、故障注入和本地回归 | 不等于真实供应商、生产 SaaS/MQ receipt 或生产切换 |
| 真实P1与切换(第二阶段) | 获授权后另行受控联调/首发运行 | 不属于本轮验收;双节点、第二 Cell、第二租户及1000路/N+1仍另立项 |
外部缺项按角色记录:S(SaaS契约/AI授权)、M(管理平台制品/审批)、O(部署/安全/供应商/预算),D/A负责实现证据。实际责任人未安排写“未指派”,不能代签。阻塞记录至少包含:受影响W/Q/D项、缺失事实、责任角色、可并行工作、解除证据。
### 6.2 不纳入本轮及P1的扩展
P1不预建在线发布/回滚编排、自动SIP FALLBACK、多Dispatcher协调/HA、权重借用、1000路/N+1实现或文本OSS专属归档;这些后续能力另行安排,不阻塞P1的合法开发,也不能将当前安全屏障延期。**D全局唯一ID、专用Topic及D1/D2隔离消息fixture属于本次MQ契约修正,不得借“多D延期”省略;不要求部署第二业务Dispatcher。**
**单EIP+NAT与第二套管理后台不是延期功能,而是明确排除的架构**;后续也不得自行设计、实现或验收。持续采用多机器/多EIP直连,management保持SIP配置唯一编辑/审批面。
真实电话仅允许原始号码 `15003164745``15830461047`,白名单不是呼叫授权;**SIP外呼仅允许 Asia/Shanghai 每日 `09:00`(含)至 `20:00`(不含),窗口外 Dispatcher/Agent 必须 fail-closed,不能等待、自动延迟、重试或换线;每次实际外呼前仍必须在当前会话再次获得用户明确确认,并展示将使用的SIP通道名称、外呼号码和抓包方案;每条 SIP trunk 对每个原始手机号每天最多 3 次,线路失败可在额度内经当前会话确认后改测另一条线路;此前确认不自动延用,也不得自动重试或超额。** 云创建/EIP变更/网络放行/供应商消费/清理都另行授权,不能因计划写了W14就自动执行。
## 7. 验证及证据规则
### 7.1 文档阶段
检查相对链接、章节引用、表格结构、D01–D10确认状态、源指纹及改动范围。仅改索引/计划不得手改生成Schema/字段索引,也不能以文档检查替代运行验收。W01/W02及本地代码已建立后,文档检查仍不能代替下列代码/集成/真实验收。
### 7.2 后续代码阶段
在本项目自己的实际 Go module 根目录,至少执行:
```sh
# 项目内模块基线的最低验证要求;每次协议/运行时变更后重跑。
go version
go vet ./...
go test -race ./...
go build ./...
```
另做自有源码格式检查,输出差异而非静默改动第三方/生成物;核验实际Go 1.27.1及构建镜像/依赖锁。当前入口还须运行 `buf lint/build/generate``scripts/check-contracts.sh``scripts/check-proto.sh``make acceptance-local`;对应任务还须运行源生成一致性、真实隔离DB/MQ、协议、故障注入及实际构建入口的检查。以上命令不代表所有验收完成。
证据使用稳定的项目相对路径(后续可在 `docs/evidence/` 下按W/工作包保存,不提前建空目录),记录环境/mock-mixed-real、代码base/head/integration commit、制品/合同/依赖版本、命令、预期与实际、退出码、时间和风险。工作包证据按实际范围归档;集成负责人将证据绑定到实际合并提交后记G。禁止存密钥、完整音频/对话,不复制旧报告冒充验收。
## 8. 当前执行台账(后续 Agent 必须维护)
状态词固定使用:`未开始``进行中``blocked``待验证``完成`;“完成”须有对应证据,不代表后续真实验收完成。本节由集成负责人维护,任务负责人提交证据和状态建议。每个父任务按工作包记录I/M/G;代码父任务需所属工作包的合并回归通过才完成,只有局部M时保持待验证。本轮文档完成不等于W00开发开工已执行。
项目已交付旧W01基线、W02 Proto/stubs和旧本地P1证据。**本轮MQ-only修订的本地代码范围已按§8.2取得新证据;表内旧证据保留为历史,不能据旧HTTP、单租户路由或本地OSS结果关闭新门禁。** 未受影响模块的旧通过事实不撤销。本轮已执行本地契约、RabbitMQ、恢复、race、vet、构建、覆盖率和acceptance检查;业务源码覆盖率(排除生成protobuf)为65.8%。真实供应商、云、生产验收及当前主机缺失Asterisk/tcpdump的部署诊断未执行,未伪造通过。
| 步骤 | 当前状态 | 历史证据/原基线结论(不代表新修订通过) | 当前下一动作 |
| --- | --- | --- | --- |
| W00 | 完成 | 已读 AGENTS、计划与 R0/R1/R3/R4/R5;工具链为 Go 1.27.1;已记录父工作区既有改动和契约源 commit。证据:`docs/evidence/20260918-local-development.json` | 维护本地基线并按 W04 证据门禁推进 |
| W01 | 完成 | 当前唯一 `contracts/upstream/v1` 已收敛为严格事件/AI/授权/OSS/静态制品/profile Schema、正反例、路由预算及JCS向量;早期 W01 基线仅作为归档文件。证据:V1 bundle、`internal/contract``internal/ai` 测试 | 外部签收与本地冻结分开;未发生契约迁移前不新增契约 |
| W02 | 完成 | `proto/agent/v1/agent.proto``gen/agent/v1/*``proto/ERRORS.md`、manifest 已交付;`buf lint/build/generate` 和生成包测试通过,覆盖 R01R03/R05/R07R13,不建 R04/R06 空壳 | 核验D身份/epoch和R12/R13的MQ异步衔接,按需冻结Proto变更,见§8.2 |
| W03 | 完成 | W03-a 单 module/Cobra/构建基线、W03-c 存储/MQ 本地实现、W03-e AI Schema/contract SaaS Mock PoC、W03-d Pion RTP thin adapter、gopsutil 资源采样已有测试;已完成 Go module 许可证清单、`go mod verify``govulncheck@v1.7.0`(Go 1.27.1 构建)无漏洞扫描;临时 module 的 `ari/v5.3.1``openai-go/v3.62.0``dashscopego/v0.1.2``doubao-speech-go` API/协议 Mock PoC 通过但均未锁入项目;固定 Asterisk 22.10.1 + 临时 ARI client runtime PoC 已通过内部 Stasis/bridge/ExternalMedia lifecyclePJSIP/PJSUA2 full mock leg 已通过双向 PCMA、U1/U2/U3 播放、端点 WAV 封口和 ARI cleanup(证据:`docs/evidence/20260918-w09-sip-rtp-ari.md`);一次 disposable RabbitMQ 4.1.8 broker confirm/ACK/DLQ 集成通过,并新增 Dispatcher tenant consume→SQLite inbox/task/outbox→event publish integration test;另以 `TestOutboxProcessCrashRecovery` 覆盖一次真实测试子进程在 outbox claim 后退出、父进程恢复并发布的本地故障窗口(证据:`docs/evidence/20260918-w05-restart.md`);2026-09-19 另锁定物理 Asterisk 22.10.1 source/native-stage、Jansson 2.15.0、PJPROJECT 2.17 和 Debian 13 systemd 构建/安装输入,依赖补充证据见 `docs/evidence/20260918-dependencies.md``make check`、脚本语法和 deployment lock JSON 检查通过 | 本阶段项目内 Go/SDK/契约/隔离验证已签收;生产 ARI module/tag/许可证、供应商真实 SIP/媒体、录音 retention/OSS、批准 broker 版本/ACL、真实 broker/commit 故障注入属于第二阶段;隔离 SIPp-to-PJSIP/ARI signaling 证据见 `docs/evidence/20260918-w09-sip-ari.md`,不把本地或隔离 PoC 当生产通过 |
| W04 | 完成 | W01/W02 项目内产物和 D10 隔离 PoC 已具备;本阶段项目内 G0 契约、Schema、fixture、隔离 PoC 和范围修订已签收;外部权威、真实预算/角色签收、生产依赖及生产运行证据属于第二阶段,不计入本轮门禁;汇总:`docs/evidence/20260918-g0-status.md` | 汇总新MQ合同及本地PoC,重新签收受影响G0,见§8.2 |
| W05 | 完成 | 已有 SQLite inbox/tasks/quotas/controls/replays/outbox、control HTTP、本地 reservation-to-Agent seam 和 RabbitMQ adapter 的 publisher confirm、prefetch=1、per-tenant DLQ 拓扑测试;新增 contract-backed local flow 将租户命令、配额、Agent 执行和 event 校验串联;`make mq-integration-local` 已用 disposable RabbitMQ 4.1.8 验证 adapter confirm/ACK/permanent reject→DLQ/consumer cancellation,以及 Dispatcher tenant consume→SQLite inbox/task/outbox→event publish;新增 Dispatcher close/reopen replay test 及 `TestOutboxProcessCrashRecovery`claimed outbox 在测试子进程崩溃后恢复并重新发布(证据:`docs/evidence/20260918-w05-restart.md`);当前候选二进制已在 owner-authorized ECS 连接隔离 RabbitMQ,完成 tenant consume→SQLite inbox/task/outbox→candidate automatic outbox flush,最终 `task_status=accepted``outbox_status=published`,无需单独 `--once`,且临时 SaaS-events queue 收到 `agent-call.command.result`(证据:`docs/evidence/20260918-rabbitmq-integration.md`);本阶段契约拓扑、隔离 broker、confirm/ACK/DLQ、单租户窗口和本地崩溃恢复已签收;批准生产 broker/ACL、SaaS application receipt 和真实 broker 故障注入延期第二阶段 | 实现D身份/专用Topic和全部MQ控制/查询请求响应,移除旧HTTP,见§8.2 |
| W06 | 完成 | 已有文件状态、transcript/assets、unknown 恢复和损坏隔离测试;`agent.v1` runtime handlers、TLS1.3 mTLS config、持久 session-generation journal、session/fencing/CAS/permit/fact/upload boundary、静态 Cell 制品启动路径/激活校验、gopsutil 主机/进程采样(媒体/AI维度显式 unknown)、R01 pre-activation status、Dispatcher AgentCoordinator/no-retry reconciliation 与可选 CLI listener 已通过本地测试;mTLS smoke、session generation、fingerprint allowlist 和错误 endpoint 拒绝已有证据;跨主机/第二 Cell/fleet-wide rotation 属后续阶段,不阻塞本轮单 Cell 验收 | 本阶段单 Cell 健康/版本报告与隔离故障矩阵已纳入本地 P1 证据;后续阶段再做跨主机 fleet 管理 |
| W07 | 完成 | W01 项目内 AI 双模式/授权/digest Schema 和样例已闭合;RPC Agent 可按部署注入的不可变快照/授权/egress 对 permit 与 Execute 做租户、版本/digest/mode、有效期、egress、撤销校验,DispatcherCoordinator 继续绑定 permit;本地 SaaS contract/fixture Mock 已由 `scripts/check-contracts.sh``internal/contract``internal/ai``make mq-integration-local` 覆盖(证据:`docs/evidence/20260919-local-saas-contract-mock.md`);真实 SaaS 读取/持久授权源延期第二阶段;本阶段契约 fixture/隔离授权已签收 | 本轮补MQ配置/授权和持久绑定的本地闭环;真实SaaS联调仍第二阶段,见§8.2 |
| W08 | 完成 | 已有租户/单 Cell scope 原子配额和 control CAS 本地测试;`Dispatcher.ExecuteReserved` 已把 SQLite reservation 与 fenced Agent permit/Execute 联通,提交前失败原子回队列,未知结果转 unknown 并保留占用;mTLS mock Agent accepted receipt 已有证据;单 Cell 最后发起屏障、控制竞态、本地故障注入和真实 MQ receipt 的本阶段边界已按契约/隔离证据签收;生产 receipt 延期第二阶段 | 重新验证MQ控制与CAS/最后发起屏障的联合行为,见§8.2 |
| W09 | 完成 | 已采用 Pion RTP v1.10.5 的 bounded `PacketGuard`,使用库解析并覆盖 payload/SSRC/包长边界;项目内 `contract.ValidateStaticArtifact` 已完成静态制品 Schema、Cell/source/digest/revision/egress/trunk 绑定校验;临时 module 的 `ari/v5.3.1` 已在固定 Asterisk 22.10.1 隔离容器完成内部 Stasis channel、mixing bridge、RTP/UDP PCMA ExternalMedia、地址/端口、RTP v2/PT=8 bridge 转发、录音 WAV 封口/清理和 `StasisEnd` runtime probe(证据:`docs/evidence/20260918-w09-ari-runtime.md`);隔离 SIPp-to-PJSIP/ARI signaling 及 PJSIP/PJSUA2 full mock leg 的双向 PCMA、U1/U2/U3、端点 WAV 和 cleanup 另有证据 `docs/evidence/20260918-w09-sip-ari.md``docs/evidence/20260918-w09-sip-rtp-ari.md`;新增本地 `TestPacketGuardPreservesPCMAPayloadByteForByte` 通过 160-byte PT=8 fixture 的精确 payload/header 保真;owner-authorized ECS 又按用户选择对三条登记线路各发一条真实 INVITE(目标 `15003164745`):数企返回 `480 Temporarily Unavailable`,中鼎返回 `404 Not Found`,百应返回含 PCMA SDP 的 `183 Session Progress` 但 25 秒内无 `200 OK`,均未形成已接通对话(证据:`docs/evidence/20260918-real-sip-provider-calls.md``docs/evidence/20260919-real-sip-provider-calls-retry.md`);后续允许窗口重试仍为数企 `100/183``200`、中鼎 `100` 无最终响应、百应 `100/183/180``200`2026-09-19 新 ECS 对两个白名单目标再次直连真实供应商:数企/百应均无最终 `200`,中鼎第二目标一次信令达到 `200`,但后续媒体 probe 未干净完成,仅捕获 5 个 SIP 包和 1 个非 SIP UDP 包,未验收 RTP/录音,证据:`docs/evidence/20260919-real-provider-ecs-direct.md`;同一 ECS 已直接编译并以 systemd 启动物理 Asterisk 22.10.1provider-second endpoint 为 `Avail`;一次 bounded Asterisk 真实外呼 origin 返回 0,但仅有 13 个 SIP 包、1 个非 SIP UDP 包和 0 字节录音,未形成干净 RTP/录音证据;同一物理 Asterisk 又按线路前缀对 provider-primary/provider-third 各做一次直接 PJSIP bounded probe,均仅有 10 个 SIP 包和 1 个非 SIP UDP 包,无录音/干净媒体;最新一次 provider-second 外呼在用户即时确认后执行,临时 PCAP 仅观察 8 个 SIP 包、0 个媒体包和 `100/200/404` 状态 token,原始 PCAP 已删除且未自动重试;父目录三条线路与当前 Go 边界的注册/认证、From/PAI、前缀和选路对比见 `docs/evidence/20260919-sip-routing-implementation-comparison.md`;新增 `docs/evidence/20260919-mixed-ari-callflow.json`:隔离 `sip_mock_server` 的 mixed 模式通过真实 ARI/ExternalMedia/双向 RTP/Agent-side WAV 和共享 CallFlow;当前静态制品已将 ExternalMedia 媒体 profile 按 trunk 配置,三条真实线路默认选择 Python 已验证的 PCMA/A-law 8 kHz/PT8Go 内部统一 PCM16/16 kHz;仍无供应商真实媒体、端到端生产 PCMA sample preservation、录音 retention/OSS handoff、重连和 Agent 媒体集成;本地 PCMA/A-law G.711 转换、ExternalMedia `alaw` 选择、双向 RTP、非静音录音和共享 CallFlow 已由 `docs/evidence/20260920-pcma-mixed-callflow.json` 闭环验证;真实供应商与生产静态加载仍未通过 | 本阶段本地/隔离媒体、录音、OSS contract fixture 和静态加载已签收;第二阶段再做 ARI 生产 tag/许可证、供应商真实媒体、retention、重连及生产静态加载;不手写协议栈 |
| W10 | 完成 | 项目内双模式 Schema、bounded/cancellable ASR-only/full-AI mock pipeline 和参数/取消单测已闭合;已锁定 OpenAI-compatible、Doubao ASR 和 Bailian Qwen3 TTS SDK/HTTP 适配,`AGENT_CALL_PROVIDER_SMOKE=1` 已通过 ASR→LLM→TTS provider chainTTS WAV 解码/16k 重采样和结果长度事实已验证;隔离 `sip_mock_server` mixed ARI 联测已完成 31 个入站 RTP 包、19,840 字节入站媒体、Agent-side WAV、transcript/reply 事实;Go shared CallFlow 现按 Python Cell 行为执行开场播放、首语音等待、最大 turn、三轮/120 秒会话上限、尾静音截断和无效通话早停,并按 trunk media profile 做 A-law/PCM16 转换;新增 PCMA `call-once` 端到端证据 `docs/evidence/20260920-pcma-mixed-callflow.json`,完成 ARI answered、PCMA/8000/PT8、ExternalMedia `alaw`、110/20 双向 RTP、U1 播放、双端非静音 WAV、transcript/reply;一次 freshly-confirmed provider-second 真实外呼曾进入 Stasis/ExternalMedia 并观察到 220 RX/136 TX RTP,但真实 ASR 为空;当前 capture-first provider-second 重测仍以 `cause=1``StasisStart` 前结束,PJSIP/完整 PCAP 记录 `100 Trying``404 Not Found`,无媒体;provider-primary capture-first 记录 `100/183/486 Busy Here`,同样无媒体;provider-third 则已完成一次约49秒三轮真实 AI、RTP、3段入站/4段出站录音和双方文本事实。证据:`docs/evidence/20260920-real-provider-second-capture-first-v9.json``docs/evidence/20260920-real-provider-primary-capture-first.json``docs/evidence/20260920-real-provider-third-capture-first.json`;禁止以 provider smoke 或 Mock 代签 | 第二阶段在获得真实供应商授权后再重跑 RTP/ASR/LLM/TTS/播放联调;不自动更换通道或号码 |
| W11 | 完成 | W01 OSS upload control-plane Schema、Agent 受限 grant 的 HTTPS/host/size/checksum/expiry/object-key/redirect 防护、直接 PUT client 和 upload metadata RPC handlers 已通过本地测试;Alibaba OSS SDK v2 presigned PUT、PUT、SHA-256、SQLite durable grant/completion、旧`recording.ready` outbox(已删除,当前为`recording.uploaded`)、显式重新申请及幂等已有证据;本阶段旧上传会话/complete/verified描述已由固定15分钟、单次PUT和可靠入队边界取代,真实 SaaS handoff 延期第二阶段 | 本轮D配置文件/TOKEN接线、Agent单次PUT及原通知恢复已有本地证据;补充封口录音大小/时长事实回归,最终联合验证仍见§8.2;不再实现SaaS会话/verified |
| W12 | 完成 | 8种事件 strict Schema/fixtures、command.result outbox、`transcript.updated` builder、资源 freshness/unknown、invalid alias rejection 和 contract-backed local flow 已通过本地测试;`internal/calllog` 脱敏业务日志、统一 AgentControl listener、R11 fact durable 去重/冲突和 Dispatcher-owned aggregate version 已有专项证据;本阶段按契约结构、fixture、confirm/outbox 状态机和隔离 RabbitMQ 验收,生产 broker ACL/TLS/application receipt 延期第二阶段 | 实现MQ来源/关联和整体结果补传,移除HTTP与重投执行的旧补传路径,见§8.2 |
| W13 | 完成 | W13-a 可复现构建制品、manifest、非 root 权限/目录、配置样例、capture-first 入口和本地 package smoke 已有证据;最新本地 `gofmt``go build``go test -race ./...``go vet ./...``go mod verify`、契约和 Proto 检查通过;本轮只需在本地/隔离单 Cell 注入重启、断连、证书、磁盘、额度和 OSS 故障,不要求 ECS 或第二 Cell | 依据新MQ合同更新候选配置/手册,重新验证消息及上传故障,见§8.2 |
| W14 | 完成 | 本轮仅认可单节点本地/隔离 session/permit 与 MQ 证据;后续云主机、真实供应商和真实外呼段均为历史记录,不作为本轮门禁;一台 owner-authorized Debian ECS 已创建、加固并完成二进制 mock smoke,并在该主机隔离运行 Asterisk/PJSIP/PJSUA2/ARI compatibility probes;本轮另从固定 EIP 对三条登记 SIP endpoint 完成 OPTIONS `200 OK` reachability probeprovider-primary 本次 capture-first 对 `sip:708915003164745@61.132.228.221:5060` 返回 `100/183/486 Busy Here`provider-second 此前对 `sip:15003164745@60.171.24.90:5060` 返回 `100/404`;两次均有完整失败 PCAP,但未进入媒体;经本次当前会话确认,provider-third `160.202.254.79:5060` 对原始号码 `15003164745` 返回 `100/183/180/200`,完成约49秒三轮真实 AI 通话、3段入站+4段出站 PCM16/16k录音和双方文本事实;新 ECS 两白名单目标的直接真实供应商探针和物理 Asterisk bounded call 见 `docs/evidence/20260919-real-provider-ecs-direct.md`。新增 physical-host systemd package 安装 smoke,但其 manifest 仍为 dirty/non-production,未启动生产服务。仍没有批准生产 broker/SaaS application receipt、真实 provider-third 录音上传闭环、第二 Cell/第二 Asterisk 及完整 3 供应商真实证据(已移出本轮范围);Alibaba OSS grant/PUT/HEAD、15分钟单次 token/显式重新申请、durable completion 和 recording.ready outbox 已完成授权本地及新 ECS mTLS gRPC→OSS 实际上传验证;provider-third 的单 Cell SIP/RTP/AI/录音/文本成功仅为部分证据,隔离 ECS RabbitMQ candidate receipt 仅为部署证据。证据:`docs/evidence/20260918-cloud-host-bootstrap.md``docs/evidence/20260918-rabbitmq-integration.md``docs/evidence/20260918-real-sip-provider-calls.md``docs/evidence/20260919-real-sip-provider-calls-retry.md``docs/evidence/20260919-real-provider-callflow-attempts.json``docs/evidence/20260919-physical-systemd-deployment.md`、W09 evidence2026-09-20 已按用户授权创建并加固 Debian 13 ECS `i-2zeew9pswry8sr33095l`,绑定固定 EIP `123.56.71.98`,安装 Asterisk/Go Agent;一次真实 provider-second 外呼曾观察到双向 RTP但 ASR 为空,新版三轮重试以 `cause=1` 在 StasisStart 前结束;capture-first v4 的 PJSIP logger 明确记录 provider-second 对 `sip:15003164745@60.171.24.90:5060` 返回 `100 Trying``404 Not Found`,但短事务 PCAP 为 header-onlyentrypoint 已加入 drain,真实三轮/录音/双方文本/OSS/MQ 仍未闭合;部署与失败证据:`docs/evidence/20260918-cloud-host-bootstrap.md``docs/evidence/20260920-real-provider-second-15003164745.json``docs/evidence/20260920-real-provider-second-3turn-attempt.json``docs/evidence/20260920-real-provider-second-capture-first-v4.json``docs/evidence/20260920-real-provider-second-capture-first-v7-package.json``docs/evidence/20260920-real-provider-second-capture-first-v9.json``docs/evidence/20260920-real-provider-third-capture-first.json``docs/evidence/20260920-real-provider-primary-capture-first.json``docs/evidence/20260920-real-sip-attempt-ledger.json``docs/evidence/20260920-sip-attempt-guard.md``docs/archive/evidence/20260920-acceptance-status.md``docs/evidence/20260920-real-cloud-inventory.md` | 重新执行MQ-only本地全流程及D1/D2路由fixture,旧验收不覆盖修订,见§8.2;真实联调仍另授权 |
| W15 | 完成 | 生产切换、真实唯一写入权交接和未知执行回迁不属于本轮;本地恢复/回滚和唯一写入规则已按适用范围验收,生产切换延期第二阶段 | 保留 scope amendment 和本地恢复证据;第二阶段另行授权 |
| W16 | 完成 | 双租户公平、第二 Cell 汇总和真实 broker 背压/DLQ不在本轮开发或验收范围;已有单租户有界窗口/SQLite恢复测试,范围修订已记录 | 第二阶段另行安排;本轮不开放第二真实租户,不作为 P1 阻塞 |
### 8.1 前次文档变更(历史记录)
以下保留当时的范围和检查事实。其中上传会话/verified等待已经被当前§1、§8.2及已确认的MQ-only冻结方案取代,不作为当前实现或验收要求。
- 状态:完成(仅当时文档阶段)。
- 保留此前新增时间泳道文档及计划记录;将其中错误的HTTP目标纠正为全部经MQ,并补齐D唯一身份/独立Topic、请求响应和旧实现差异。
- 同步SaaS↔D、D↔A契约及相关总体、通信、G0、验收和AGENTS约束;不修改Schema、Proto、代码、生成索引或旧证据。
- 用户随后确认OSS配置存于D配置文件,A从D领取临时上传TOKEN;已纠正先前“SaaS下发OSS配置/TOKEN、删除D签发”的误判。该历史段落中的业务会话/verified表述已被当前recording.uploaded可靠入队边界取代。
- 完成条件:目标时序无SaaS↔D直连、所有交互明确MQ路径、独立D接收与租户隔离不冲突、新旧状态分开。
- 本轮OSS来源纠正文档验证已通过:11份文档、75个本地链接/锚点、76张表格、代码围栏/空白及`git diff --check`;当前时序保留D配置→D临时TOKEN→A直传→`recording.uploaded`可靠入队,无SaaS↔D直连。旧“SaaS提供OSS配置/TOKEN、删除D签发”及verified等待表述已清理;代码、Proto、旧契约包/生成索引及历史证据未改。未进行Mermaid渲染,不以静态检查替代运行验收。
### 8.2 MQ-only修订后的当前待办与解除条件
| 工作包 / 当前状态 | I/M/G 与下一动作 | 解除条件 |
| --- | --- | --- |
| W01 / 完成 | 单一 V1 契约包、严格Schema/正反例、D身份/路由预算及JCS摘要通过;见`20260921-mq-v1-contracts.md``20260921-ai-jcs-digest.md``20260922-mq-only-local-final.md` | 仅外部签收仍不在本轮 |
| W02 / 完成 | R13已移除oss_id并保留reserved字段;Agent执行/控制文件恢复、原回执、新会话重放及Proto生成一致性通过 | 不把Agent启动快照宣称为外部动态AI交付 |
| W04 / 完成 | 新I、PoC及本地证据已汇总 | 外部权威/角色签收仍另行处理 |
| W05/W08/W12 / 完成 | 旧SaaS HTTP业务入口已删除;MQ查询/补传、控制worker、重复/丢回复/SQLite重启、断连和迟到revision有本地往返证据,见`mq-control-recovery.md`、查询/补传证据及`20260922-mq-only-local-final.md` | 外部SaaS receipt不在本轮;accepted不等于applied,不重发执行当补传 |
| W07 / 完成 | 实际本地RabbitMQ配置请求/内嵌授权响应、原请求关联、重复、范围和SQLite恢复通过,见`mq-ai-local-roundtrip.md` | 不发明独立授权消息;Agent动态交付边界仍按现有Unary合同 |
| W11 / 完成 | D配置文件、固定15分钟授权、原请求/显式新请求、单次PUT及recording.uploaded恢复已有本地证据,见`20260921-mq-upload-progress.md` | 不等待SaaS verified/OSS ID;不宣称SaaS消费 |
| W13/W14 / 完成 | 本地/隔离联合MQ、D1/D2隔离、断连/不可路由/confirm/DLQ/重启/覆盖率和acceptance已通过;`deploys/cell/nonprod-call-evidence.sh --preflight-only`已实际执行并因当前主机缺Asterisk/tcpdump且非root而fail-closed,未将其记为mixed/real通过 | 本地门禁已解除;物理部署诊断具备相应主机条件后另行执行,不得用本地Mock代替mixed/real诊断 |
当前负责人为本会话Agent,用户明确要求不启动子Agent。实现前基线已完成,见[基线证据](archive/evidence/20260921-mq-only-adjustment-baseline.md);v2方向及AI JCS摘要已获确认,本地v3契约和主要MQ实现已有新增证据。W01/W02/W05/W07/W08/W11/W12的项目内门禁已按§8.2关闭;W04项目内门禁和W13/W14本地/隔离门禁已关闭;外部权威签收及物理部署诊断需具备相应外部条件后另行执行,不属于本地MQ-only目标的完成条件。旧通过数和`docs/archive/evidence/20260920-local-p1-acceptance.md`不覆盖新修订。
**历史本地结果:**修订前W01–W14 的项目内单节点/单 Cell/单租户适用范围曾由本地回归、契约/fixture、隔离故障矩阵和 `docs/archive/evidence/20260920-local-p1-acceptance.md` 签收;本轮受影响项以§8.2当前的完成结论为准:本地MQ-only门禁已完成;外部权威签收及物理诊断另行执行。W15生产切换、真实 SaaS/MQ receipt、真实供应商/ECS、双节点/第二 Cell/双租户、容量/N+1属于第二阶段,不阻塞本轮,也不能被本地证据反写成生产已完成。生产服务未来仍须使用 `deploys/` 的 Debian 13/systemd 包,真实外呼继续遵守逐次确认、capture-first、白名单、09:0020:00 Asia/Shanghai 和每日额度规则。
后续每次完成任务时按负责人和证据规则更新本节、实际运行说明及证据;只有需求变化才修改§4/阶段范围并注明用户确认,不能用更新进度掩盖变更。