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

208 lines
12 KiB
Markdown
Raw Normal View History

# 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/test | **PASS** | `go build` ✅ / `go vet` ✅ / race ✅ 零 DATA RACE / `go test ./... -count=1 -p 1` ✅ 全部通过postgres/e2e/integration skip 属于预期行为) |
2026-05-12 19:02:47 +08:00
| sub2api 单平台主链 | **PASS** | 已验证 webhook → dialog → outbox → callback worker 链路;并发 claim 已实现UPDATE RETURNING + SKIP LOCKED事务外盒已文档化 |
| newapi 平台能力 | **BLOCKED / 已禁用** | 入口返回 501app.go 已禁用 adapter 注册与 worker 启动;待实现完成后重新启用 |
| 真实预生产 Gate B | **FAIL** | 未复跑 |
| 生产灰度 Gate C | **FAIL** | 未复跑 |
| Dirty worktree | **PASS** | 已收口,`git status --short` 零 modified / 零 untracked |
**综合评级PARTIAL — A/B/C 阶段已完成D 阶段待实现,真实预生产/生产灰度未复跑,不可进入生产上线**
---
## 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 已禁用 adapter 注册与 worker 启动 | `app.go:129-130,186-187` | 能力口径失真,安全配置浪费 | Engineer | 已完成 |
### P1 — 必须修复
| ID | 问题 | 位置 | 影响 | 责任角色 | 状态 |
|---|---|---|---|---|---|
| P1-1 | ticket_handler.List 覆盖率 0% → 100% | `ticket_handler.go:33` | 列表接口无回归保护 | Engineer | 已完成 |
| P1-2 | newapi_adapter.BuildIngressAck 覆盖率 0% → 100% | `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.go:31-34` | 数据模型与运行时行为不一致 | TechLead | ADR 已输出,待 Engineer 实现 |
| L-3 | outbox 并发 claim 缺失 | `platform_event_store.go:78-86` | 多实例重复投递 | TechLead | ADR 已输出,待 Engineer 实现 |
| L-4 | platform webhook 非严格事务外盒 | `platform_webhook_handler.go:86-103` | 业务状态与事件持久化不一致 | TechLead | ADR 已输出,待 Engineer 实现 |
| L-5 | E2E 稳定性根因 | `test/e2e/` | 事件顺序异常与 DB 关闭 | QA/Engineer | ADR 已输出分析方向,待 QA 确认后 Engineer 修复 |
### P2 — 建议修复
| ID | 问题 | 位置 | 影响 | 责任角色 | 状态 |
|---|---|---|---|---|---|
| P2-1 | 配置解析失败已在生产模式下严格解析 | `config.go:201-255` | 拼写错误的环境变量值被静默忽略 | Engineer | 已完成 |
| P2-2 | callback worker 已添加连接池限制 | `app.go:172` | 默认连接池可能耗尽 | Engineer | 已完成 |
| P2-3 | 已添加 PostgreSQL skip 回退 | `test/e2e`, `test/integration`, `internal/store/postgres` | 无 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 与 postgres store 测试 skip 回退 | `test/e2e/`, `test/integration/`, `internal/store/postgres` | 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 实现 | 代码与文档一致 | ADR 已输出tech/ADR_QA_ARCHITECTURE_GAPS_2026-05-11.md待 Engineer 实现 |
| D-02 | outbox 并发 claim行级锁或单实例约束 | `platform_event_store.go` | TechLead 决策 → Engineer 实现 | 多实例场景下无重复投递 | ADR 已输出,待 Engineer 实现 |
| D-03 | platform webhook 事务外盒:统一事务或文档化边界 | `platform_webhook_handler.go` | TechLead 决策 → Engineer 实现 | 事务一致性证据 | ADR 已输出,待 Engineer 实现 |
| D-04 | E2E 稳定性:定位事件顺序/数据库关闭根因 | `test/e2e/` | QA 分析 → Engineer 修复 | E2E 多轮复跑稳定 | ADR 已输出分析方向,待 QA 确认后 Engineer 修复 |
---
## 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