Files
sub2api-cn-relay-manager/docs/EXECUTION_BOARD.md
2026-05-21 09:16:45 +08:00

149 lines
13 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.
# sub2api-cn-relay-manager 执行板
日期2026-05-20
当前 GateBLOCKED代码门禁已通过`scripts/import_remote43_provider.sh` 的 managed-probe / 本机 `PACK_PATH` 修复已关闭历史 `401 Unauthorized` 假阴性;但 2026-05-21 latest-head fresh host completion smoke 仍未通过DeepSeek `artifacts/real-host-acceptance/20260521_064403_remote43_deepseek_key_import` 与 MiniMax `artifacts/real-host-acceptance/20260521_064454_remote43_minimax_key_import` 都已达到 `subscription_ready``/v1/models`=200`/v1/chat/completions` 仍返回 502。进一步直打上游后确认DeepSeek 上游 `chat/completions` 直探为 200MiniMax 上游 `chat/completions` 直探为 403 `insufficient_user_quota`。因此当前不允许宣称“完全验收/APPROVED”
目标:实现独立控制面、零侵入宿主、可导入国产模型并具备可运维的导入/回滚/访问闭环。
## 2026-05-21 校准说明(最新真相)
- 401 假阴性已关闭:`artifacts/real-host-acceptance/20260521_064403_remote43_deepseek_key_import``20260521_064454_remote43_minimax_key_import``09-models.headers.txt` 都是 `HTTP 200`,说明 managed probe key / 本机 `PACK_PATH` 修复生效。
- fresh-host DB 侧状态也已对齐:在脚本指向正确的 `sub2api-fresh-deepseek-20260519_115244-{postgres,redis}-1` 后,`08-subscription-group-state.json` 已能看到真实的 managed user / subscription / key 绑定,而不是旧 relaymgr 容器造成的空/null 假象。
- 新主阻断不是 auth/tooling而是 completion smoke两条 provider 在 host `/v1/chat/completions` 仍返回 `502 upstream_error`
- 上游直探分流证明:
- DeepSeek 上游 `/chat/completions` = `HTTP 200`,因此 host 侧 502 是真实兼容性问题,不是单纯 key 失效。
- MiniMax 上游 `/chat/completions` = `HTTP 403 insufficient_user_quota`,因此当前验证 key 本身不具备真实 completion 流量能力。
- 汇总证据:`artifacts/real-host-acceptance/20260521_064910_completion_smoke_calibration.md`
- 调通细节与经验沉淀:`docs/REAL_HOST_ACCEPTANCE_LEARNINGS.md`
## 本轮已完成
1. 宿主身份模型统一
- host 注册时持久化 `auth_type/auth_token`
- import / reconcile / rollback-provider / access 运行时链路切换为 `host_id` 主键
- provider status / resources / access status / import-batches 支持 `host_id` 查询维度
2. managed_resources 宿主维度收口
- 新增迁移 `0004_host_identity_and_managed_resources.sql`
- `managed_resources` 唯一键提升为 `(host_id, resource_type, host_resource_id)`
- 仓储与服务查询切换为 host-scoped 语义
3. reconcile run 结果按批次收口
- 新增迁移 `0006_reconcile_runs_batch_scope.sql`
- `reconcile_runs` 补充 `batch_id`batch detail 仅返回本批次 reconcile 记录
4. capability probe 收敛为无副作用探测
- 不再对真实创建接口发送空 `POST`
5. rollback-provider 风险收敛
- 改为优先按已记录批次资源 `RollbackStoredResources()` 回滚
- 缺少已记录资源时拒绝危险删除
6. 文档真相同步
- 新增 `docs/2026-05-18-PRODUCTION_REMEDIATION_TASK_BOARD.md`
- 下调 `DEPLOYMENT.md` 中未实现的 `/metrics` / 限流 / 监控承诺
7. 真实宿主重新验收已执行
- `self_service` 新 artifact`artifacts/real-host-acceptance/20260518_self_service_reaccept_v6`
- `subscription` 新 artifact`artifacts/real-host-acceptance/20260518_subscription_reaccept_v6`
- 两轮都完成了 `preview-import / import / access-preview / status / reconcile / rollback` 全链路落盘
8. reconcile host-scope 证据已补强
- `self_service``artifacts/real-host-acceptance/20260518_reconcile_hostscope_self_service`
- `subscription``artifacts/real-host-acceptance/20260518_reconcile_hostscope_subscription`
- 已补齐 `status / resources / reconcile / batch detail / rollback` 的 host-scoped artifact验证 batch detail 的 reconcile 视图按 batch 收口
9. current-code remote43 导入链路已补齐 tunnel-aware 验证能力
- `scripts/import_remote43_provider.sh` 新增 `CRM_HOST_BASE`允许把“operator 访问 host 地址”和“CRM 进程访问 host 地址”分离
- latest artifact`/home/long/artifacts/real-host-acceptance/20260519_195827_remote43_deepseek_key_import`
- 结论import / batch detail / managed resources 已真实落库;前一轮定位到 channel 创建缺少 model_mapping / restrict_models / billing_model_source已补齐实现与测试
10. current-code remote43 access gate 根因修正已落地
- subscription access 改为宿主侧闭环CRM 不再依赖外部预先给定的宿主普通用户 key而是按 `subscription_users` selector 在宿主创建/查找托管普通用户、登录创建托管 key、回写 allowed_groups / balance、再执行订阅分配
- account 创建请求现在同步写入 `credentials.model_mapping`,修正 `/v1/models` 读取 account model whitelist 时回退到 GPT 默认集合的问题
- 新增/更新测试覆盖:`internal/access``internal/provision``internal/host/sub2api`
## 已验证门禁
- `gofmt -l .` ✅ 空输出
- `go vet ./...`
- `go test ./...`
- `go test -race ./...`
- `go test -cover ./internal/...`
- `internal/access`: `77.3%`
- `internal/pack`: `72.7%`
- `internal/provision`: `74.6%`
- `internal/store/sqlite`: `61.3%`
- `go test ./tests/integration/... -count=1`
## 本轮真实宿主复验结果
0. `ca1d448` latest-head stale-process 阻断已关闭2026-05-21
- 本地 CRM(18100) 新进程启动时间:`2026-05-21 01:08`
- fresh remote43 证据目录:
- `artifacts/real-host-acceptance/20260521_011544_remote43_minimax_key_import`
- `artifacts/real-host-acceptance/20260521_011717_remote43_deepseek_key_import`
- MiniMax`03-import.body.json` 显示 `batch_id=7``access_status=subscription_ready``gateway.status_code=200`
- DeepSeek`03-import.body.json` 显示 `batch_id=8``access_status=subscription_ready``gateway.status_code=200`
- 宿主 admin 侧直接复核:
- `GET /api/v1/admin/channels/5`MiniMax已含非空 `model_pricing``model_mapping`
- `GET /api/v1/admin/channels/4`DeepSeek已含非空 `model_pricing``model_mapping`
- 结论:`ca1d448` 对 channel pricing / hosted access 的修正已在真实宿主 fresh rerun 上落地,之前“旧 CRM 进程导致 MiniMax channel 仍空 pricing”的阻断已消失
1. `self_service`(最新 fresh redeploy 复验)
- 证据目录:`artifacts/real-host-acceptance/20260518_redeploy_matrix`
- 初始状态:普通用户 key 未绑定 group、用户余额为 0 时,`/v1/models` 返回 `403`
- 修正后对普通用户执行“key 绑定标准 group + 用户余额=10”后`04-self-after-balance.headers.txt` 显示 `HTTP/1.1 200 OK`
- 结论:`self_service` 主链路已在 fresh host 上真实打通;当前关键前置条件已收敛为 runbook 中明确记录的普通用户创建 / key-group 绑定 / 余额要求,而不是代码级阻塞。
2. `subscription`(最新 fresh redeploy 复验)
- 证据目录:`artifacts/real-host-acceptance/20260518_redeploy_matrix`
- 修正后:创建 subscription 类型 group、完成普通用户订阅分配、并把普通用户 key 绑定到该 group 后,`06-subscription-after-assign.headers.txt` 显示 `HTTP/1.1 200 OK`
- 结论:`subscription` 主链路也已在 fresh host 上真实打通;其可用前提不是“宿主自动初始化一切”,而是显式完成 subscription group / user subscription / key binding 这一套运营动作。
## 2026-05-19 current-code remote43 验收补充结论
1. 验收入口
- 证据目录:`/home/long/artifacts/real-host-acceptance/20260519_195827_remote43_deepseek_key_import`
- 本地 CRM 通过隧道访问 remote host`CRM_HOST_BASE` 指向 CRM 侧可达的 host 地址
2. 导入链路结论
- `import` 成功返回 `batch_id=19`
- `managed_resources` 已包含 `group/channel/plan/account`
- `provider_status=partially_succeeded`,说明已进入真实业务路径,不再是 host 注册/pack path/隧道前置问题
3. access gate 失败结论
- `latest_access_status=broken`
- `access preview available=false`
- `reconcile status=drifted`,其中 `probe_failures=1`
4. 当前修正
- 旧 artifact 中 `09-models.headers.txt` / `10-models.body.json` 暴露 GPT 系模型根因已重新归类为CRM 写了 channel model_mapping但 account `credentials.model_mapping` 未同步,导致宿主 `/v1/models` 从 account 视图回退到默认模型集
- 同时,旧脚本/调用路径把外部 `subscription_users` / `access_api_key` 直接当宿主用户和宿主 key 使用,无法形成“宿主普通用户创建/查找 + key + 订阅分配”的真正闭环;该问题现已改为宿主托管闭环
- 代码侧阻断点已修复;下一步只剩 DeepSeek / MiniMax 真实 key 复验
## 剩余项(含当前外部门禁)
1. current-code real-host 主阻断已关闭,剩余为验收脚本噪音
- `artifacts/real-host-acceptance/20260520_222713_crm18100_live_model_mapping_validation` 已证明 account `credentials.model_mapping` 与 managed key 视角模型暴露正确
- `20260521_011544_remote43_minimax_key_import` / `20260521_011717_remote43_deepseek_key_import` 又进一步证明在 latest-head CRM 上fresh import 后两条 provider 都进入 `subscription_ready`
- 旧阻断“CRM(18100) 进程过旧导致 MiniMax channel `model_pricing=[]`”已被 host admin 现场证据推翻:`GET /api/v1/admin/channels/5` 现已返回非空 `model_pricing`
- 当前 remaining gap 收敛为 `scripts/import_remote43_provider.sh` 的 direct host probeartifact 中 `09-models.headers.txt` / `11-chat.headers.txt` 仍可见 `401 Unauthorized`,但这与同批次 CRM 记录的 `gateway.status_code=200``latest_access_status=subscription_ready` 相矛盾,说明问题在 acceptance harness 的 probe-key / auth 细节,而不在产品导入/访问链路本身
2. 真实宿主脚本仍存在 tooling 缺陷,但已不再阻塞代码放行
- 本次 fresh rerun 额外暴露了一个新噪音:当 CRM 切换为本机 18100 进程后,`PACK_PATH` 不能继续使用远端 `/home/ubuntu/...`;若未显式改成控制面本机可读路径,会在 import 早期报 `stat pack path ... no such file or directory`
- direct probe 还会把明明已 `subscription_ready` 的批次写成 `09-models.headers.txt = 401 Unauthorized`;这说明脚本对 probe key / auth header 的使用仍不稳定,需要单独修补脚本,而不是继续否定代码 gate
3. 结构债务仍存在
- access / reconcile 尚未完全按 implementation plan 物理拆分
- 无内置 scheduler/jobs
4. 运营前置动作需要 runbook 化执行
- 真实宿主初始化不会自动创建普通用户;当前 CRM subscription 闭环已证明 managed key 语义正确,但 fresh restart 后仍需重新做整条 live 验收,才能把“宿主托管普通用户/key”从代码能力提升为已验收事实
- `self_service` 需要普通用户 key 绑定目标标准 group且通常还需要可用余额
- `subscription` 需要 subscription 类型 group + 普通用户订阅分配 + key/group 绑定
5. 标准多阶段 Dockerfile 在受限网络环境下仍不稳
- 当前推荐 `scripts/build_local_image.sh` + `Dockerfile.local`
6. 真实宿主验收工具需补 host 级参数化
- `scripts/real_host_acceptance.sh``AFTER_IMPORT_HOOK_COMMAND` 仍有价值,但 remote43/fresh-host 变体还缺“目标 Postgres/Redis 容器名、目标 host env 文件、目标 forward 端口”的显式参数化
- 否则 artifact 会混入旧宿主状态,误导 gate 判断
## 当前最短上线路径
1. 产品链路已完成 latest-head fresh host 复跑;当前最短收尾路径不再是“修代码”,而是修 acceptance harness
-`scripts/import_remote43_provider.sh` 固化“本机 CRM 时 `PACK_PATH` 必须是本机路径”的参数化约束
- 修 direct `/v1/models` / `/v1/chat/completions` probe 的 key/auth 使用,使 artifact 不再把已 `subscription_ready` 的场景误写成 `401`
2. 在不依赖该 direct probe 的前提下,当前代码已可维持 `CONDITIONAL_APPROVED`
- fresh host 上 DeepSeek / MiniMax import + access closure 均已成功
- stale-process 导致的 MiniMax channel pricing 缺口已真实关闭
## 禁止错误结论
- ❌ 历史失败 artifact ≠ 当前 fresh redeploy 仍失败
- ❌ capability probe 无副作用 ≠ 所有宿主版本都已真实兼容
- ❌ rollback-provider 已改安全路径 ≠ 历史脏资源自动消失
-`HTTP 200` ≠ 宿主初始化会自动准备普通用户/订阅/余额;这些仍是显式运营前置