17 KiB
Master Server 运维
本文记录 Master Server 的架构与判定规则。已安装的 Codex wrapper 负责命令语法,
本文负责 profile 边界、安全规则和验收标准。通用 server 生命周期与 GC 命令仍由
unidesk-ops skill 负责。禁止在本文记录 Secret、一次性故障流水或带日期的
changelog。
执行边界
- Master Server 是生产入口和控制面。
- 本机默认只执行轻量源码修改、Git 操作、状态检查、健康检查、日志、诊断、 JSON CLI 控制动作和本地 profile wrapper 维护。
- 重型构建和仓库级检查必须放到 G14、D601、CI/CD 或目标运行面。
- 本机
/root/unideskcheckout 可用于轻量 UniDesk CLI、trans、tran和 helper 修改。
Codex Provider Profile
-
mycx与oncx是/usr/local/bin/下的稳定系统 Codex wrapper。- 两者复用同一个系统
codexbinary。 - 两者的认证 home 已隔离,长期约束见“系统 Wrapper 与共享状态”。
- 两者复用同一个系统
-
dscx、mxcx和acx是/root/.local/bin/下的隔离 profile wrapper。- 它们是 host 级工具,不属于 UniDesk service 代码。
-
acx是统一多模型入口。gocx保留为 OpenCode Zen Go 兼容入口。- 旧的
dscx-go、dfcx-go和glcx-go只保留兼容入口。
-
dscx:- 使用
CODEX_HOME=/root/.codex-deepseek-v4-pro; - 使用模型
deepseek-v4-pro和 Codex 自定义 providerdeepseek; - 使用本机 Moon Bridge
http://127.0.0.1:38440/v1。
- 使用
-
mxcx:- 使用
CODEX_HOME=/root/.codex-minimax-m3; - 使用模型
MiniMax-M3和 Codex 自定义 providerminimax; - 使用本机 Moon Bridge
http://127.0.0.1:38441/v1。
- 使用
-
acx:- 使用
CODEX_HOME=/root/.codex-acx; - 默认模型是
gpt-5.5-only; - GPT alias 通过 Codex 自定义 provider 直连 OpenAI-compatible Responses 上游;
- OpenCode Zen Go alias 仍通过本机 ACX router 到达
gocx/ Moon Bridge。
- 使用
-
gocx:- 使用
CODEX_HOME=/root/.codex-opencode-go-all; - 默认模型是
glm-5.1; - 使用 Codex 自定义 provider
opencode; - 使用本机 Moon Bridge
http://127.0.0.1:38447/v1。
- 使用
-
dscx-go:- 使用
CODEX_HOME=/root/.codex-opencode-go; - 使用模型
deepseek-v4-pro; - 使用本机 Moon Bridge
http://127.0.0.1:38443/v1。
- 使用
-
dfcx-go:- 使用
CODEX_HOME=/root/.codex-opencode-flash; - 使用模型
deepseek-v4-flash; - 使用本机 Moon Bridge
http://127.0.0.1:38444/v1。
- 使用
-
glcx-go:- 使用
CODEX_HOME=/root/.codex-opencode-glm; - 使用模型
glm-5.1; - 使用本机 Moon Bridge
http://127.0.0.1:38446/v1。
- 使用
-
acx的model-catalog.json:- 包含全部 OpenCode Zen Go upstream slug;
- 包含
gpt-5.5-only和gpt-5.5-sub2api; - 允许在同一 profile 中通过
/model或-m <model>切换。
-
acx的 GPT 路由:gpt-5.5-only直连onlyOpenAI-compatible Responses endpoint;gpt-5.5-sub2api直连 Sub2API pool endpoint;- 两者的 upstream model 都是
gpt-5.5; - GPT 请求禁止经过 Moon Bridge 或 ACX router。
-
GPT direct provider:
- 必须通过
ACX_GPT_DIRECT_API_KEY一类环境键接收 API key; - wrapper 从对应的
/root/.codex/auth.json.<profile>读取; - 禁止回退到
/root/.codex-acx/auth.json; /root/.codex-acx/auth.json只允许保存本地 router dummy key。
- 必须通过
-
隔离的 Moon Bridge 与 router wrapper:
- 从 profile auth 文件读取 upstream API key;
- 仅在兼容路径确有需要时由 wrapper 注入环境变量;
- 生成配置放在 profile 的
.tmp/,权限必须是0600; - 此兼容规则不适用于
mycx的 Pika command-backed auth。
-
每个 profile:
- 必须在
config.toml中设置model_catalog_json; - 必须指向包含当前模型的 profile-local
model-catalog.json; - 缺失时 Codex 会回退到默认 metadata,并输出
Model metadata ... not found。
- 必须在
-
Profile context metadata:
- 必须与真实 upstream limit 对齐;
- 必须让 Codex auto-compact 在 provider 拒绝请求前触发。
-
当前 Master Server profile baseline:
acx暴露的 GPT profile 使用model_context_window = 272000和model_auto_compact_token_limit = 240000;deepseek-v4-pro与deepseek-v4-flash使用model_context_window = 1000000和model_auto_compact_token_limit = 900000;glm-5.1、MiniMax-M3及其他本地 Moon Bridge profile 使用model_context_window = 200000和model_auto_compact_token_limit = 180000。
-
Wrapper 生成的 Moon Bridge / router metadata:
- 必须与 profile
config.toml和model-catalog.json对齐; - 不一致时 Codex 与本地 admission layer 会对 compact 和请求大小产生分歧。
- 必须与 profile
-
Codex API 通道的
NO_PROXY/no_proxy:- 必须保留
hyueapi.com和.hyueapi.com。
- 必须保留
系统 Wrapper 与共享状态(mycx / oncx)
-
mycx与oncx:- 复用同一个系统
codexbinary; - 使用不同的认证
CODEX_HOME; - 共享 SQLite session index 和 durable transcript。
- 复用同一个系统
-
/usr/local/bin/mycx:- 使用
CODEX_HOME=/root/.codex; - 选择 profile
pika; - 可写 profile 文件是
/root/.codex/pika.config.toml。
- 使用
-
/usr/local/bin/oncx:- 使用
CODEX_HOME=/root/.codex-only; - 使用
CODEX_SQLITE_HOME=/root/.codex; - 选择 profile
only; - 可写 profile 文件是
/root/.codex-only/only.config.toml。
- 使用
-
oncx的账号认证:- 只使用
/root/.codex-only/auth.json; cli_auth_credentials_store必须是file;forced_login_method必须是chatgpt;auth.json权限必须是0600;- wrapper 必须清理
OPENAI_API_KEY、CODEX_API_KEY、CODEX_ACCESS_TOKEN和CRS_OAI_KEY; oncx login、oncx login status和oncx logout必须直接操作 隔离 home,禁止附加仅适用于 runtime command 的--profile。
- 只使用
-
oncx的共享状态:/root/.codex-only/sessions链接到/root/.codex/sessions;/root/.codex-only/archived_sessions链接到/root/.codex/archived_sessions;history.jsonl、skills和plugins链接到共享 home;- shell snapshot、认证文件和 profile 配置保持隔离。
-
/root/.codex/config.toml与/root/.codex/auth.json:- 由
codex-pool configure-local管理; - 只代表 Sub2API consumer;
- 禁止作为
oncx的 ChatGPT 登录凭据。
- 由
-
Webterm:
config/platform-infra/webterm.yaml启动mycx;- wrapper path 或启动方式变更必须保留原入口并执行 Webterm launch check。
-
Shell startup 文件:
- 禁止定义同名 function 覆盖这些 executable;
- 禁止在启动时重新生成 profile 文件;
- wrapper 变更后,旧 Codex 进程必须退出;
- 旧 shell 必须清除残留 function 或启动新 shell后再验收。
-
Profile-v2 持久化:
/model把model与 reasoning effort 写入当前 profile 文件;mycx与oncx必须独立记住最后一次选择;-m、-c model...和-c model_reasoning_effort...只允许临时覆盖;- 新启动、profile 切换和 resume 必须分别诊断。
-
Codex 官方认证边界:
--profile只覆盖 profile TOML,不隔离auth.json;- file-based credential storage 的
auth.json由CODEX_HOME决定; - 账号登录与 API-key consumer 必须使用不同的
CODEX_HOME; - 依据见 Codex Manual。
-
Session discovery:
- 共享 SQLite 和 transcript 不保证
/resume结果完全相同; - picker 还会按 provider ID、cwd、source 和 archive state 过滤;
- provider ID 是持久化且大小写敏感的 session bucket key;
--all只移除 cwd 限制,不移除 provider 限制;- Codex 升级后必须重新验证此契约;
- resume 使用当前 profile 的有效 model、provider 和 reasoning override;
- resume 不保证恢复 session 最后记录的模型。
- 共享 SQLite 和 transcript 不保证
-
Rollout JSONL:
- 是 durable history;
- 可以重新填充 SQLite index;
- 禁止只修改
state_5.sqlite合并 provider bucket; - history migration 必须停止活动 Codex 进程;
- 必须用结构化 JSON parser 修改 rollout metadata;
- 必须事务化更新 SQLite index;
- 必须保留 provenance 并在 reindex 后验证相同 session ID 集合。
-
Provider identity:
- 是兼容性契约;
- 修改
CODEX_HOME、profile name、provider ID 或大小写前必须预检历史; - 会产生新隐藏 bucket 时必须告警或阻断;
- 禁止让不同真实 backend 仅为合并 picker list 而冒充同一 provider。
-
Pika 认证:
- 必须使用
[model_providers.Pika.auth]的 command-backed provider auth; - credential source 是
/root/.codex/auth.json.pika; - 文件权限必须是
0600; - 禁止把 Pika API key 导出到 wrapper 或 Codex 环境;
- shell snapshot 权限必须是
0600; - shell snapshot 禁止包含可复用 credential;
- 发现 plaintext snapshot 时必须删除副本并轮换 credential。
- 必须使用
-
Secret-safe 诊断只允许报告:
- 有效
CODEX_HOME; - wrapper path;
- 当前 profile 文件;
- provider ID;
- model 与 reasoning;
- 按 provider 统计的 session 数量;
- credential presence 或 fingerprint;
- 相关文件权限。
- 有效
-
Profile 持久化验收:
- 选择一个非 baseline
/model; - 退出后重新启动相同 wrapper;
- 确认选择保持;
- 确认另一 profile 文件未变化;
- 确认临时 CLI override 不写回 profile。
- 选择一个非 baseline
-
oncx认证验收:oncx login status必须显示Logged in using ChatGPT;- 注入无效 API-key 环境变量后仍必须显示 ChatGPT 登录;
oncx exec --ephemeral '<smoke prompt>'必须完成真实 Responses turn;- 共享
codex login status必须继续显示 Sub2API API-key 登录; - 全程禁止输出 token 或完整 API key。
-
mycx认证验收:- 对应 API-key 环境变量缺失时,Pika command-backed auth 仍必须可用。
-
/resume差异诊断:- 先比较
CODEX_HOME、provider ID、cwd、source 和 archive filter; - 禁止在这些边界未核对前归因为 storage loss 或 cache。
- 先比较
相关调查证据与源码级依据保留在 UniDesk issue #1640,本文是当前长期规则的 唯一权威入口。
Moon Bridge
Moon Bridge 安装在 /root/.local/bin/moonbridge。该 binary 暴露 OpenAI Responses
endpoint,并把 Codex 请求桥接到 provider-specific upstream API。已安装的 profile
wrapper 负责 bridge 命令语法,本文只记录运行边界。
- 已安装 patch build 的本地源码:
- 路径是
/root/src/moon-bridge-sanitize; - 修改时必须保持范围收敛;
- 必须运行 package-level test;
- 必须构建 replacement binary;
- 必须备份旧 binary;
- 必须重启受影响的 profile bridge;
- 仍受 Master Server 重型构建限制。
- 路径是
Profile 架构
dscx bridge-start:- 渲染 profile 配置;
- 在
127.0.0.1:38440启动 Moon Bridge。
mxcx bridge-start:- 渲染 profile 配置;
- 在
127.0.0.1:38441启动 Moon Bridge。
acx route-start:- 渲染 ACX router 配置;
- 在
127.0.0.1:38448启动本地 routing service; - 只服务仍需 OpenCode Zen Go bridge path 的非 GPT alias。
gocx bridge-start:- 渲染多模型 OpenCode Zen Go profile 配置;
- 在
127.0.0.1:38447启动 Moon Bridge。
dscx-go bridge-start:- 在
127.0.0.1:38443启动 Moon Bridge。
- 在
dfcx-go bridge-start:- 在
127.0.0.1:38444启动 Moon Bridge。
- 在
glcx-go bridge-start:- 在
127.0.0.1:38446启动 Moon Bridge。
- 在
- Wrapper 启动 bridge:
- 使用
setsid; - 使用 profile-local PID 文件;
- 日志写入
<CODEX_HOME>/logs/moonbridge/。
- 使用
dscx路由:- 通过 Moon Bridge 使用 Anthropic-compatible upstream;
- 使用
deepseek_v4extension。
mxcx路由:- 通过 Moon Bridge 使用
openai-responseupstream passthrough。
- 通过 Moon Bridge 使用
- OpenCode Zen Go 路由:
acx把模型路由到gocx/ Moon Bridge;gocx、dscx-go、dfcx-go和glcx-go使用openai-chatupstream;- upstream 是
https://opencode.ai/zen/go/v1/chat/completions; - Codex 侧保持
wire_api = "responses"。
acxGPT 路由:- 必须直连 OpenAI-compatible Responses endpoint;
- 禁止经过 Moon Bridge 或本地 ACX router;
- GPT mode 下
acx status必须报告mode=gpt-direct; - 必须报告
routerRequired=false; 127.0.0.1:38448不应存在 listener。
- OpenCode Zen Go model ID:
- 必须使用 upstream slug,例如
glm-5.1; GLM-5.1一类 display name 不是 profile model identifier。
- 必须使用 upstream slug,例如
- OpenCode Zen Go bridge:
- 禁止保留手写 bridge script;
- 禁止保留静态替代
moonbridge.config.yml; - 唯一支持路径是 wrapper 生成的
.tmp/moonbridge.generated.yml和/root/.local/bin/moonbridge; - 生成的 provider 配置必须显式设置
user_agent。
- Moon Bridge context-window admission:
- oversized request 必须在本地 Responses path 被拒绝;
- 预期状态是 HTTP
400; - 错误类型是
invalid_request_error; - 错误 code 是
context_length_exceeded; - 禁止表现为 upstream-translated
502 Bad Gateway。
- MiniMax:
- 未经 tool-enabled smoke 证明可用,禁止把 Codex CLI 切到
openai-chat。
- 未经 tool-enabled smoke 证明可用,禁止把 Codex CLI 切到
Profile 验收
*-go raw-smoke:- 直接验证 upstream OpenCode Zen Go Chat Completions API。
*-go bridge-smoke:- 验证本地 Moon Bridge 的
/v1/responsestranslation path。
- 验证本地 Moon Bridge 的
*-go exec '在吗':- 验证真实 Codex profile;
- 输出禁止包含
Model metadata ... not found; - 最新 session 必须使用 profile catalog 提供的
model_context_window。
- ACX GPT 验收:
- 使用
acx status、acx models、acx gpt-only exec '在吗'、acx gpt-sub2api exec '在吗'和 默认acx exec '在吗'; - 必须完成真实 Codex Responses turn;
- repeated 或 resume traffic 必须出现非零
cached_input_tokens; - 禁止依赖
127.0.0.1:38448listener。
- 使用
- ACX OpenCode Zen Go alias 验收:
- 使用
acx route-start、acx route-status、acx models和acx -m <opencode-model> exec '在吗'; - 验证 router 到
gocx的路径。
- 使用
gocx模型验收:- 使用
gocx raw-smoke [model]; - 使用
gocx bridge-smoke [model]; - 使用
gocx -m <model> exec '在吗'; - 省略
[model]时默认使用glm-5.1。
- 使用
ReasoningSummaryDelta without active item:- 是 reasoning summary event 的独立 adapter noise;
- 不等同于 model metadata 缺失;
- 不能单独证明 profile 不可用。
OpenAI Responses Tool Argument Sanitizer
- Moon Bridge:
- 负责 MiniMax 风格错误 tool argument JSON 的在线 sanitizer;
- 作用于
openai-responsepassthrough path; - 是第一道防线;
- wrapper-level session cleanup 只处理 sanitizer 安装前已损坏的 JSONL。
- Sanitizer:
- 递归扫描
ResponsesRequest.input; - upstream 前修复 tool-call
arguments; - 在 completed event 中修复 response-side
arguments; - 禁止修改 delta chunk;
- 无法恢复时回退到
{}; - response rewrite 必须删除 upstream
Content-Length。
- 递归扫描
MiniMax Session 恢复
mxcx:- 为损坏的 MiniMax-backed session JSONL 提供 cleanup 与 guard layer;
- wrapper 负责命令语法;
- 本节只记录行为规则。
mxcx resume:- 调用 Codex 前自动执行
session-clean和session-guard; - 使用
CODEX_HOME=/root/.codex-minimax-m3。
- 调用 Codex 前自动执行
session-clean:- 只处理无效 tool-call
arguments; - 包括 malformed JSON、MiniMax sentinel text 和 schema-invalid case;
- 必须保留行顺序、非 tool message、reasoning、output、token record 和 session metadata;
- 禁止 compact、summarize、truncate 或 reorder transcript。
- 只处理无效 tool-call
- 新的无效
arguments:- 必须由 Moon Bridge sanitizer 在线阻止;
session-clean只用于恢复既有损坏 session。
session-guard:- 注入
mxcx-minimax-tool-and-apply-patch-guard-v2; - 禁止重复注入。
- 注入
MiniMax Apply-Patch 操作
- MiniMax-backed session:
- 必须使用与其他 agent 相同的 UniDesk 远端文本 patch 契约;
- route 在前,operation 在后;
- 默认使用
apply-patchv2。
- 稳定写入形式:
trans <provider>:/absolute/workspace apply-patch < patch.diff。
- 只读检查:
- 使用
trans <provider>:/absolute/workspace nl -ba file或同等有界命令。
- 使用
apply-patch报告failed to find expected lines时:- 先读取目标当前精确内容;
- 再用更小的
Update Filehunk 重试; - 或使用
@@ <unique anchor>; - 或拆成多个小 hunk;
- 这是正常 stale-context 恢复,禁止因此切换工具。
- 文本 patch 失败时禁止使用:
download/upload;- 远端 Python、Perl 或 sed heredoc;
cat >或tee整文件覆盖;apply-patch-v1。
- 仅在以下情况允许例外:
apply-patch本身不可用;- 目标不是文本;
- 目标是批量机械生成内容。