2026-05-15 19:26:25 +08:00
|
|
|
|
# sub2api-cn-relay-manager 执行板
|
|
|
|
|
|
|
2026-05-20 22:09:40 +08:00
|
|
|
|
日期:2026-05-20
|
2026-05-21 09:16:45 +08:00
|
|
|
|
当前 Gate:BLOCKED(代码门禁已通过,且 `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` 直探为 200,MiniMax 上游 `chat/completions` 直探为 403 `insufficient_user_quota`。因此当前不允许宣称“完全验收/APPROVED”)
|
2026-05-18 22:22:22 +08:00
|
|
|
|
目标:实现独立控制面、零侵入宿主、可导入国产模型并具备可运维的导入/回滚/访问闭环。
|
|
|
|
|
|
|
2026-05-21 09:16:45 +08:00
|
|
|
|
## 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 流量能力。
|
2026-05-21 13:49:58 +08:00
|
|
|
|
- 2026-05-21 进一步缩圈结果:
|
|
|
|
|
|
- DeepSeek managed key 直打 fresh host `http://127.0.0.1:18097/v1/chat/completions` 仍稳定返回 `502`;但同一台 remote43 主机直接 `curl https://aitoken.quanfuli.cn/v1/chat/completions`(同一 upstream key、同一 payload)返回 `HTTP 200`,且 `Content-Type: text/event-stream`。
|
|
|
|
|
|
- fresh-host app 日志显示 DeepSeek group `5` 当前挂了 10 个 active account(IDs `14,15,16,17,19,20,23,25,26,28`),chat 请求会在这些重复 account 之间 failover,全部记为 `account_upstream_error 500/502` 后才落成 gateway `502`。
|
|
|
|
|
|
- MiniMax group `6` 当前挂了 6 个 active account(IDs `18,21,22,24,27,29`),`temp_unschedulable_reason` 都明确记录为 `insufficient_user_quota`;说明它的 completion 阻断已不是 CRM/host 路由问题,而是验证 key 配额不足。
|
2026-05-21 09:16:45 +08:00
|
|
|
|
- 汇总证据:`artifacts/real-host-acceptance/20260521_064910_completion_smoke_calibration.md`
|
|
|
|
|
|
- 调通细节与经验沉淀:`docs/REAL_HOST_ACCEPTANCE_LEARNINGS.md`
|
2026-05-21 13:37:49 +08:00
|
|
|
|
- 代码门禁与本地运行态已于 2026-05-21 再次独立复跑:`gofmt -l .`、`go vet ./...`、`go test ./... -count=1`、`go test -race ./... -count=1`、`go test -cover ./internal/... -count=1`、`go test ./tests/integration/... -count=1` 全通过;本机 CRM(18100) 的 `GET /healthz` / 带 token 的 `GET /api/hosts` = `200`,另起 fresh smoke 实例 `127.0.0.1:18101` 也成功返回 `GET /healthz = ok`、`GET /api/hosts = {"hosts":[]}`。
|
2026-05-21 09:16:45 +08:00
|
|
|
|
|
2026-05-18 22:22:22 +08:00
|
|
|
|
## 本轮已完成
|
|
|
|
|
|
|
|
|
|
|
|
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 收口
|
2026-05-19 20:21:21 +08:00
|
|
|
|
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`
|
2026-05-20 22:09:40 +08:00
|
|
|
|
- 结论: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`
|
2026-05-18 22:22:22 +08:00
|
|
|
|
|
|
|
|
|
|
## 已验证门禁
|
|
|
|
|
|
|
|
|
|
|
|
- `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` ✅
|
2026-05-21 13:37:49 +08:00
|
|
|
|
- `bash ./scripts/test_real_host_scripts.sh` ✅
|
2026-05-18 22:22:22 +08:00
|
|
|
|
|
|
|
|
|
|
## 本轮真实宿主复验结果
|
|
|
|
|
|
|
2026-05-21 09:16:45 +08:00
|
|
|
|
0. `ca1d448` latest-head stale-process 阻断已关闭(2026-05-21)
|
|
|
|
|
|
- 本地 CRM(18100) 新进程启动时间:`2026-05-21 01:08`
|
2026-05-21 13:37:49 +08:00
|
|
|
|
- 当前 18100 使用的真实 DB:`/tmp/sub2api-relay-manager-realhost-18100.db`
|
2026-05-21 09:16:45 +08:00
|
|
|
|
- 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`
|
2026-05-21 13:37:49 +08:00
|
|
|
|
- 旧现象的根因时间线已确认:`artifacts/real-host-acceptance/20260520_222713_crm18100_live_model_mapping_validation/summary.json` 中 MiniMax channel 5 仍是 `model_pricing=[]`,且 `created_at=updated_at=2026-05-20T20:39:23Z`,说明它是旧 CRM 进程创建出的半成品 channel,而不是 current-code rerun 后依然未纠偏
|
|
|
|
|
|
- 当前 live host 上同一 channel 5 的 `updated_at=2026-05-21T06:45:00Z`,且 `model_pricing` 已非空,证明新进程已真正执行 `UpdateChannel` 纠偏
|
2026-05-21 09:16:45 +08:00
|
|
|
|
- 结论:`ca1d448` 对 channel pricing / hosted access 的修正已在真实宿主 fresh rerun 上落地,之前“旧 CRM 进程导致 MiniMax channel 仍空 pricing”的阻断已消失
|
|
|
|
|
|
|
2026-05-18 22:22:22 +08:00
|
|
|
|
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 20:21:21 +08:00
|
|
|
|
## 2026-05-19 current-code remote43 验收补充结论
|
2026-05-18 22:22:22 +08:00
|
|
|
|
|
2026-05-19 20:21:21 +08:00
|
|
|
|
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`
|
2026-05-20 22:09:40 +08:00
|
|
|
|
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 复验
|
2026-05-19 20:21:21 +08:00
|
|
|
|
|
|
|
|
|
|
## 剩余项(含当前外部门禁)
|
|
|
|
|
|
|
2026-05-21 09:16:45 +08:00
|
|
|
|
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 probe:artifact 中 `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
|
2026-05-20 22:09:40 +08:00
|
|
|
|
3. 结构债务仍存在
|
2026-05-18 22:22:22 +08:00
|
|
|
|
- access / reconcile 尚未完全按 implementation plan 物理拆分
|
|
|
|
|
|
- 无内置 scheduler/jobs
|
2026-05-20 22:09:40 +08:00
|
|
|
|
4. 运营前置动作需要 runbook 化执行
|
2026-05-21 09:16:45 +08:00
|
|
|
|
- 真实宿主初始化不会自动创建普通用户;当前 CRM subscription 闭环已证明 managed key 语义正确,但 fresh restart 后仍需重新做整条 live 验收,才能把“宿主托管普通用户/key”从代码能力提升为已验收事实
|
2026-05-18 22:22:22 +08:00
|
|
|
|
- `self_service` 需要普通用户 key 绑定目标标准 group,且通常还需要可用余额
|
|
|
|
|
|
- `subscription` 需要 subscription 类型 group + 普通用户订阅分配 + key/group 绑定
|
2026-05-20 22:09:40 +08:00
|
|
|
|
5. 标准多阶段 Dockerfile 在受限网络环境下仍不稳
|
2026-05-18 22:22:22 +08:00
|
|
|
|
- 当前推荐 `scripts/build_local_image.sh` + `Dockerfile.local`
|
2026-05-20 22:09:40 +08:00
|
|
|
|
6. 真实宿主验收工具需补 host 级参数化
|
|
|
|
|
|
- `scripts/real_host_acceptance.sh` 的 `AFTER_IMPORT_HOOK_COMMAND` 仍有价值,但 remote43/fresh-host 变体还缺“目标 Postgres/Redis 容器名、目标 host env 文件、目标 forward 端口”的显式参数化
|
|
|
|
|
|
- 否则 artifact 会混入旧宿主状态,误导 gate 判断
|
2026-05-18 22:22:22 +08:00
|
|
|
|
|
|
|
|
|
|
## 当前最短上线路径
|
|
|
|
|
|
|
2026-05-21 09:16:45 +08:00
|
|
|
|
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 缺口已真实关闭
|
2026-05-15 19:26:25 +08:00
|
|
|
|
|
|
|
|
|
|
## 禁止错误结论
|
2026-05-18 22:22:22 +08:00
|
|
|
|
|
|
|
|
|
|
- ❌ 历史失败 artifact ≠ 当前 fresh redeploy 仍失败
|
|
|
|
|
|
- ❌ capability probe 无副作用 ≠ 所有宿主版本都已真实兼容
|
|
|
|
|
|
- ❌ rollback-provider 已改安全路径 ≠ 历史脏资源自动消失
|
|
|
|
|
|
- ❌ `HTTP 200` ≠ 宿主初始化会自动准备普通用户/订阅/余额;这些仍是显式运营前置
|