# 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 分支已关闭 | 未开始 |

### 阶段 B：P1 代码修复

| 任务 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 测试通过 | 未开始 |

### 阶段 C：P2 代码修复

| 任务 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 内正常退出 | 未开始 |

### 阶段 D：QA 发现的遗漏项（需 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）

阶段 B：P1 代码修复
  ├── B-01 List 测试
  ├── B-02 newapi 测试
  ├── B-03 Authz 文档
  ├── B-04 RateLimiter 优化
  └── B-05 IPv6 修复
       → QA 回归验证（CP-04 ~ CP-07）

阶段 C：P2 代码修复
  ├── 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
