games-development-ai/docs/内网凭据与端点.md
lili a513ae38fd
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
fix(storage): harden source authorization and committed CAS
Provision the isolated game-source writer path, bind source uploads to
GameSourceArchive manifests, and require every immutable storage field for
pending-to-committed CAS. Reuse the gate-validated runtime manifest snapshot,
normalize remote storage errors, and record the staging object/CAS evidence.
2026-07-29 19:10:09 -07:00

215 lines
22 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.

---
date: 2026-07-02
topic: 内网凭据与端点
canonical: true
---
# 内网凭据与端点authoritative · 内网阶段密钥/端点单一事实源)
> **创始人铁律2026-06-18****内网阶段,所有决策 + 密钥都进项目文档,不靠环境变量。** 内网Tailscale地址/密钥/token **允许入仓**`CLAUDE.md` 已授权:"内网,地址和密码可入仓")。**需要 key 一律查本档——别再反复找创始人要。**
> 本档 = 内网密钥/端点单一事实源。e2e / 生成产线 / 部署 / 量测 需 key 的地方都读这里。
---
## new-api 网关(生成主线 LLM 网关)
- **`NEWAPI_KEY`(调网关的 token**`sk-84GAintLi0YPG92nGh3fxdIYn6sB7NuOGw0FN491qu1h8NXT`
- **`NEWAPI_BASE_URL`**`http://100.64.0.8:3000`mini-infra
- ⚠️ **baseUrl 坑**JavaSpring AI侧用 **host 根、不带 `/v1`**`http://100.64.0.8:3000`,经 `stripV1Suffix`;Pythonopenai`base_url` 要带 `/v1`。见 `.agents/skills/saa-graph-orchestration.md §3`
- **协议端点(同一 baseUrl、统一 `NEWAPI_KEY`、协议由调用方选)**
- OpenAI 兼容:`POST {baseUrl}/v1/chat/completions`
- Anthropic 原生:`POST {baseUrl}/v1/messages`thinking 分离MiniMax-M3「用对它」走这条
- **接入铁律2026-06-22 纠正旧口径)**:统一出口 = new-api 网关baseUrl + `NEWAPI_KEY`),统一计费 / 密钥 / 审计;**协议与 SDK 不锁**——OpenAI 兼容 / Anthropic 原生 / 厂商 SDK 均可,只要 baseUrl 落 new-api、key 用 `NEWAPI_KEY`。**作废**「唯一 OpenAI 兼容出口 / 绝不直连厂商 SDK」旧表述new-api 只是统一端点,不锁协议)。
- **用途**`SaaFullGraphE2eTest``-Dsaa.e2e=1`/ 生成产线 / **gameDefinition 路 cutover ≥60% 量测**003-U1 第一步)都用它。
- **上游 channel keys**new-api 配的各 provider key,非调网关 token`game-cloud/huijing-server/src/main/resources/application.yaml``channels.*.api-key`(行 ~207-290
- **预置额度池 provision 凭据**WU2 内测 per-user ¥100 = 离线预置池,`game-runtime/tools/newapi_pool_provision.py` 建池/补池用S0 实证 admin 不能替他人建 token → 必直连 new-api postgres,决策见 `.agents/knowledge/tech-decisions.md` §16
- **`NEWAPI_PG_PASSWORD`** = new-api 库(`infra-postgres`)的 postgres 超级用户口令 = **`f6710e2d0294eb1c10e26a805a64bc54`**(用户名 **`root`** 非 postgres;经 `docker exec -e PGPASSWORD=… infra-postgres psql -U root -d new-api` 连,已实测可连、2026-07-08 池水位 11 条可用 token
- **`NEWAPI_ROOT_TOKEN`**(选填,建户/设 quota 用):脚本未设时自动从 `new-api.users.id=1` 读,一般无需显式给。
- **补池**:池空则新用户 claim 不到额度、拿不到生成配额 → 提高 `--count` 重跑脚本(ensure 语义、按确定性 username 去重、不重复建号)。
- **dev 栈 backend↔worker 回调 HMAC 密钥** `AIGC_CALLBACK_SECRET` = **`e8aab27300f74bca3717ce0670644dfc`**(32hex;后端经 `/root/huijing-dev.env` 注入、便宜档 worker 起服带 `--callback-secret <同值>`,两端必须逐字相同;空=验签关闭=内网可伪造回调,内测必须非空)。运行单源 = mini-desktop `/root/huijing-dev.env`(chmod 600),此处为可复现副本。
- **内测账号确定性密码派生种子** `DOGFOOD_PASSWORD_SEED` = **`0f14ed5d8ca2bff1b27785dd15bcfc6d0b91e125e9270806cc1f9ec46b20b740`**64hex仅供 `deploy/provision-dogfood-users.sh` 在受控 Nacos 租约内派生 40 个种子账号密码;禁止进入前端制品、日志或普通用户响应)。运行单源 = mini-desktop `/root/huijing-dev.env`chmod 600此处为可复现副本。
- **可用模型档(对比测试 / 证路用 · 2026-06-25 补)**
- **`glm-5.2`** —— **Anthropic message 协议**(走 `/v1/messages`),定位 **opus 高级模型档**,上下文 **512K**。后续作**高级档对比测试 / 强模型 cross-check 证路**用,填补复杂档「真强模型证路」此前缺 opus 档的空缺(原 deepseek-v4-pro 跨族证路力弱)。
- 便宜档生成主力 = **MiniMax-M3**Anthropic 原生分离 thinking,见上「协议端点」);其余 provider 模型见 application.yaml `channels.*`
---
## 机器Tailscale 内网)
| 机器 | ssh 别名 | Tailscale IP | 角色 |
|---|---|---|---|
| 6c6g本机 | — | 100.64.0.9 | 常驻大脑(文档/计划/评审);**禁 chromeexit 144** |
| mini-desktop | `mini-desktop` | 100.64.0.7 | 权威构建 / e2e 门x86 同构);staging repo `/root/game-staging/repo` |
| mini-infra | `mini-infra` | 100.64.0.8 | 基建new-api:3000 / PostgreSQL / Redis / Gitea / Docker |
| lili-mac | `lili-mac` | 100.64.0.10 | Mac 开发执行线(非常驻,会休眠) |
## Git 远程
- Aliyun Gitea`ssh://git@101.200.34.71:2222`clone/fetch/push 默认走它)
---
## 基建数据面mini-infra `100.64.0.8` · Docker · 2026-06-24 从容器 env 抠出落档)
> tier2 P4 服务化/落库要用:Agent Service 的 MessageBus/session 走 Redis;第二装载落库 manifest 进 MySQL、源文件全文进 MinIO(S3 兼容 OSS)。
| 服务 | 端点(Tailscale) | 凭据 | 用途 |
|---|---|---|---|
| **Redis** | `100.64.0.8:6379` | `requirepass` = `9ea28f5d28d68b09bfd7ccfc31216a52` | tier2 Agent Service MessageBus / session 状态(create_app) |
| **MySQL** | `100.64.0.8:3306` | root / `ZRH3jwYLOrntBcTAw29MW9BP` | tier2 落库源工程版本表(manifest);game-cloud 业务库 |
| **MinIO**(S3 兼容 OSS) | `100.64.0.8:9000`(控制台 9001) | `ragflow` / `6c4b77b2f055c8a66e00e3c38ef3d818c166951d478cc7cc` | tier2 落库源文件全文(key=`tier2-src/<game_id>/<version_id>/<相对路径>`) |
| **PostgreSQL** | `100.64.0.8:5433`(外)→5432(内) | root / `f6710e2d0294eb1c10e26a805a64bc54` | new-api 库(users/tokens/quota,WU2 预置池)/ ragflow;超级用户 = **root** 非 postgres |
> Redis 需 AUTH(NOAUTH 已实证);MinIO root 即 ragflow(与 ragflow 共用实例,tier2 另开 bucket 如 `tier2-src` 隔离)。这些是内网 Tailscale 凭据、按铁律入仓。
### 游戏内容对象存储专用身份2026-07-29
具体游戏的素材、运行包和验收证据不复用 MinIO root。`game-artifact-writer` 只允许对两个制品/证据桶的 `tenants/` 前缀执行对象 Put/Get、前缀内 List 与分片上传恢复;引擎无关源归档另用独立的 `game-source-writer`,只允许 `game-sources/tenants/`。两个身份都没有 DeleteObject、建桶、删桶或策略管理权限source CLI 只读取 source 身份分区,缺失时必须 fail-closed。当前 MinIO 的根列桶接口会返回调用者有权访问的桶名,不会返回其它桶;这项行为不能表述为根列桶请求被拒绝。
| 项 | 值 |
|---|---|
| S3 端点 | `100.64.0.8:9000`(内网 HTTP公网/生产必须切 TLS |
| access key | `game-artifact-writer` |
| secret key | `4aa0a3f0036aac13cded3942c056df2c270b99cb7962624b` |
| 策略 | `game-artifact-writer-policy-v3` |
| 运行包与素材桶 | `game-artifacts` |
| 验收证据桶 | `game-evidence` |
| 允许资源 | `game-artifacts/tenants/*``game-evidence/tenants/*` |
### 引擎无关源归档专用身份2026-07-29
| 项 | 值 |
|---|---|
| access key | `game-source-writer` |
| secret key | `f059ab4593ba7a679a7dbc2ac22305106fabfe2917f98ffacb4a6d67ef0ab0df` |
| 策略 | `game-source-writer-policy-v1` |
| 源归档桶 | `game-sources` |
| 允许资源 | `game-sources/tenants/*` |
2026-07-29 权限实测artifact writer 的两个允许前缀 Put/Get、前缀内 List 和完整 GET/物化流程通过;根列桶只返回该身份可见的制品/证据桶,列/写 `tier2-src`、删除已写对象均被拒绝。当天创建 `game-sources` 与独立 source writer 后source writer 在 `tenants/*` 下 Put/Get/List 成功,删除、越前缀写入和访问 `game-artifacts` 均被拒绝root 只用于清理临时权限探针。运行器分别读取 `tier2/config/infra.yaml``game_artifact_minio``game_source_minio` 分区,任何一个分区缺失都必须拒绝联网,禁止回落到 `minio` root 或另一身份。
两类身份都只代表对象上传/回读权限,不单独代表数据库 committed。source CLI 首次上传回执为 `verified_pending`;本轮 staging 随后完成 V34 数据库条件创建/完整不可变字段 CAS形成 `committed=true` 回执。
同日生产身份盘点纠偏mini-infra 的 `game_cloud` 空库没有接入现行 game-cloud不是游戏身份权威。内网 staging 的真实消费库是 mini-desktop `game-staging-mysql/ruoyi-vue-pro`2026-07-29 在隔离服务进程中应用 V34 后,库中共有 34 条成功 Flyway 历史、110 个项目、53 个版本和 54 个运行包,并通过正式 App API 创建了对象存储验收项目 `gameId=80034`、版本 `versionId=93156`。V34 存储记录已按 artifact/source manifest、bucket、provider、版本和 hash 完整 CAS 为 `status=committed/committed=true`;该 staging 身份只用于本轮隔离验收,不能当作生产发布或正式金标身份,也禁止在空 `game_cloud` 建无人消费的临时记录。
运行时对象提交门已接入 game-cloud 的取包、原始 manifest 和发布入口,配置键为 `game.artifact-storage.enforce-committed`,默认 `false` 仅用于生产切换前的兼容窗口。此前隔离 Runtime 打开 `true` 时,真实 `GET /app-api/runtime/package/93156?scene=preview` 对 pending 记录返回 `1102001001`,日志记录 `[artifactStorageGate] 对象记录未 committed拒绝运行时消费`;同一版本的 artifact manifest 已由专用 writer 全量 GET 回读并物化 263 个对象,`runtimeManifestHash=1191b84776703ce009d361c920da0c3dbb73f328f1383e25580915b10937e4ee`staging generic 适配 bundle 的 `bundleHash=ef2fff2764227b773e4f4dc092941ddbef7f7062fae2dae80160992de637066d`,下载后逐字节一致。提交后的同一进程因 staging Spring 循环依赖未能启动,未宣称 HTTP 放行已复测;正式金标继续使用已签认 bundle `17b9073c767faf7990e0bf4563a86d55ffa81121f11e7c8ad37c8b8ce72e8cbd`,未切换 OSS `PackageStore`
---
## Nacos 配置中心 + 服务发现mini-infra `100.64.0.8` · 2026-07-01 自托管落档 · 切片一 阶段〇 B1
> game-cloud 是 Spring Cloud Alibaba,Nacos 是其原生配置中心 + 服务发现。自托管在 mini-infra,standalone + 外部 MySQL 后端 + lean 512m JVM,纯增量部署(不动既有容器)。配置控制面设计 §3.7 采纳。**C1/C2/D 引用的 `${NACOS_PASSWORD}` = 下面的 admin 口令。**
| 项 | 值 |
|---|---|
| **控制台 / OpenAPI** | `http://100.64.0.8:8848/nacos`(readiness 探针 `/nacos/v1/console/health/readiness`,在 auth 白名单内、免鉴权) |
| **admin 账号** | 用户名 `nacos` / 口令 `3157df7c3edf6c1ecc8a0a58a6efe3a9`(v2.4.3 无内置默认账号,首启 API 建;登录返 globalAdmin JWT) |
| **鉴权 token**(`NACOS_AUTH_TOKEN` = token.secret.key) | `wBMa0tgBihFX6IqJvq364+xIgTb0O9ZpRGY1xE+lTWg=`(base64,解码 32 字节;JWT 签名密钥) |
| **server identity**(server 间鉴权头) | key `nacosServerIdentity` / value `f358e96034ab2cd5e41c1a691b4200bb6f576849d61ed4dd` |
| **MySQL 后端** | 复用既有 `100.64.0.8:3306``nacos` 库(root/`ZRH3jwYLOrntBcTAw29MW9BP`,不新增实例);12 张官方表 |
| **部署位置** | mini-infra `/opt/infra-nacos`(compose 源在仓 `deploy/infra/nacos/`);镜像 `nacos/nacos-server:v2.4.3` |
| **命名空间(namespaceId)** | 默认公共空间 = **空串 `""`**,**勿写字面量 `public`**——`public` 只是显示名(namespaceShowName),不是 id。写侧(game-cloud SCA / yudao publish)与读侧(worker nacos_registry / NacosHotConfig)一律用空串;写 `public` 会静默落进另一个空间、配置永远推不到(阶段〇同款坑)。实测 `GET /nacos/v1/console/namespaces``namespace:""` / `namespaceShowName:"public"`。业务生成配置若要隔离,另建**真实** namespaceId、勿复用显示名 |
- **密钥注入**:上面四个密钥在服务器上物化为 `/opt/infra-nacos/.env`(chmod 600、不入仓);本文档是权威副本,compose 文件只用 `${VAR}` 引用、无明文。
- **运维**:起/停 `cd /opt/infra-nacos && docker compose up -d / down`;探活 `NACOS=http://100.64.0.8:8848 bash deploy/infra/nacos/health-check.sh`(绿=readiness 200)。standalone 单机 512m,实测常驻内存 ~627M。
- admin 口令由首启 API `POST /nacos/v1/auth/users/admin` 一次性设定(重复调用无效);改口令走登录后的用户管理 API,并同步回本档。
---
## RocketMQ 异步消息队列mini-infra `100.64.0.8` · 2026-07-01 自托管落档 · 切片一 阶段〇 B2
> game-cloud 是 Spring Cloud Alibaba,RocketMQ 是其原生异步消息基建,承载异步生成队列。自托管在 mini-infra,单机 NameServer + 单 Broker + lean JVM(broker 1g / namesrv 512m),纯增量部署(不动既有容器)。配置控制面设计 §3.7 采纳。**C3(game-cloud)`rocketmq.name-server: 100.64.0.8:9876`,gen 队列在 `AIGC_GEN_TOPIC` 上生产 / 消费。**
| 项 | 值 |
|---|---|
| **NameServer** | `100.64.0.8:9876`(客户端 `rocketmq.name-server` / `NAMESRV_ADDR` 指这里) |
| **Broker** | `100.64.0.8:10911`(brokerName `broker-a`、DefaultCluster、ASYNC_MASTER;brokerIP1 钉死 Tailscale 地址,故 NameServer 返回的 broker 地址跨机可达) |
| **gen 队列 topic** | `AIGC_GEN_TOPIC`(autoCreateTopicEnable=true,生产端首发消息时自动建;C3 生产 / 消费) |
| **鉴权** | 无(MVP 单机内网,未开 ACL、无密钥) |
| **部署位置** | mini-infra `/opt/infra-rocketmq`(compose 源在仓 `deploy/infra/rocketmq/`);镜像 `apache/rocketmq:5.3.1` |
- **存储**:store / logs 落宿主 `/opt/infra-rocketmq/data`(不入仓)。⚠️ 容器以 uid=3000 运行,该 data 目录部署时已 `chown 3000:3000`,否则 broker 无权写 CommitLog、起不来。
- **运维**:起/停 `cd /opt/infra-rocketmq && docker compose up -d / down`;探活 `NS=100.64.0.8:9876 bash deploy/infra/rocketmq/health-check.sh`(绿=NameServer 端口通 + Broker 在 NameServer 注册)。broker 1g / namesrv 512m,实测常驻内存 broker ~1.24G、namesrv ~186M。
---
## tier2 P4 服务化部署拓扑2026-06-24 首次部署成功落档 · 团队共享)
> 内部开发阶段 · 内网环境;为开发方便,端点 + 凭据明文记录(铁律授权)。下面是「服务跑在哪、怎么起、连什么」。
**Agent Serviceagentscope 2.0.2 `create_app`)—— 跑在 mini-desktop**
- 端点:`http://100.64.0.7:8200`(Tailscale;本机 `127.0.0.1:8200`)。`/docs``/openapi.json` 返 200。
- 起服务:`ssh mini-desktop``cd /root/tier2-run/tier2/gen-worker && NEWAPI_KEY=<见 new-api 段> NO_PROXY=100.64.0.8 /root/.venvs/agentscope-tier2/bin/python -m service.app`(无 CLI serve 命令,模块自调 uvicorn;默认 0.0.0.0:8200,`TIER2_SERVICE_PORT` 可改)。
- REST 路由:`/credential` `/agent` `/sessions` `/chat` `/sessions/{id}/stream`(SSE 收事件)`/workspace/mcp` `/workspace/skill` `/model` `/schedule`
- 后端:Redis(mini-infra:6379)做 session 状态 storage(db0)+ MessageBus(db1)——见上「基建数据面」。
- 代码:dev/2.0.0 `tier2/gen-worker/service/{app,infra_config,bootstrap}.py`;基建配置 `tier2/config/infra.yaml`(运行时读)。
**第二装载落库 BackendStore(`TIER2_STORE=backend` 切换)**
- manifest → MySQL `tier2` 库 · 表 `tier2_source_project_version`(幂等键 `(game_id, source_hash)`;表首次 save 自建,建库 SQL `tier2/config/schema/tier2_source_project_version.sql`)。
- 源文件全文 → MinIO 桶 `tier2-src` · key `tier2-src/<game_id>/<version_id>/<工程内相对路径>`
- 已验:save→fetch 往返、main.js 内容字节一致(2026-06-24)。
**B1 控制面有界 resume(`service/control_plane.py`)—— 真驱服务跑一款到门绿落库**
- 它是服务消费方:驱动上面的 :8200 服务,每回合等 SSE 末态(REPLY_END)→ 独立跑 run_gates 机器判门 → 门绿落库 / 否则带 verdict 反馈续修,直到门绿/预算耗尽。等价 CLI `run_studio` 的外层有界 resume,补服务态此前缺的那道循环。
- 跑一款(detached,日志落 `cp-smoke.log`):
```bash
ssh mini-desktop
cd /root/tier2-run/tier2/gen-worker
NEWAPI_KEY=<见 new-api 段> NO_PROXY=100.64.0.8 \
setsid /root/.venvs/agentscope-tier2/bin/python -m service.control_plane <game_id> \
--base-url http://127.0.0.1:8200 --brief "<一句话富游戏题面>" --max-resumes 3 \
>/root/tier2-run/cp-smoke.log 2>&1 </dev/null &
```
- 评门 `game_id` = 框架分配的 `session_id`(九工具按它管工程目录 `game-runtime/games/_tier2-gen/<session_id>`);控制面不靠内存 session 判收敛,靠每回合独立 run_gates。
- 凭据体口径(2026-06-24 smoke 实证定稿):POST `/credential/` 要 `{data:{type:"anthropic_credential",api_key,base_url}}`(凭据载荷嵌 `data`、无 `model`);POST `/chat/` 的 `input.content` 必须是内容块列表 `[{type:"text",text:...}]`、不能是裸字符串。模型名在 session `chat_model_config.model`。
**运行环境(mini-desktop · 权威运行机)**
- venv:`/root/.venvs/agentscope-tier2`(`agentscope[full]==2.0.2` + `redis`/`pymysql`/`minio`/`httpx`/`esbuild`/`ws`/`phaser`)。
- 部署 worktree:`/root/tier2-run`(detached @ dev/2.0.0;同步新代码 = `git fetch origin dev/2.0.0 && git checkout origin/dev/2.0.0`)。
- 装依赖:`/root/.venvs/agentscope-tier2/bin/pip install -r tier2/gen-worker/requirements.txt`(含 pymysql/minio)`+ redis httpx`。
- **起服务铁律(踩坑)**:经 ssh 起常驻服务,**必须 `setsid … >log 2>&1 </dev/null &` 完全脱离会话**——`nohup … &` 会让 ssh 通道挂住、`timeout ssh` 到点把启动一并打断(实测 service.log 空、:8200 不起)。起完用单独一条只读 ssh 轮询 `/openapi.json`=200 确认就绪。
- 纪律:真玩门(run_gates / chrome / esbuild)只在 mini-desktop;6c6g 禁 chrome、只做静态校验。
> 历史 demo 服务:feie-005 富游戏静态服务在 `mini-desktop:4180`(`python -m http.server 4180 --directory /root/tier2-run`),供创始人亲玩;非生产、可随时关。
## 观测栈 · 全链路可观测性mini-infra `100.64.0.8` · Docker · 2026-07-05 阶段四第一波落档)
> 配置控制面阶段四第一波:OTel Collector + Prometheus + Tempo + Loki + Grafana,接既有 `infra-shared` 网、存 MinIO(obs-tempo/obs-loki 桶)。compose 源在仓 `deploy/infra/observability/`、部署位置 `mini-infra:/opt/infra-observability/`。第一波只后端五件+自监控,不碰生产 game-cloud/生成主链。
| 项 | 值 |
|---|---|
| **Grafana 看板** | `http://100.64.0.8:3002` · admin / `hj-obs-grafana-9K2p7wR`(首登可改;`.env` 的 GF_ADMIN_PASSWORD) |
| Prometheus | `http://100.64.0.8:9091`(9090 被 mini-infra 自身 mihomo/clash API 占,让到 9091) |
| Tempo query | `http://100.64.0.8:3200` |
| Loki | `http://100.64.0.8:3100`(OTLP 摄入端点 `/otlp`) |
| Collector OTLP | gRPC `100.64.0.8:4317` / HTTP `:4318`(跨机信号源推这里);健康 `:13133` |
| MinIO 桶 | `obs-tempo` / `obs-loki`(access `ragflow`、secret 见上「基建数据面」MinIO 行) |
| `.env` | `mini-infra:/opt/infra-observability/.env`(chmod 600、不入仓:MINIO_SECRET_KEY + GF_ADMIN_PASSWORD) |
- **起停探活**:`cd /opt/infra-observability && docker compose up -d / down`;`HOST=100.64.0.8 bash deploy/infra/observability/health-check.sh`(五件全 200 = 绿)。
- **镜像定版**:collector `otel/opentelemetry-collector-contrib:0.155.0`(0.116.0 在 daocloud mirror 缺 binary、0.114.0 redaction 字段不全,几经周折定 0.155.0) / prometheus `v3.1.0` / tempo `2.7.1` / loki `3.3.2` / grafana `11.4.0`。
- **ssh 连法**:内网直连 `ssh -o ProxyCommand=none root@100.64.0.8`(别名 `mini-infra` 经 clash ProxyCommand、mini-infra 内存升级重启后失效)。
---
## game 专属 dify 实例mini-infra `100.64.0.8` · Docker · 2026-07-08 落档 · WU3 形态A
mini-infra 上那套 dify 是 muse 与 game 两个项目共用的。muse 的实例(`muse-dify-*`、宿主端口 18080/18443/15003、owner `muse-admin@local.muse`)被配成单工作区、不许注册与建工作区,不能塞 game 的东西进去。所以给 game **单起了一套隔离 dify**——独立 compose 项目 `game-dify`、独立卷、错开宿主端口,与 muse 零共享数据,muse 侧全程未受扰。WU3「游戏开发节点」形态 A 就在这套里跑通:dify workflow → HTTP 节点 → 它自己的 ssrf_proxy已放行生成 worker→ cheap-worker `:9501/generate` 受理 202。
| 项 | 值 |
|---|---|
| **Console / API** | `http://100.64.0.8:28080`httpssl `28443`、plugin-debug `25003` |
| **owner 登录** | `game-admin@local.game` / `GameDifyMuse2026` |
| `INIT_PASSWORD`setup 前置闸,随 muse .env 克隆来) | `37e442085c5d74ba5cbf93fe` |
| compose 部署位 | `mini-infra:/root/dify-game/docker``COMPOSE_PROJECT_NAME=game-dify`;起停 `cd /root/dify-game/docker && docker compose -p game-dify up -d / down` |
| workflow 应用 | 「游戏开发节点-形态A」`app_id=5ba490f2-e0be-4c84-98a4-8ab5873a17c4`(已发布;跑一次 brief→worker 返 202 |
| 与生成栈关系 | a-min 形态不带 userToken,worker 回落进程级全局 `NEWAPI_KEY`,与真实创作者 per-user 计费天然隔离 |
- **与 muse 隔离**:容器全 `game-dify-` 前缀,内部端口api 5001/db 5432/redis 6379不暴露宿主、由 compose 网络命名空间隔离,只错开了三个 EXPOSE 宿主端口。`SECRET_KEY` 已换新(不与 muse 共签)。ssrf_proxy 只在 game 自己这套的 squid 模板里放行了生成 worker`acl gen_worker dst 100.64.0.7`,在 `deny to_private_networks` 前),muse 的 ssrf 防护一字未动(实测 muse→:9501 仍 403、game→:9501 已 404 通)。
- **console token 签发法headless**:这套 dify 登录要 RSA 加密密码、且所有 console 请求走 CSRF double-submitheader `X-CSRF-Token` 须等于 cookie `csrf_token`、且是 `PassportService` 签的合法 JWT、`sub`=登录用户)。脚本里绕开浏览器取 token 的办法:`docker exec -i game-dify-api-1 flask shell` 里 `AccountService.login(account=<game-admin>, session=db.session, ip_address=...)` 拿 `tp.access_token` 与 `tp.csrf_token`,请求带 `Authorization: Bearer <access>` + `X-CSRF-Token: <csrf>` + `Cookie: csrf_token=<csrf>` 即过。
- **搭建/操作留痕**`spikes/dify-game-dev-node/`(配方 + 已验证可导入的 DSL
---
> 其余基建密钥Gitea 等)按需补入本档,**别散落 env var 或只留在对话**。决策同理——拍板进对应 plan / 本档,不留口头。