# 任务计划可选字段:本地合同适配与验证(2026-10-09) ## 基线与唯一差异 - 起始主仓库 `main`:`6e028d4`,更新前工作区干净,已执行远程同步,未发生主仓库快进。 - 验证时主仓库另有独立提交 `ef1c625`,仅调整 `AGENTS.md` 和独立 sip-call 部署证据,与本次修改文件无交叠;该提交及文件原样保留,本次未创建提交。 - 共享合同:`b502ad2` → `adc49ace34a0cdfd21c4de5a20dc6dfc1ab9b9df`;`make contracts-update` 成功。 - 唯一变化:`http-task-detail.schema.json` 的任务计划不再要求提供 `ends_at`、`excluded_dates`。属性类型、其他必填项、任务/线路时段、授权、并发及消息规则均未改变。 - 定义仍仅由 [`contracts/schema/`](../../contracts/schema/README.md) 提供,本项目没有修改共享仓库文件或添加平行 Schema。 - 用户追加批准:**仅暂存 `contracts/schema` 指针**,以满足现有合同验收要求;其他改动未暂存,不提交、不推送。此前未暂存指针时 `make check` 明确失败,未更改或绕过检查规则。 ## 差异对应处理 | 变更或影响 | 处理结果与依据 | | --- | --- | | 两个字段分别省略或同时省略 | `contracts/task_schedule_schema_test.go` 分别核验 ASR-only 与完整 AI 任务;显式 null 结束时间和空排除日期继续有效。 | | HTTP 读取与冻结快照 | `TestReadTaskSnapshot` 覆盖两种任务的四种字段组合,核验原始响应原样保存,不补结束时间或排除日期。 | | 实际选线与通话期限 | `TestSelectTrunkOptionalTaskSchedule` 核验省略字段后的准入与期限;开始时间、每周窗口、显式结束时间及排除日期仍生效,SIP 加载和线路并发仍约束执行。 | | 非法输入与边界 | 缺失其他必填项、非法结束时间、错误日期、重复日期、错误类型和未知字段仍拒绝;结束早于开始、到达结束边界等由现有调度测试核验。 | | 隔离完整链路 | `TestDispatcherCommandStartsWithIsolatedMQHTTPAndAgent` 的模拟 SaaS 任务同时省略两个字段,经配置读取、持久化、RabbitMQ、双向 TLS Agent 和模拟 HTTPS 对象上传实际取得最终结果。 | | 业务实现 | `internal/callwindow/policy.go` 已将未提供结束时间视为无额外结束限制、未提供排除日期视为无排除日期;读取层原样保留计划,Dispatcher 已调用该逻辑。无需修改运行逻辑,不新增兼容、兜底、默认值或数据迁移。 | | 文档 | `docs/contracts.md` 增加本次适配入口;既有日期证据保留历史事实,不把旧合同路径或旧覆盖率当作本次依据。 | ## 测试先失败再通过 新增 `TestTaskScheduleOptionalFieldsSchema` 后,在独立临时测试目录中仅用旧提交的任务 Schema 执行测试:ASR-only 与完整 AI 的“省略结束时间”“省略排除日期”“同时省略”六项均因缺失必填属性失败。 同一临时测试目录换成已更新的任务 Schema 后,该测试全部通过。真实工作区的共享合同未回退、未被临时改写;临时目录仅用于负例验证,完成后删除,不构成运行时备用合同。 ## 本地验证结果 | 检查 | 结果 | | --- | --- | | `go test ./contracts ./internal/configread ./internal/callwindow ./internal/dispatcher -count=1` | PASS | | `make check` | PASS:格式、Proto 生成及 7 文件清单、合同来源/离线引用/历史来源、`go mod verify`、`go vet ./...`、`go test -race ./...`、构建及实际隔离 MQ 测试。 | | `make coverage` | PASS:排除生成文件后的业务语句覆盖率 **70.6%**,达到 ≥65%。 | | `make release-check-local` | PASS:当前合同固定提交与本地制品/打包检查;`source_dirty=true`、`production_approval=false`。 | 本次实际运行并通过的隔离 MQ 测试: - `TestBrokerSharedResultQueueAndNoConfigure` - `TestRuntimeIsolatedControlBacklogExecuteAndSharedResult` - `TestDispatcherCommandStartsWithIsolatedMQHTTPAndAgent` - `TestSaaSMockPublishesOneCommandOnProvisionedRabbitMQ` - `TestSaaSMockAwaitsExactResultBeforeStoppingCapture` 本地发布检查报告制品 SHA-256:`025018369e0f2e3d50aecae3edd35e9dcf21e7f601e8200c1acdfefb50b1590b`。此检查制品和临时打包产物由检查脚本删除,未安装或部署。 ## A01–A12 本次对照 | 项目 | 受影响范围与本次依据 | | --- | --- | | A01 合同一致性 | 直接影响;新 Schema 正反例及 `TestCurrentContractExamples` 通过,固定共享提交,无重复定义。 | | A02 代次名称 | 不适用新增变更:仅消费字段可选性变化,未引入新运行入口、协议代次或旧路径。 | | A03 固定通信名称 | 无业务变更;`TestCurrentContractTopology` 与实际隔离 MQ 回归通过。 | | A04 来源与生成一致性 | 直接影响合同提交;`make check` 的共享来源、引用及 Proto 检查通过。 | | A05 配置读取与失效 | 直接影响;`TestReadTaskSnapshot` 的八种组合通过;`TestReadTaskDoesNotReuseConfigAfterHTTPFailure` 随完整回归通过,无旧快照回退。 | | A06 队列归属与路由 | 无业务变更;实际 `TestBrokerSharedResultQueueAndNoConfigure` 通过,未赋予 Dispatcher 建队列权限。 | | A07 控制与发现竞态 | 无业务变更;`TestControlStopCannotResumeOrDispatchPending`、`TestSIPNotificationPersistsBarrierAndWaitsForLoadedFullSnapshot` 等随完整回归通过。 | | A08 执行与 AI | 直接影响任务计划;新选线测试与省略字段的隔离完整链路通过。AI 连接、参数及对话行为未改。 | | A09 结果与录音 | 无业务变更;省略字段的完整链路取得最终结果;`TestFinalResultNeedsConfirmedEndAndRemainsExactlyOne` 等随完整回归通过。 | | A10 数据保护与恢复 | 无业务变更;`TestRecordingRecoveryUnknownPUTNeverRetriesAfterRestart` 等随完整回归通过;未改业务表、恢复文件或未知占用。 | | A11 测试与构建 | 直接影响;新合同测试先失败再通过;完整本地验收、70.6% 覆盖率、发布检查通过。 | | A12 交付边界 | 仅本地改动与验证,未部署或调用真实业务服务,未签收生产。 | ## K01–K16 本次对照 | 项目 | 受影响范围与本次依据 | | --- | --- | | K01 队列拓扑与所有权 | 无业务变更;实际隔离 MQ 与 `TestCurrentContractTopology` 通过。 | | K02 归属与事件身份 | 无业务变更;`TestCurrentContractExamples`、原身份持久执行测试随完整回归通过。 | | K03 分页发现 | 无业务变更;`TestReadAllTasksContinuesAfterShortPageUntilEmptyPage` 随完整回归通过。 | | K04 停止不可恢复 | 无业务变更;`TestControlStopCannotResumeOrDispatchPending` 随完整回归通过。 | | K05 暂停控制 | 无业务变更;`TestControlPauseDefaultHangupAckAfterAgentDispatch` 随完整回归通过。 | | K06 派发与通话事实 | 无业务变更;`TestExecuteWaitsForRulesThenDispatchesOriginalIdentity` 随完整回归通过;隔离完整链路取得原事件最终结果。 | | K07 SIP 加载屏障 | 无业务变更;新选线测试确认未加载时不放行;SIP 通知持久屏障测试随完整回归通过。 | | K08 AI 授权绑定 | 无业务变更;`TestBindCurrentRejectsUnauthorizedProviderBeforeCall` 随完整回归通过,未发真实 AI 请求。 | | K09 关键词结束 | 无业务变更;`TestKeywordHangupOnlyFinalUserLiteralAndOrderedGroups` 随完整回归通过。 | | K10 上传恢复 | 无业务变更;`TestRecordingRecoveryExpiresAfterExactly48HoursWithoutResult` 随完整回归通过;未更改恢复窗口。 | | K11 SIP 事实 | 无业务变更;`TestFinalResultPayloadRejectsMissingOrInventedCallFacts` 随完整回归通过,未新增或伪造真实 SIP 证据。 | | K12 呼出规则 | 直接影响;`TestSelectTrunkOptionalTaskSchedule` 核验省略字段、开始/结束边界、每周时段、排除日期及并发/加载门槛;缺省不等于绕过其他规则。 | | K13 单号拒绝 | 无业务变更;`TestExecuteRejectsInvalidCalleeWithoutStoppingTask` 随完整回归通过。 | | K14 通话结果与未知执行 | 无业务变更;`TestFinalResultPayloadNoAnswerHasNoFabricatedTranscriptOrAsset` 随完整回归通过,未知占用未清除。 | | K15 录音生成失败 | 无业务变更;`TestRecordingDeliveryCaptureFailureDescribesFailureWithoutInventingUpload` 随完整回归通过。 | | K16 双文件保存失败 | 无业务变更;`TestRecordingDeliveryRecoveryDiskFailureNeverReportsUploaded` 随完整回归通过。 | ## 未验证范围 没有真实 SaaS/management 的配置签收、真实运营商 SIP 接通、Asterisk 实际加载、真实 ASR/LLM/TTS、OSS、主机重启、容量或生产验收。本次 RabbitMQ、HTTP/HTTPS、双向 TLS、上传与通话均为本机隔离测试,不授权或证明任何真实拨号。 未操作测试机,未读取私有配置,未清理或迁移既有数据,未修改其他项目。共享仓库本次仅同步读取,未替 SaaS 开发人员确认应用已同步或已完成联调。