Files
go-sip/docs/evidence/task-control-receipt-fields-20261010.md
T

58 lines
6.2 KiB
Markdown
Raw 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.
# 任务控制回执补齐 — 2026-10-10
## 后续 main 合并与固定环境部署授权
使用者随后批准合入 main、推送并更新部署。合并提交 `60fe840` 已推送;主工作区合同仅从共享仓库快进至已发布 `e750fe4`,没有回退旧合同或覆盖修改。部署前完整检查发现 HTTP 异步日志写入与测试缓冲读取的竞态;新增并发写入/快照/复制隔离测试先失败后通过,`7357eae` 为全部日志测试使用加锁、返回独立快照的捕获器,不改变业务日志或 HTTP 传输;连续 20 轮目标测试、3 轮完整日志 race 及重新完整 `make check` 通过,覆盖率仍 72.6%,发布检查与部署 Python21通过。
本轮固定环境部署采用干净、已推送 main、现有 `nonprod-real`、Debug 开启/Capture 关闭,先关闭 Dispatcher 新准入并核对零活动通话/未确认执行,再调用原部署入口,不 reset、不重启 Asterisk、不生成试拨或额外消息。最终部署来源、两个制品 SHA-256、原生通道、服务进程与稳定性、持久任务/执行占用、恢复目录及日志摘要保存于私密 `.local/task-control-deployment/`;没有把部署计划或本地测试写成现场成功。下文的未合入/未部署表述是功能分支交付时的历史边界,不是此后 main 的状态。
## SaaS 就绪延期的后续授权与限制
首轮现场部署的只读探测确认 MQ 正常,但 SaaS 的 tasks 请求返回 HTTP 200、顶层仅 code/msg 且 code=500,不是任务列表。未修改 SaaS 或放宽 Schema,部署在该门禁处停止,Asterisk 保持原进程。使用者随后明确批准忽略当前 SaaS 问题、继续部署。
因此部署入口增加默认关闭的 `--defer-saas-readiness`,只对已通过独立 MQ 检查且被当前合同拒绝的 SaaS HTTP 200 配置响应显式延期;仍保留字段路径/安全原因与延期标记,运行时 Schema、任务归属、持久准入和独立错误检查不变,业务状态仍为未 ready。最新实际 Dispatcher 错误必须对应 SaaS 配置验证,且服务实际自动重试,不以任意 failed 状态代签。
探测器原先只报告错误类型,补充从 `ValidationFailure.Reason` 提取安全路径/规则错误,不输出其原始正文或普通错误内容;安全诊断先失败后通过。新增默认拒绝、显式延期、错误类型/阶段/TLS限制、真实等待日志判定、MQ 登录/关闭不可跳过、数据不重置测试。部署规则及示例只在 `deploys/production/README.md` 维护。
## 范围与来源
- 使用者确认恢复任务控制成功回执的五个字段,覆盖 start/pause/resume/stop/edit。
- 使用者进一步确认:整条消息未通过 Schema,不能据此丢弃其中有效的任务编号和动作;拒绝回执仅省略自身无效或确实无法取得的字段,不填 null,不推测任务状态。
- 调研前已同步项目与共享合同,基线为项目 `e48ef85`、共享合同 `8e6c332`。
- 共享合同变更 `e750fe4618e6472821ceaa74f6c6227d11f998e3` 已推送到共享仓库 main;消费方实现与合同指针一起提交为 `b1ae50a`,推送到本项目 `check-task-control-receipt-task-id` 分支。
- 未合入本项目 main、未部署、未向真实 SaaS/MQ 发送消息、未拨号、未读取或重置现存业务数据。
## SaaS 开发同步说明
共享仓库 `git@gitee.com:zzmbac/sip-contracts.git` 的 main 已更新至 `e750fe4`。请 SaaS 开发同步读取以下权威入口;本文件不维护另一份字段定义:
- `contracts/schema/mq-task-control-receipt.schema.json`
- `contracts/schema/saas-dispatcher.md` 的任务控制与拒绝反馈规则
- `contracts/schema/examples/mq-control-ack.json`
- `contracts/schema/examples/mq-control-rejected.json`
成功回执恢复任务关联和实际状态;拒绝回执仍保留具体原因,分别按共享字段定义读取有效身份与动作。已存的原回执不会因任务状态后来变化被改写。队列确认不代表 SaaS 应用已处理。
本次共享合同已经发布,但消费方代码尚未合入 main 或部署,不能据此要求当前线上服务已经返回新结构。此说明供使用者直接转达 SaaS;没有独立的 SaaS 通知送达或应用签收证据。
## 实现边界
- 成功与业务拒绝的任务状态在持久回执所在事务内读取,限定 Dispatcher、租户、任务归属。
- 结构拒绝逐字段使用共享 Schema 的字段定义验证;缺少 issued_at、reason 类型错误、无效动作或无效任务编号不会丢失其他有效字段。
- 先按原始 JSON 字段拆分,再分别解码目标字段;其他字段含超出浮点范围的数值也不会抹掉有效任务编号。
- 请求自带的状态不作为事实;查不到归属内任务时省略状态,数据库读取失败则明确返回错误并回滚,不能以省略状态掩盖故障。
- 原回执重发保持原消息身份与原状态;不同动作不能复用同一回执身份。
- 增加收发方向判定:补齐任务编号和动作后的回执仍不能作为入站控制命令执行。
- 未新增业务表、旧库迁移、旧回执兼容或回退路径。
## 验证结果
- 新增 Schema、存储测试先失败后通过;入站方向与实际 MQ 收发断言通过。
- `go test ./contracts ./internal/store ./internal/mq ./internal/dispatcher -count=1` 通过。
- `make check` 通过:格式、Proto/来源、共享合同、Go vet、全部 race 测试、构建、隔离 RabbitMQ 与本机 HTTP/HTTPS/双向 TLS 测试。
- 隔离 RabbitMQ 的 `TestBrokerSharedResultQueueAndNoConfigure` 直接读取队列里的成功和结构拒绝回执,核对任务关联、动作、实际状态、原因及发送前后正文相等;不是仅检查构造函数或本机数据库。
- `make coverage` 通过,业务单元覆盖率 **72.6%**,高于要求的 65%。
- 固定提交 `b1ae50a` 的 `make release-check-local` 通过,source dirty=false,合同固定为 `e750fe4`,本地制品 SHA-256 为 `a87168962e4e6bef828a02a7ce92eafb71c759707547cac8c2aba8978731684f`;production approved=false。
本地隔离验证不代替真实 SaaS 接收或生产签收。本次未验证线上新回执、真实 SIP/AI/OSS、主机部署或呼叫。