Files
ai-customer-service/docs/PRODUCTION_CLOSURE_BOARD_2026-05-11.md

208 lines
11 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.
# ai-customer-service 生产上线 Closure Board
> 生成时间2026-05-11
> 基线 commit`67922c5` (HEAD)
> 小龙:验证 review 报告 → QA 交叉核对 → TechLead 制定方案 → 整合 closure
> 上游产物:
> - `docs/CODE_REVIEW_REPORT_SYSTEMATIC_2026-05-11.md` — 系统性 review 报告
> - `docs/REMEDIATION_TASK_BOARD_2026-05-06.md` — 旧整改任务板
> - `docs/REMEDIATION_PLAN_2026-05-11.md` — TechLead 技术修复方案
---
## 0. 当前门控结论
| 门控 | 结论 | 证据 |
|------|------|------|
| 代码级门禁build/vet/race | **PARTIAL** | `go build` ✅ / `go vet` ✅ / race ✅ 零 DATA RACE`go test ./...` 整体失败postgres/e2e/integration 缺少 DB |
| sub2api 单平台主链 | **PASS WITH RISKS** | 已验证 webhook → dialog → outbox → callback worker 链路;但事务外盒不严格、并发 claim 缺失 |
| newapi 平台能力 | **FAIL** | 入口返回 501但 app.go 允许注册 adapter 并启动 worker |
| 真实预生产 Gate B | **FAIL** | 未复跑 |
| 生产灰度 Gate C | **FAIL** | 未复跑 |
| Dirty worktree | **BLOCKED** | 13 modified + 4 untracked未收口前不可视为可发布基线 |
**综合评级BLOCKED — 不可进入生产上线**
---
## 1. 问题清单(已整合 QA 交叉验证结果)
### P0 — 阻塞级(必须修复后才能进展)
| ID | 问题 | 位置 | 影响 | 责任角色 | 状态 |
|---|---|---|---|---|---|
| P0-1 | Dirty worktree 未收口 | 全仓库 | 评审边界模糊、回滚困难、CI 基线不稳定 | Engineer | 未开始 |
| P0-2 | Makefile test 目标缺少 `-p 1` | `Makefile:2` | 本地执行 `make test` 并发污染共享 DB | Engineer | 未开始 |
| L-1 | **newapi 假接通**app.go 允许注册并启动 worker但 adapter 返回 501 | `app.go:129-130,186-187` | 能力口径失真,安全配置浪费 | Engineer | 未开始 |
### P1 — 必须修复
| ID | 问题 | 位置 | 影响 | 责任角色 | 状态 |
|---|---|---|---|---|---|
| P1-1 | ticket_handler.List 覆盖率 0% | `ticket_handler.go:33` | 列表接口无回归保护 | Engineer | 未开始 |
| P1-2 | newapi_adapter.BuildIngressAck 覆盖率 0% | `newapi_adapter.go:24` | 占位逻辑无验证 | Engineer | 未开始 |
| P1-3 | Authz header 伪造风险未文档化 | `middleware/authz.go` | 内部 API 若直接暴露可被绕过 | TechLead/Engineer | 未开始 |
| P1-4 | RateLimiter GC 压力 | `httpx/limits.go:67` | 高并发下频繁分配切片 | Engineer | 未开始 |
| P1-5 | IPv6 地址在 rate limit key 中被错误截断 | `httpx/limits.go:110-114` | IPv6 客户端共用限流配额 | Engineer | 未开始 |
| L-2 | callback_target 契约漂移builder 写入但 worker 不消费 | `builder.go:31-34` | 数据模型与运行时行为不一致 | TechLead | 未开始 |
| L-3 | outbox 并发 claim 缺失 | `platform_event_store.go:78-86` | 多实例重复投递 | TechLead | 未开始 |
| L-4 | platform webhook 非严格事务外盒 | `platform_webhook_handler.go:86-103` | 业务状态与事件持久化不一致 | TechLead | 未开始 |
| L-5 | E2E 稳定性根因 | `test/e2e/` | 事件顺序异常与 DB 关闭 | QA/Engineer | 未开始 |
### P2 — 建议修复
| ID | 问题 | 位置 | 影响 | 责任角色 | 状态 |
|---|---|---|---|---|---|
| P2-1 | 配置解析失败静默回退 | `config.go:201-255` | 拼写错误的环境变量值被静默忽略 | Engineer | 未开始 |
| P2-2 | callback worker 无连接池限制 | `app.go:172` | 默认连接池可能耗尽 | Engineer | 未开始 |
| P2-3 | 缺少 SQLite/内存测试回退 | `test/e2e`, `test/integration` | 无 PostgreSQL 时无法跑测试 | Engineer | 未开始 |
| P2-4 | worker 缺少优雅关闭等待 | `app.go:164-188` | cancel() 后不等待 worker 真正退出 | Engineer | 未开始 |
---
## 2. 修复任务清单(整合 TechLead 方案 + QA 发现的遗漏项)
### 阶段 A收口与基线稳定P0
| 任务 ID | 描述 | 文件 | 角色 | 验证方式 | 状态 |
|---|---|---|---|---|---|
| A-01 | 批次 1 提交 docs 文件8 modified + 4 untracked | 全仓库 | Engineer | `git status --short` 显示 docs 已清 | 未开始 |
| A-02 | 批次 2 提交代码文件3 modified internal | `internal/` | Engineer | `git status --short` 显示 internal 已清 | 未开始 |
| A-03 | 打 tag `v0.9.1-pre` | 全仓库 | Engineer | `git describe --tags` 确认 | 未开始 |
| A-04 | 修复 Makefile test 目标 | `Makefile:2` | Engineer | `make test` 执行 `-p 1` | 未开始 |
| A-05 | 禁用 newapi 装配与 worker 启动(在实现完成前) | `app.go:129-130,186-187` | Engineer | 读取确认 newapi 分支已关闭 | 未开始 |
### 阶段 BP1 代码修复
| 任务 ID | 描述 | 文件 | 角色 | 验证方式 | 状态 |
|---|---|---|---|---|---|
| B-01 | 补充 ticket_handler.List 测试 | `ticket_handler_test.go` | Engineer | 覆盖率 > 0% | 未开始 |
| B-02 | 补充 newapi_adapter.BuildIngressAck 测试 | `newapi_adapter_test.go` | Engineer | 覆盖率 > 0% | 未开始 |
| B-03 | 新建 SECURITY_BOUNDARY.md + authz 注释 | `docs/SECURITY_BOUNDARY.md`, `authz.go` | Engineer | 文件存在且口径一致 | 未开始 |
| B-04 | RateLimiter 原地过滤优化 | `httpx/limits.go` | Engineer | `go test -race ./internal/platform/httpx/...` 通过 | 未开始 |
| B-05 | IPv6 rate limit key 修复 | `httpx/limits.go` | Engineer | 新增 IPv6 测试通过 | 未开始 |
### 阶段 CP2 代码修复
| 任务 ID | 描述 | 文件 | 角色 | 验证方式 | 状态 |
|---|---|---|---|---|---|
| C-01 | 生产模式配置严格解析 | `config.go` | Engineer | 设置无效值后启动报错 | 未开始 |
| C-02 | callback worker 连接池限制 | `app.go:172` | Engineer | `grep MaxIdleConns` 确认 | 未开始 |
| C-03 | e2e/integration skip 回退 | `test/e2e/`, `test/integration/` | Engineer | 无 PostgreSQL 时测试被 skip | 未开始 |
| C-04 | worker 优雅关闭等待 | `app.go` | Engineer | SIGTERM 后 5s 内正常退出 | 未开始 |
### 阶段 DQA 发现的遗漏项(需 TechLead 先输出架构决策)
| 任务 ID | 描述 | 文件 | 角色 | 验证方式 | 状态 |
|---|---|---|---|---|---|
| D-01 | callback_target 契约漂移:删除字段或让 worker 消费 | `builder.go`, `worker.go` | TechLead 决策 → Engineer 实现 | 代码与文档一致 | 未开始 |
| D-02 | outbox 并发 claim行级锁或单实例约束 | `platform_event_store.go` | TechLead 决策 → Engineer 实现 | 多实例场景下无重复投递 | 未开始 |
| D-03 | platform webhook 事务外盒:统一事务或文档化边界 | `platform_webhook_handler.go` | TechLead 决策 → Engineer 实现 | 事务一致性证据 | 未开始 |
| D-04 | E2E 稳定性:定位事件顺序/数据库关闭根因 | `test/e2e/` | QA 分析 → Engineer 修复 | E2E 多轮复跑稳定 | 未开始 |
---
## 3. 角色责任
| 角色 | 本轮职责 | 交付物 | 完成判据 |
|------|---------|---------|--------|
| **Engineer** | 执行 A/B/C 阶段所有代码修复 | 修改后的源码 + 测试 + 验证记录 | 每项有 `go build` / `go vet` / `go test -race` 通过证据 |
| **TechLead** | 对 D 阶段输出架构决策;审查 Engineer 交付物 | 架构决策记录(针对 D-01/D-02/D-03 | 决策有文档化记录、不引入回退风险 |
| **QA** | 对 A/B/C 做回归验证;对 D-04 做根因分析 | 验证报告 + 漂移检测报告 | 所有 CP 检查点通过 |
| **DevOps** | 待 A/B/C/D 全部完成后,执行上线前检查 | 上线检查清单 | 服务启动、健康检查、监控、回滚路径就绪 |
| **PM** | 更新对外发布口径(如需要) | 口径更新记录 | 无失真口径 |
| **小龙** | 整合、门控、抽样自验、汇报用户 | Closure board + 进度汇报 | 每个阶段有明确通过/阻塞结论 |
---
## 4. 最短闭环执行顺序
```
阶段 A收口与基线
├── A-01 提交 docs
├── A-02 提交代码
├── A-03 打 tag
├── A-04 Makefile 修复
└── A-05 禁用 newapi 假接通
→ QA 回归验证CP-01, CP-02, CP-03
阶段 BP1 代码修复
├── B-01 List 测试
├── B-02 newapi 测试
├── B-03 Authz 文档
├── B-04 RateLimiter 优化
└── B-05 IPv6 修复
→ QA 回归验证CP-04 ~ CP-07
阶段 CP2 代码修复
├── C-01 配置严格解析
├── C-02 连接池限制
├── C-03 测试 skip 回退
└── C-04 优雅关闭
→ QA 回归验证CP-08 ~ CP-10
阶段 D遗漏项架构决策
→ TechLead 输出 D-01/D-02/D-03 决策
→ Engineer 按决策执行
→ D-04 QA 分析后 Engineer 修复
→ QA 回归验证
阶段 E上线前门控
→ DevOps 执行上线前检查
→ 小龙抽样自验
→ 更新本 board 为 APPROVED
```
---
## 5. 明确禁止的错误结论
在以下任务完成前,禁止出现这些说法:
- “多平台接入已经完成”
- “newapi 已支持,只差联调”
- “当前整体生产可上线”
- “预生产 / 灰度已通过”
- “callback_target 已支持多目标回调”
- “平台回调 outbox 已具备多实例生产级可靠性”
- “当前 review 报告已全部完成修复” — 未完成 D 阶段前不得如此声明
---
## 6. 验证检查点CP
| CP ID | 验证命令 | 通过标准 | 所属阶段 |
|---|---|---|---|
| CP-01 | `git status --short` | 零 modified / 零 untracked | A |
| CP-02 | `make test` | 等价于 `go test ./... -count=1 -p 1`,零失败 | A |
| CP-03 | `go test -race ./internal/... -count=1 -p 1` | 24/24 pass零 DATA RACE | A/B/C |
| CP-04 | `go test ./internal/http/handlers/... -coverprofile=/tmp/h.out && go tool cover -func=/tmp/h.out \| grep List` | List 覆盖率 > 0% | B |
| CP-05 | `go test ./internal/platformadapter/... -coverprofile=/tmp/pa.out && go tool cover -func=/tmp/pa.out \| grep BuildIngressAck` | BuildIngressAck 覆盖率 > 0% | B |
| CP-06 | `go test ./internal/platform/httpx/...` | 全部通过,含 IPv6 用例 | B |
| CP-07 | `ls docs/SECURITY_BOUNDARY.md && head -n 20` | 文件存在,首段含 RequireRoles + upstream gateway | B |
| CP-08 | `grep -n "sync.WaitGroup\|workerWg" internal/app/app.go` | 出现 Add/Done/Wait 三处 | C |
| CP-09 | `grep -n "MaxIdleConns" internal/app/app.go` | 出现 MaxIdleConns 与 MaxIdleConnsPerHost | C |
| CP-10 | `go vet ./...` | 零警告 | A/B/C |
---
## 7. 交付风险
| 风险 | 等级 | 说明 | 缓解 |
|------|------|------|------|
| 批量 commit 引入未评审代码 | 🔴 高 | 13 modified 中包含 code 变更 | 分 docs/code 两批次提交,单独 revert |
| RateLimiter 优化引入 panic | 🔴 高 | 原地过滤索引越界 | 改前跑测试覆盖,改后 race 检测 |
| Worker shutdown 死锁 | 🔴 高 | WaitGroup 使用不当 | wg.Add 在 goroutine 前Wait 带超时宕底 |
| 配置严格解析打断现有环境 | 🟡 中 | 生产模式下解析失败启动失败 | 仅对生产模式生效,开发环境保持 fallback |
| IPv6 兼容改变 IPv4 行为 | 🟡 中 | net.SplitHostPort 可能有边界情况差异 | 保留原有 IPv4 测试用例 |
| D 阶段架构决策延迟 | 🟡 中 | TechLead 决策需时间 | 不阻塑 A/B/C 执行 |
---
## 8. 后续跟踪
- 本 board 位于:`/home/long/project/ai-customer-service/docs/PRODUCTION_CLOSURE_BOARD_2026-05-11.md`
- 每完成一个阶段,更新本 board 的状态列
- 每次更新后,小龙执行抽样自验
- 最终目标:所有 CP 检查点通过,所有阶段状态为"已完成",门控结论更新为 APPROVED