# F09 P1 本地 Mock 验收(任务发现 v0.2) 仅验收单节点、单 Dispatcher、单 Agent、单 Cell、单租户的本地隔离 Mock。任务发现采用 `docs/thirds/v0.2.md` §2.5;其余 SaaS 项目内协议仍为 v0.1。未修改 `contracts/upstream/v1/`,旧分页发现不运行、不回退。此处的通过不代表 SaaS/management、真实 OSS/SIP、Asterisk 媒体、云部署或生产切换通过。 ## 计划 §5 本轮适用矩阵 | 适用场景 | 本地验证结果 | | --- | --- | | 发现版本与恢复 | 单次完整响应最多 256 项、无分页及队列地址/key;空变更保持请求水位,`removed` 退役,410 `cursor_expired` 重新取得全量并原子持久化;超限/未知字段拒绝,不截断、不启用旧分页兼容。合同正反例、来源及 SHA-256、Mock SaaS 流程见 [`f03-local-task-discovery-v0.2.md`](f03-local-task-discovery-v0.2.md),`internal/configread/discovery_v02_test.go`、`internal/store/local_v01_discovery_test.go`。 | | 只读配置、归属与额度 | D 身份/租户/任务及版本、SIP 快照已加载校验,HTTP 错误与缓存过期关闭新准入;按归属 D 及 tenant_id 取得共享额度,缺失/0/降额/未知占用不擅自发额或释放。`internal/dispatcher/local_config_read_test.go`、`local_v01_config_test.go`、`local_origination_quota_test.go` 及 F02 证据。 | | 最后拨号判断 | 任务×已选线路的上海时区窗口、任务排除日期、号码白名单、有效期及较小时限在接纳和发起前检查;不等下一窗口、不换线重拨;mock 授权仅 Mock Agent 使用,mixed/real 不启用新授权。见 [`f04-local-dial-policy-v0.1.md`](f04-local-dial-policy-v0.1.md)、`internal/dispatcher/dial_policy_test.go`、`local_v01_test.go`。 | | 队列暂停、恢复及停止 | RabbitMQ 隔离测试中 100 条积压经 pause 保留、resume 从原队列继续;stop 静默 ACK 另 100 条未接纳命令,不产生逐条结果。两条已发起的 Mock 执行在 stop 前已将 Agent 归属与一次性拨号决定**同一 SQLite 事务**持久化,故 stop 对两条都发 hangup;已在途通话仍各自产生最终结果、释放额度,不额外拨号。见 `internal/mq/amqp_v3_integration_test.go`、`internal/dispatcher/task_queue_v3_stop_active_test.go`、`task_control_v3_test.go`。此前测试发现 V3 缺失持久 Agent 归属,导致两条在途执行被 stop 控制漏掉;先有失败测试,再修复并复测。 | | 队列所有权、队列满、SQLite 写入失败 | Dispatcher 的受限 RabbitMQ 账号无 `configure` 权限,仅消费 SaaS 预建任务/控制队列;队列缺失不自行声明。SaaS Mock 建 `x-max-length=1`、`reject-publish` 队列,第二条 persistent 命令获拒绝,原第一条保留并由 D 消费,未入队的消息不虚称 D 自动补收。SQLite 写入故障以隔离测试触发器模拟满盘类写入错误:准入事务无残留任务/额度、错误非永久命令错误,恢复后沿原命令身份接纳;MQ 瞬态 handler 错误 NACK/requeue 原消息,恢复后 ACK。**未物理填满磁盘**。见 `internal/mq/amqp_v3_queue_full_integration_test.go`、`amqp_v3_integration_test.go`、`internal/dispatcher/local_sqlite_full_test.go`。 | | 结果、上传及故障恢复 | 确认终态后独立释放额度;`uploaded`/`unavailable`/`not_created` 只出一份最终 `call.result`。明确录音失败事实、未知 PUT、15 分钟期限、断回执/重启、MQ confirm 丢失和超长正文均保留原身份,不重拨或重新 PUT;confirm 不是 SaaS 应用签收。见 [`f08-local-final-result-v0.1.md`](f08-local-final-result-v0.1.md) 与本轮受限 RabbitMQ 集成。默认 Mock 无真实录音,录音分支由严格绑定的合成事实注入。 | ## 执行与覆盖率 - `./scripts/acceptance-local.sh`:通过;内含格式、Proto/合同及 hash 校验、`go mod verify`、`go test -race ./... -count=1`、`go vet ./...`、构建和无 `configure` 权限的本地 RabbitMQ 集成测试。 - `go test -cover -count=1`:本轮 P1 业务包 `agent` 71.1%、`callwindow` 84.4%、`configread` 74.9%、`contract` 74.0%、`dispatcher` 70.4%、`rpc` 69.9%、`store` 67.2%、`tenant` 85.4%。`mq` 必须带 RabbitMQ integration tag 执行,`./scripts/mq-integration-local.sh` 中为 66.4%。均达到用户确认的**本轮 P1 业务模块 ≥65%**口径。 - 独立列明未达线包:`cmd/sip-go-agent` 29.6%、历史 `internal/callruntime` 61.7%;MQ 普通测试不带 integration tag 时仅 1.7%。这些数字**不计入本轮 P1 业务模块门槛**,不宣称 CLI 或全仓库达到 65%,后续补测仍是技术债。 ## 未验证及门禁 真实 SaaS/management 合同、ECS/OSS/SIP 供应商、Asterisk 媒体、第二节点/Cell/租户、容量及切换均未验证或未获授权。F06 只核对本地制品、合同/队列版本和 fail-closed 发布准备;不得因上述本地 Mock 结果启动真实部署、拨号或生产切换。