38 KiB
G0 开发准备与契约冻结提案 v0.1
1. 状态、权限与使用方式
状态:D01–D10原方向已确认,旧W01契约和W02 Proto已有项目内证据;本轮用户确认SaaS↔Dispatcher全MQ,受影响G0的项目内部分已按计划§1.2/§8.2重新验证。 SaaS与D之间所有请求、响应和事件禁止HTTP,每个D具备全局唯一ID和独立接收Topic/队列;V1 Schema、拓扑和关联已有本地包及RabbitMQ证据,外部发布/签收另计。OSS补充确认:配置存于D配置文件,A向D领取固定15分钟临时上传TOKEN后直传;SaaS不再提供OSS配置/TOKEN,上传完成以recording.uploaded可靠入队为界,不等待SaaS verified或OSS ID,D不转发文件。原HTTP方向被本修订替代,不把旧证据覆盖到新设计。
本项目已创建并验证自己的 Go module、W01 bundle、W02 Proto/stubs、RPC/mTLS 和本地 Mock 测试;未修改父项目权威来源、字段索引或生成产物,未访问真实供应商或创建云资源。文件名保留“提案”以保持链接稳定,不代表还需重复审批已确认方向。
当前结论:可以继续开展 P0 契约补充、隔离 PoC 和项目内实现;不得宣称 G0 通过或把项目内基线冒充外部权威,也不得启动未获授权的真实供应商/云/拨号。架构、首发范围和供应商方向沿用已有决定,不重新选型。
- 外部字段/路径/状态仍以带来源哈希的上游主契约为准。本文件记录已确认的变更方向和验收要求,不能被代码当 Schema 使用。后续由上游维护者修改唯一来源并发布,再导入生成;本文件保留为决策历史,不继续手工维护字段副本。
- 内部机制、字段方向及兼容策略已确认,正式 Proto 的类型/编号/错误映射等仍需定稿与校验。本轮不生成
.proto,也不以临时 JSON 绕过契约;未提供的字段细节、实际预算和技术验证不能视为一并通过。 - 角色简称:S=SaaS/上游契约维护方,M=管理平台维护方,D/A=Dispatcher/Agent 实现方,O=部署/安全/测试负责人。角色不代表已指定人员或已签收;实际姓名、版本、日期和证据须在批准记录补全。
- 保留既有业务语义和8类业务事件,但原7条SaaS HTTP路径与AI GET全部废弃为接入方式;控制/查询/补传/配置授权/上传协调都改为专用MQ请求响应。D↔A仍Unary,A→OSS仍直传,不新增任务mode字段或内部MQ。
- 依据:重写方案、通信设计、验收方案、只读字段索引、组件清单。索引不是独立契约包。
2. 方案确认记录与开发边界
D01–D10 的共同状态为 用户已确认方案/源发布与验证未完成,D07 明确为 Agent 从 Dispatcher 取配置后直连 OSS 上传。确认人及依据为 §1 的本轮用户指令;实现/安全签收责任人和产物版本仍待实际登记。不得再次把已确认方向标成“待用户审批”,也不得因此关闭 GAP。编号保留用于跟踪交付证据,不增加原 88 项运行验收数量。
| 确认项 | 对应缺口/交付内容 | 提交与签收角色 | 最小退出证据 | 未满足时阻塞 |
|---|---|---|---|---|
| D01 | §3 八种事件的 payload、条件约束与同域版本 | S 提交,D/A 联合验证 | 上游发布版本、Schema、每种事件正反例、跨语言校验/摘要适用规则 | 业务结果序列化与消费闭环冻结;不阻塞只读工具 PoC |
| D02 | §4.1 双 AI 模式及旧版本兼容(GAP-08) | S 提交,D/A 签收 | 两分支 Schema、旧完整模式兼容样本、模式资源/行为断言 | 两模式执行配置实现与 P1 双模式签收 |
| D03 | §4.2 SaaS MQ配置/授权、参数、受控引用(GAP-09/10) | S/O 提交,D/A 签收 | 请求响应/原D关联、租户授权/撤销合同、摘要金样、参数到SDK映射PoC | 配置缓存/下发和对应 AI 参数能力承诺 |
| D04 | §5 Unary/最后许可/控制屏障(GAP-04) | D/A 提交,S 确认业务控制语义,O 确认恢复边界 | 已批准协议、状态转移及崩溃矩阵;随后生成 Proto 并做隔离 PoC | 跨 Cell 发起、控制、事实提交和恢复实现冻结 |
| D05 | §5.2 共用证书会话与撤销(GAP-05) | O 提交,D/A 签收 | Endpoint/SAN 清单、角色隔离、重放负例、全组轮换方案及风险签收 | 节点准入和敏感配置交付 |
| D06 | §6.1 P1 静态制品交接(GAP-03 P1) | M/O 提交,D/A 签收 | 制品来源、授权矩阵、唯一写入口、精确加载证据格式 | SIP 静态集成与真实发布 |
| D07 | §6.2 D配置文件/临时TOKEN与A直传(GAP-02 P1) | D/O提交配置与TOKEN合同,D/A联合签收 | D配置来源及失败反例、TOKEN/UploadGrant映射、15分钟/显式向D重申请、A直传/D不转发;recording.uploaded事实可靠入队,不等待SaaS会话/verified/OSS ID | 录音通知闭环;文本归档仍延后 |
| D08 | §6.3 profile、单活恢复、保留(GAP-06/07 P1) | O 提交,D/A 签收 | 明确数值/来源/预算、备份与恢复演练设计、唯一所有权方案 | 对应运行参数冻结与真实验收,不阻塞离线原理 PoC |
| D09 | §7 独立契约包和重建链,补GAP-10全MQ版本 | S/M 提供版本,D/A 负责导入 | 新版D身份/Topic/消息/错误/期限及正反例、只读包/哈希、可重复生成校验;不覆盖旧包 | 独立可交付构建,不得临时读取父目录运行 |
| D10 | §8 依赖和关键 SDK PoC | D/A 提交,O 审核许可/安全 | 精确版本、许可/NOTICE、漏洞处置及对应 PoC 原始记录 | 未验证组件进入正式实现/发布依赖 |
2.1 允许先做、不能先做
允许先做:在另行安排开发时,用成熟库开展 SQLite 事务/恢复、AMQP 确认、ARI/媒体、Schema 工具链、SDK 参数映射和 mTLS 原理 PoC;本地资源必须隔离真实外网,不使用生产凭据。PoC 不依赖猜测的业务字段,也不以临时协议投入业务运行。
不能先做:实现者自行给 MQ 补字段、用宽松 object 校验生产事件、凭本地 CLI/env 选择 AI 模式、先写临时许可协议后让上游兼容、把供应商 SDK 示例成功当作参数/取消/收费行为验收。
可按依赖逐项解锁开发,不要求所有真实供应商测试先完成;但完整 G0 须有 P1 合同和本地关键 PoC 签收,P1 交付仍须独立完成真实验证。真实凭据、外呼、云资源或费用均另行授权。
2.2 P1/P2 配额澄清(既有要求,不是新提案)
P1 必须实施当前真实租户的限额,并在单活 D 的同一 SQLite 事务域汇总两个 Cell 的租户/全局/供应商/Cell/按模式 AI 并发及 CPS;保留租户复合键、有界窗口、未知占用、停止屏障。不能把“只有一个真实租户”解释为免除租户隔离或额度执行。
P2 增加多个同时活跃租户的等权轮询、额度不足跳过、公平恢复、全链路背压和公平性验收;不是首次实现原子配额。P1 可用两个模拟租户测隔离,但不因此开放第二真实租户。
2.3 本轮MQ-only补充(已确认方向,消息细节待冻结)
本轮补充纳入D03/D04/D07/D09/D10及通信设计GAP-10,不新增运行验收编号。完整约束见SaaS↔D契约:每个D全局唯一ID、独立Topic/接收队列、请求/响应固定原D与租户、持久inbox/outbox、错目标/重复身份/重投/乱序/超时/重启恢复;新路由长度须重算,不能照搬旧224字节租户预算。ID生命周期、Topic/绑定、消息枚举/字段/关联、错误/期限未冻结前不实现猜测协议。
P1仍为单节点/单Agent/单Cell/单租户/单活D,下文沿用的早期两Cell/两Agent全量矩阵仅为后续目录,不是本轮门禁。新增D1/D2本地消息fixture只验证定向隔离,不授权多D业务调度、HA或共享配额。旧OpenAPI/只读索引和历史证据原样保存;新MQ生产链不得保留SaaS↔D HTTP;D提供上传TOKEN的职责保留,项目完成边界为recording.uploaded可靠入队,不等待SaaS对象处理。
3. D01:外部事件 Schema 补齐方案(已确认方向)
3.1 上游修改方法
由上游将现有 event_type 分支与专属 payload 约束关联,保留原信封和严格未知字段策略。复用上游已有 Call、Attempt、TranscriptSegment、Recording、CommandResult 等实际组件;组件名称以源发布物为准,不在本项目重复定义。现有字段可复用不等于可以省略事件条件约束。
源发布前须给每种事件补齐必填/可选、类型/枚举、字节限制、可空规则、时间单位和条件组合。下表是已确认的约束及复用方向,不是已发布完整字段表;缺少源字段的地方由 S 明确扩展细节,不能凭表生成未经权威源定义的 JSON。
| 事件 | payload 方向与必须冻结的条件 | 最少反例 |
|---|---|---|
command.result |
复用原命令结果快照;按 command_type/status 限定 execution/call/control revision 及 reason 的适用性;发起前拒绝/超期没有 call_id;executing 不代表已发 SIP,控制 applied 必须有全目标屏障事实 | 无 call 拒绝却造 call_id;仅 accepted 就标控制 applied;CAS 失败返回成功 |
call.status |
复用同 call 下的通话/attempt 状态快照,关联租户、原命令/执行及当前 attempt;线路/Cell/出口来自实际获批路由;阶段时间依据观测而非纯本地计时 | answered 无接通事实;换租户/attempt;用整体版本丢掉独立域事件 |
call.finished |
复用通话终态和 attempt 结论;开始/接通/结束及持续时间保留原单位与未接通规则;允许录音/文字仍在后处理,不覆盖资产域 | 未接通却生成接通时长;通话结束强行把未交接录音设 ready |
transcript.updated |
复用段/轮次/revision/text/final、说话方和真实播放证据;中间稿/最终稿规则与同段 final 同内容幂等、异内容冲突机读化;完整文本不截断 | 迟到中间稿覆盖 final;仅生成 TTS 就标已播放;ASR-only 伪造助手播放 |
transcript.failed |
引用原 call 和受影响文字范围、源定义的失败阶段/原因/恢复性;无 segment 时如何表达整流失败由上游明确;不虚构空 final | 无关联对象;失败后静默删除已持久最终稿;用 recording.failed 代替 |
recording.uploaded |
报告原录音/上传事实、对象位置和文件元信息;不带OSS ID、上传会话、长期凭据或公开URL | 事实缺字段、大小/摘要不符、跨bucket/object绑定;把SaaS处理结果伪装上传事实 |
recording.failed |
复用原录音身份、失败原因与可恢复性;明确上传超时、校验失败和永久丢失的区分;仍保存后续对账/补传所需关联 | 失败产生新 recording_id 逃避幂等;永久丢失报 ready |
contact.opt_out |
复用原租户/task/member/call 关联与拒绝时间/证据引用;最小必要信息;ASR-only 同样具备经批准的判定与通知流程 | 未授权模型判定;跨成员关联;等待录音上传才发 opt-out |
3.2 顺序、重复与测试
- D 对同一稳定事实和内容摘要幂等;同事实 ID 异内容必须冲突。MQ event_id/aggregate 字段继续由 D 的权威事务生成,不能由 Agent 自报最大版本。
- 版本按源规定的聚合实体和状态域处理,独立文字段/录音不被其它域的大版本覆盖;重放使用原事件身份,publish confirm 不等于 SaaS 应用收讫。
- 每种事件至少保留一个合法样本和一个非法样本;另测缺必填、未知字段、错误事件分支、跨租户/归属、空值、边界尺寸、乱序与重复。Schema 能验证形状,数据库归属、控制屏障和 verified 来源还必须运行时验证。
- 上游发布包含上述样本与预期结果的版本;本项目导入原样例运行 Go 校验,不手写一组与上游互不校验的“同名 Schema”。
4. D02/D03:双模式与 AI 配置方案
4.1 两模式与兼容(用户已确认,待 S 发布)
在不可变 AI 版本对象新增 mode,枚举为 asr_only / asr_llm_tts;不放入 call.execute。模式随 agent_version_id 固定,不能通过运行时参数覆盖;当前上游 Schema 尚未更新。
| 情况 | 已确认解释与条件 |
|---|---|
| 已有发布版本未带 mode | 仅在符合原完整 AI Schema 时按 asr_llm_tts 执行;不回写原对象、不注入默认值后重算原摘要。该兼容规则须进发布版本说明 |
| 新发布版本 | 发布入口要求显式 mode;读取旧版本与创建新版本可有不同校验上下文,不能拿兼容读取规则默许新建省略 mode |
asr_llm_tts |
保持原 llm/prompt/tts/asr/conversation 条件和完整对话能力,不因模式引入放宽原必填 |
asr_only |
要求原身份/不可变标记、asr 和适用的 conversation 控制;llm/prompt/tts 必须缺省而非空对象或 null;不得建立 LLM/TTS 会话或占用其专属额度 |
| ASR-only 的 conversation | 仅要求 silence_timeout_ms/max_duration_ms;opening/allow_interrupt/max_turns/sentence_max_chars/max_pending_audio_chunks 禁止提供,避免对无播放/生成场景产生假控制。若业务需识别段数量上限,应另提明确字段,不套用对话轮数 |
| 缺必需能力/未知 mode | 拒绝新准入,不自动切换成另一模式,不静默关闭不支持参数 |
ASR-only 静音以实际输入活动及获批 VAD 策略判定,最长时限从源契约约定的接通时点起算;静音到期按获批结束策略关闭,不自动播放提示。最终文字、录音、文字失败、opt-out 和控制屏障仍适用。opt-out 判定复用独立批准规则;禁止为此暗中开启 LLM,规则缺失时该能力门禁仍阻塞。
模式分支由上游使用源 Schema 机制生成,保持 additionalProperties 严格策略。当前 Schema 无法表达上述 ASR-only,上游发布前不能提交假的完整配置“先跑起来”。
4.2 读取、授权与快照(方向已确认,待 S/O 补齐部署与合同细节)
- D按原任务租户/agent_version_id经MQ请求SaaS不可变配置和授权,SaaS经原D专用Topic响应;校验请求关联、来源/目标与可信租户,不能用响应覆盖归属。无权、找不到、不可用分别表达,精确MQ消息及错误待GAP-10冻结;旧AI GET已废弃,不开发HTTP client或第二个task-config路径。
- 在首次成功准备执行配置时,将
(原值 tenant_key, agent_version_id, 源 Schema 版本, 原内容摘要)与执行绑定并持久化。尚未取得有效配置的排队项不能准入;已有有效绑定的排队/在途项不因“最新版本”改变配置。新任务须显式引用新 agent_version_id。 - 摘要采用上游已有算法及其精确输入边界,导入跨语言金样:键顺序、Unicode、数值、缺省/null/0/false 均须验证;本项目不另选 canonical 算法。若上游未发布明确算法,保持该项阻塞,不把普通 json.Marshal 字节当权威摘要。
- 模式/参数归一化结果作为独立有效快照,关联原摘要和适配器版本,不修改原不可变内容。日志仅留版本、摘要及允许的脱敏参数,不留 prompt/variables/密钥。
- P1 不凭离线缓存授予新的发起许可:D 可缓存不可变内容,但最终许可前须有本次执行的有效授权检查;SaaS 不可达且无上游已批准有效期的授权记录则拒新准入。已确认撤销阻止新许可,已发许可按 §5 有界收敛,在途终止仍走批准控制,不擅自挂断;撤销传播时效等源细节仍需冻结。
- 如需要离线准入,上游须另外发布租户绑定、有效期、撤销传播和缓存可用性规则;未批准前不从本地 TTL 或 ETag 推导业务授权。每次权威检查使用新版获批MQ请求响应,不走HTTP或自造授权接口。
- provider_ref/credential_ref 由 O 管理的受控注册表解析,包含供应商、允许 Endpoint、API/资源版本、凭据种类、租户作用域及出口/能力限制;AI 业务参数不写入该注册表。Agent 不直连 SaaS,也不接收全局凭据库。
- D 向被绑定 Agent 交付本执行最小权限配置/凭据;会话元数据、令牌和敏感值不进日志。配置哈希与原 JSON 校验、有效参数映射和权限检查都成功才准入。并发 SDK 客户端不得共享可变的 per-call 参数。
4.3 参数差异表(方向已确认,待进入上游,不是本地 Schema)
现有 model/prompt/voice/speed、ASR 输入/语言/interim、temperature/max_tokens/timeout_ms 和 conversation 字段必须原义传入 SDK/控制器;不能因 SDK 有默认值就省略映射。已有 speed 范围等不在本文件重定义。
| 待源发布的扩展名 | 已确认语义/单位/缺省方向 | 能力与边界要求 |
|---|---|---|
asr.hotwords |
有界非空词字符串列表;未提供表示不启用用户热词 | S 冻结项数/UTF-8 字节上限和必要的词权重模型;仅适配 SDK 真正支持的表达,不能塞 raw_request |
asr.vad |
enabled(bool)及获批的语音开始/结束静音阈值(ms);false 与未提供不同 | 明确供应商 VAD 或本地控制器职责,不能双重处理互相截断;阈值范围需供应商证据 |
llm.top_p |
number,0 < top_p ≤ 1;未提供按版本化能力表明确解释 | 与 temperature 的同时使用/互斥规则逐供应商批准,不擅自丢弃一个参数 |
tts.volume |
对外统一 0–1 线性音量;显式 0 表示静音,不是默认音量 | 须验证 SDK 原生单位及转换是否保真;只能离散或无等价语义时先提交变更确认,不能先四舍五入上线 |
| 阶段时限 | 分 connect/first_output/idle/total,均整数 ms;与现有 timeout_ms 的优先级须源合同定义 | 网络连接由适配器、流空闲/总时限由控制器共同执行;缺省使用已批准模式 profile 的明确值,不静默沿用 SDK 默认 |
批准参数必须附:必填条件、合法范围、缺省来源、显式零/false 处理、SDK 精确字段/转换、供应商不支持时的拒绝行为和正反例。上表未给齐的供应商范围属于待取证项,不允许本地臆定;metadata 不承担执行参数透传。OpenAI 兼容 SDK 自动重试显式关闭;取消不能触发旧音频重播或二次收费请求。
5. D04/D05:首发 Unary 与最后许可方案
5.1 公共关联和幂等(语义已确认,待正式 Proto 定稿)
保持通信设计 R01–R03/R05/R07–R13 职责,不增加在线发布 R04/R06 空壳。公共字段按已确认方向分层,精确 wire 定义随 Proto 定稿:
| 层 | 字段方向/规则 |
|---|---|
| 传输/诊断 | protocol_version、request_id、trace_id;RPC deadline 只限制一次等待,不是业务授权/通话期限;重试可换 request_id,不能换业务幂等键 |
| 目标/授权 | dispatcher_epoch、agent_id、cell_id、boot_id、session_generation;节点会话凭据仅安全元数据传输;目标均来自 D 的受控绑定 |
| 持久幂等 | operation_id + operation_type + target;内容摘要不可变,同键异内容冲突;业务归属键始终包含原值 tenant_key 与源 execution/call/attempt 标识 |
| 配置/控制 | AI 原版本/摘要、SIP applied revision/hash、task_revision、admission_generation 与 resource_reservation_id;缺失/过期/不匹配拒绝 |
| 事实提交 | fact_id、fact_digest、observed_at、发生时 boot/source_sequence;当前认证会话与历史事实 boot 分离,D 事务持久接收后才确认 |
错误映射沿用通信设计 §7.1。accepted 仅表示持久接收,applied 需真实屏障/加载/控制证据;NOT_FOUND、超时、CANCELLED、Asterisk 当前通道列表为空均不是“从未拨过”证明。
5.2 共用证书下的激活、代次和撤销
- D 从预配置 Endpoint 列表发 R01 受限探测,校验 TLS SAN/SNI、Agent 群组证书及部署期预期目标,再发 R02 绑定 agent/cell/boot。A 只接受独立 Dispatcher 身份;不能执行 A 自报 URL。
- D的全局唯一逻辑ID及专用Topic不等于运行代次,身份保持/恢复及重复拒绝随GAP-10冻结;不能以新epoch清除原消息归属。D 每次取得唯一运行所有权后建立新的 dispatcher_epoch;A 每次启动产生新的 boot_id,旧 boot 的执行许可一律无效,但旧执行/资产占用不清零。generation 在所属 epoch 内单调;epoch 不能按 UUID 大小排序。
- R02 采用持久 activation operation_id:D 先保存 pending 绑定,再由 A 持久接受,D 收到/查询到相同绑定后标 active;回复丢失重查原操作。active 前 A 不获得执行/敏感配置权限。会话令牌用成熟安全随机源,D 仅保存必要校验材料,禁止自研密码协议。
- 激活冲突、旧 epoch、重放、错误 boot、未完成绑定都 fail closed。新 epoch 激活必须在旧 D 已停用/网络隔离/身份撤销可证明后进行;备份恢复不能仅修改一个 generation 数字声称隔离旧进程。
- 共用私钥泄露可能冒充整组 Agent,Endpoint 和会话只能降低误绑定/重放风险,不形成节点级密码学隔离。撤销/轮换针对全组;先关准入、收敛许可并处理在途,再替换证书和会话。不能关闭主机名验证或以风险声明替代演练。
5.3 最后许可的持久顺序(已确认安全边界)
内部阶段为 prepared → permit_granted → dispatching → observed/unknown → terminal;这些不是新增 MQ status。资源预留、文件记录、D 账本和 Asterisk 事实分别承担职责,不宣称跨 SQLite/文件/ARI 原子事务。
- D 事务建立原执行/attempt 的发起意图及完整资源预留、唯一 Agent/Cell 路由和配置绑定,持久后才 R07。A 校验后先持久执行文件,R07 重复只能返回原决定,不能发起通话。
- A 准备发起时,以原 attempt 和唯一 permit 请求 R08。D 在一个短 SQLite 事务内校验当前任务控制、准入代次、会话/健康/版本、授权时段/截止、供应商矩阵及全部额度,再记录唯一 permit_id 和有效期;不跨网络持有 SQLite 写事务。
- 同 permit 操作重试返回原许可/原期限,不延长授权、不另计一份并发。CPS 在最后许可发放时不可重复扣减地记入限速窗口;许可未使用也不在窗口内提前退 CPS。但许可速率不能直接当真实发起速率:不同许可可能因传输/调度延迟集中提交。P1对每个共享资源采用保守窗口,在任意“源CPS统计窗口+最大许可TTL+时钟安全余量”内发放的许可不超过原窗口预算,同时保留原突发上限;不得各Cell自行发满一份。该办法降低可用吞吐,须由O按供应商实际CPS口径批准,并用两Cell延迟/集中提交负例验证,不能擅自缩短窗口换吞吐。并发释放另依实际可证明终态判断,不能将两者混为退款。
- A 在统一的本地发起/控制串行区检查 boot/session、控制/准入代次、实际加载快照和许可期限,持久记录 dispatching 及确定的 ARI 通道关联后,才允许至多一次 originate 提交。R05/R09 关闭准入也进入该串行区;检查与提交之间不能让控制悄悄穿过。
- 串行区不能无限等 ARI:网络等待有界,超时/进程中断即保留 unknown;已经提交或可能提交的请求不以同 ID 再次 originate。ARI 客户端对该操作禁止透明自动重试;确定通道 ID 用于关联对账,不单独构成 exactly-once 证明。
- A 用本机单调时钟对一次 R08 请求建立有效期上界:计时从请求发出起,不从响应收到起;同请求重试不重置起点。D 返回剩余有效期不得超过原许可期限/业务截止。绝对授权截止还须检查批准的时钟偏差安全余量;RPC 晚到、时钟异常、失联或本地代次变化拒绝发起。
- boot 重启不恢复旧单调计时或旧许可;dispatching/unknown 先查本地文件、D 意图和 Asterisk/其它获批证据,不自行重新拨号。prepared 未越过发起点也必须得到 D 对旧许可收敛的明确决定,不能自动续期。
- R11 提交稳定事实:D 将去重、状态/配额和 MQ outbox 放同一事务,commit 后才成功响应。成功包丢失 A 重报原 fact;A 不得因缺确认删除唯一事实,也不得换 fact_id 制造新结果。
这套顺序选择“宁可保留不确定占用,也不重拨”,不是承诺网络分区下无需对账的 exactly-once。许可控制的本地界线是首次提交 ARI,不是对 Asterisk 发出线上 INVITE 的跨进程原子提交;已经在途的 ARI 请求必须计入未知占用和控制屏障,不能仅等 TTL 就报告无发起可能。许可过期只禁止新的 ARI 提交,不证明过去没有提交,不能自动释放未知占用。CPS还须观测 Asterisk 实际发起时间;若其排队能使供应商实际口径超额,须先用适用的 Asterisk 原生限速/准入能力及成熟 SDK 验证解决,否则阻塞 D04,不以许可窗口通过冒充实际CPS通过。
5.4 pause/stop/维护屏障
D 先 CAS 持久化控制及关闭新许可,再向所有相关 Cell 下发同一控制操作和目标 revision。A 持久关闭门闩、使未使用旧许可失效,报告已提交/可能提交/振铃/接通/未知占用。串行区内抢先提交的发起属于屏障前执行,必须计入控制范围,不能漏掉。
- pause/drain:不新增发起,屏障前已拨出/振铃/接通沿原生命周期继续;暂停后的恢复须新的合法控制/授权,不复活旧许可。
- stop/drain:同样阻止新发起,已提交执行按源 drain 规则结束;stopped 不可恢复。stop/hangup 必须逐项执行获授权挂断并核对终态,超时不当成功。
- 维护/SIP 静态改配:关闭受影响资源,旧许可失效且未知占用完成对账,按维护要求排空后才加载。不能拿任务 pause 的完成条件代替配置安全排空。
- applied 只有在所有必需目标的对应语义均有证据时成立。失联 A/仍可能在途的 ARI 请求保持 applying/reconciling;D 自己等到 TTL 不替代 A 的收敛证据。
5.5 恢复/故障矩阵与内部 PoC 初始 profile
| 注入位置 | 必须保留与允许的动作 | 禁止 |
|---|---|---|
| D commit 前后崩溃、R07 回复丢失 | 原执行/预留/操作恢复并查询原结果 | 改 execution_id 再投;重新发一份额度 |
| R08 已提交但回包丢失 | 查/重取原许可和原期限;过期进入收敛 | 新 permit 无限延寿;先退并发再重拨 |
| A 写 dispatching 后、ARI 提交前后崩溃 | 按原通道/意图对账;不能证明则 unknown | “通道没找到”即重发 originate |
| 控制与最终检查/ARI 提交交错 | 同串行区判定先后,D 等所有目标屏障事实 | 仅 CAS 成功就发 applied |
| A 重启/D epoch 更新/时钟跳变 | 废弃旧发起权限,保留旧通话/资产归属 | 新 boot 清空占用;旧事实按旧 boot 丢弃 |
| R11 commit 后回复丢失 | 重报同 fact 同摘要,返回原持久结果 | 二次 outbox 事件、跨状态域版本覆盖 |
| SQLite 备份恢复、旧 D 仍可能存在 | 隔离旧 D 后受控激活;无证据停止新准入 | 两份 SQLite 并行发许可;NFS 共享文件充当 HA |
以下为用户已确认、尚未实测的内部隔离 PoC 初始值,不覆盖验收 §9 的上游基线或真实供应商预算:最终许可 TTL 上限 1000ms、R08 单次 deadline 500ms;一般查询/事实提交单次 deadline 3s;接收控制单次 deadline 1s(不是 applied 完成时限)。重试不得越原业务/许可截止,退避继承已批准 profile;不能证明 TTL/网络/时钟余量时拒绝发起。
每条内部 Unary 编码后上限 512KiB,许可/控制请求上限 64KiB;不传音频/录音字节,不无限批量事实。外部MQ仍按256KiB源上限及新版分消息约束验证,旧HTTP JSON 64KiB仅保留为历史来源,不用于恢复SaaS↔D HTTP;内部较大上限不能绕过外部上限;超限拒绝/告警而非截断。协议初版仅支持同一批准版本和显式能力集,未知枚举/关键字段拒绝准入;后续兼容范围须有升级测试再扩展,不承诺自动滚动升级。
6. D06–D08:静态交接、录音与运行恢复
6.1 P1 静态制品交接(流程已确认,待正式制品合同)
M 是唯一编辑/审批面;制品外层记录 source_release、source_digest、approval_reference、精确 cell/trunk 目标、源 Publication 的 revision/config_sha256 和协议兼容范围。SIP 配置体复用源结构,外层包装不得冒充已有 API 已支持的新字段。
交接顺序:M 批准 → O 核验来源和两个 Cell×至少三供应商授权矩阵 → D 持久关闭资源准入/R05 收敛 → O 经唯一受控入口原子部署/加载 → A/R01 报实际快照与脱敏 Asterisk 加载证据 → D 核验后逐资源开放。审批记录必须证明旧直写入口已关闭。
加载证据至少关联制品版本/哈希、目标、Agent boot、Asterisk 镜像/配置版本、实际加载时间及 SDK/CLI 观测摘要;文件写入成功或 reload 返回 0 不足以证明加载。失败保留关闭准入,人工恢复旧制品同样重新核验;不自动拨电话验证,也不自动启用未获白名单授权的另一出口。
6.2 P1 录音配置与 Agent 直连 OSS 上传(用户已确认)
上传数据面固定为Agent→OSS;OSS配置唯一来源为D配置文件,临时上传TOKEN由D通过Unary交给A。 SaaS不下发OSS配置/TOKEN;本项目不申请业务会话,不等待complete/verified或OSS ID。D不接收/缓存/转发文件,不替A上传,A不持长期凭据。
D/O须核验配置文件读取、服务地址/bucket/对象规则、受控凭据配置或引用、SDK签发及TOKEN与现有UploadGrant映射;未给定的精确字段不能猜。配置缺失/无效明确失败,不向SaaS取配置、不用A本地bucket/长期AK兜底;样例/日志不存实际密钥或完整TOKEN。D仅交付原执行/对象所需TOKEN、目标/方法、headers与期限。recording.uploaded仅报告原call/recording/upload标识、对象位置、格式、时长、完整文件大小及SHA-256;MQ中不传D配置文件、长期凭据、TOKEN或签名URL。SaaS后续处理不属于本项目,不以其消费或对象登记作为完成前置。
- A封口并持久元信息,经R12向D领取固定15分钟的临时TOKEN,D按自身配置复用SDK提供。同一请求重放返回原授权及原到期时间,不能借重试自动续期;不向SaaS申请会话或资产登记。
- A 直接把文件内容上传至指定 OSS,不把文件发给 D,也不通过内部 gRPC 传录音字节。D 失联时已有仍有效授权可继续上传;TOKEN过期或缺失则保留原文件,D恢复后由A显式向D重新申请,不自动续期,不向SaaS申请TOKEN,不改用A本地长期密钥。
- A成功PUT后通过R13报告原上传事实;D同事务保存事实及recording.uploaded outbox。D/MQ不可达时保留源文件和原通知恢复记录,不重新PUT,不新建资产,不重拨。
- D以persistent消息、指定durable队列/绑定、mandatory无return和publisher confirm成功确认交付;未可靠入队不返回completed,仅写本地outbox不算完成。不新增VERIFYING,不返回OSS ID,也不等待SaaS回复。预签名URL不具备OSS原生强制一次性语义,每次授权尝试只执行一次PUT由Agent状态机保证。
本地删除条件继承验收 profile:原上传事实已持久保存、recording.uploaded已可靠入队、无恢复任务且满足保留;MQ confirm 不等于 SaaS 应用收讫,不额外等待不存在的应用 ACK。文本 OSS 归档继续受 GAP-02 延后约束,实时 transcript.updated/opt-out 不等待 OSS。
6.3 运行 profile 与单活恢复登记
审批登记须包含:profile_id/版本/源哈希/覆盖理由、1 D+2 A 的精确资源绑定、租户/供应商/Cell/模式额度、队列与待发起窗口、心跳/许可/时钟余量、磁盘/文件阈值、保留/备份、真实测试号码/线路/费用上限、维护窗口、RPO/RTO 和签收人。
沿用验收 §9/§9.1 的适用基线(例如心跳 2s、租约 10s、失联停新发起、磁盘 70%告警/80%停新准入/60%恢复),拓扑差异只用有批准记录的覆盖;不把 DEV 全局 6 或后续 1000 路当 P1 真实授权。未取得实际预算/供应商上限时填写 blocked,不填虚构数字。
单活采用本机部署监督+成熟 OS 排他锁防止同机双启动,SQLite 保持本地盘,在线备份走成熟驱动/SQLite 支持的备份能力,包含 WAL 一致性;这些不构成跨机隔离。人工迁移/恢复先证明旧 D 停止与发起权限隔离,再恢复库、激活新 epoch、核对两 A 的文件/Asterisk/未决资产和额度,最后开准入。卷丢失时按实际事实损失签收,永久未上传录音不得承诺 RPO=0。
7. D09:独立只读契约包与可重复生成方案
后续进入开发时,在本项目导入一个只读版本目录 contracts/upstream/<release>/(此目录本轮未创建),完整包含需要的 Schema/OpenAPI/示例及其引用闭包;禁止外部 $ref 在构建时联网或越出包目录。本项目自己的批准 Proto 来源单独维护并记录版本,不手写外部业务结构替代源类型。
清单记录:发布 ID、上游仓库/不可变 commit 或发布地址、文件路径与 SHA-256、批准引用、生成器版本/校验参数、源 Schema 方言和许可证。发布方的来源校验与内容哈希都要验证;自报哈希不等于可信来源。
已确认的后续流水线(本轮未执行):
- 验证来源和全文件哈希,拒绝缺失/额外未声明/路径越界/引用不闭合的文件;导入过程不能覆盖旧已发布版本。
- 用锁定的成熟生成器从源生成 Go 类型和只读字段索引,并使用锁定的成熟 Schema 校验器显式执行运行时校验;类型生成不等于校验。生成器不支持的关键约束应报阻塞,不手改生成代码绕过。
- 对上游合法/非法样例执行一致性测试;同输入重建结果必须确定,生成结果差异须在 CI 失败。源升级经过兼容测试而非静默替换。
- 将项目复制到无父目录、无外部网络依赖的隔离工作区,用已批准依赖缓存完成生成/构建/测试;普通运行不读取父文档目录。维护者导入可以显式取上游发布物,普通构建不可以偷偷读父目录。
- 字段索引同步由同一源版本生成,本文件提案不进入生成输入。本轮保留现有索引,避免手工改成第二套 Schema。
8. D10:最小 PoC 顺序与证据
复用组件清单现有候选,不新增协议栈。本轮不声称已下载或验证任一精确版本。每个采用项记录 module/tag/commit、源码/依赖哈希、Go 1.27.1 构建、许可证/NOTICE、传递依赖/漏洞处置和适用协议版本。
| 顺序/已有验收域 | 本地最小检查与通过条件 | 失败处理 |
|---|---|---|
| 1.Schema/生成工具 | 真实上游 3.1/2020-12 特性、严格对象、条件分支、缺省/0/false、引用闭包和中文原值在 Go 中与金样一致;不只编译生成类型 | 换成熟生成/校验工具或修上游;不放宽 Schema |
| 2.SQLite+Agent 文件/恢复 | 单 Cell 额度事务、inbox/outbox crash 点、WAL 备份还原;文件使用成熟 FS 原语验证落盘/原子替换/损坏隔离和重启重放 | 驱动不满足先替代;不改成内存字典或 Agent 业务数据库;跨 Cell 额度延期第二阶段 |
| 3.Unary/身份/许可 | 成熟 gRPC/mTLS、SAN 错配/重放、R02 丢包、§5 崩溃矩阵、RPC 超时不重拨、同机第二 D 拒绝启动 | D04/D05方案已确认;后续开发时定稿/生成Proto并验证,未通过不得签收 |
| 4.ARI/RTP/录音 | 本地固定 digest Asterisk、确定通道关联、ExternalMedia、PCMA/PCM、事件断连与取消清理;故障下注入 originate 响应丢失不得二次提交 | 先换成熟 SDK/修上游;不能手写 ARI/SIP/RTP/G.711 替代 |
| 5.ASR/LLM/TTS 参数 | 百炼/火山 ASR、OpenAI 兼容 LLM、火山 TTS 的实际锁定 SDK 对照 §4 记录传参、0/false、取消和重试;Mock 检查边界行为 | SDK 缺能力不走 metadata/raw_request;报阻塞或批准替代 SDK |
| 6.MQ/录音交接 | 隔离broker验证D1/D2定向Topic与租户隔离、错目标/重复ID、不可路由/confirm丢失、请求响应乱序/重启恢复;D从配置文件提供固定15分钟临时TOKEN并覆盖配置缺失/无效反例;AI/控制/查询经MQ,A直传OSS后D可靠发布recording.uploaded;证明无SaaS↔D HTTP或SaaS下发OSS配置/TOKEN | 本地通过不替代真实 MQ/OSS/云身份验证 |
每份证据记录环境/mock-mixed-real、版本、输入边界、预期/实际、脱敏日志、失败注入点和残余风险;失败/blocked 不删样本。SDK 本地 Mock 只验证客户端映射,不证明供应商服务端支持、费用或双模式真实可用。真实 SIP/AI/OSS 必须另行授权并分别验收。
9. 确认结果、后续交付与完成判定
D01–D10 的建议已按 §1 用户指令确认,D07 明确为 Agent 取 Dispatcher 配置后直连 OSS 上传。不再重复要求用户审批相同方向。后续优先完成 D02 的上游双模式 Schema 和 D04/D05 的正式 Proto/会话合同,同时由 S 补 D01/D03、M/O 补静态交接、上传会话细节和实际 profile;选型 PoC 与只读包工具验证可以并行准备。
逐项跟踪格式:确认项 → 用户已确认语义/例外 → 待交付字段/产物 → 上游发布版本/哈希或内部协议版本 → 实施/签收责任人及日期 → PoC/验收证据 → 未决风险。缺产物/责任人/证据时标为“方案已确认,交付/验证未完成”,不能退回“待用户审批”或冒充“已冻结/通过”;对未给出的字段细节、真实额度/费用以及偏离已确认方案的变更另行确认。
**本轮完成标准:**确认状态、Agent→OSS直传及相关验收要求在文档间一致,父项目权威源未改;不是十项门禁全部通过。后续获得修改上游/创建代码的执行授权再导入发布物、生成 Proto/类型和执行隔离 PoC;本轮不扩大到这些操作。真实云、供应商消费和拨号仍另获明确授权,P1/P2/后续功能分别验收。