12 KiB
Master Server Ops
This document records master-server architecture and decision rules. Operations commands (Moon Bridge management, profile smoke tests, MiniMax session recovery) have moved to the unidesk-ops skill (~/.agents/skills/unidesk-ops/SKILL.md). Do not place secrets, one-off incident logs, or dated changelog notes here.
Execution Boundary
- The master server is the production entry point and control plane. Default work on this host is limited to light source edits, Git operations, status checks, health checks, logs, diagnostics, JSON CLI control actions, and local profile wrapper maintenance.
- Heavy builds and repository-wide checks should run on an external execution surface such as G14, D601, CI/CD, or the target runtime.
- The local UniDesk checkout at
/root/unideskcan be used for lightweight UniDesk CLI/trans/tran/helper changes.
Codex Provider Profiles
dscx, mxcx, and acx are local Codex profile wrappers under /root/.local/bin/. They are host-level tools, not UniDesk service code. acx is the unified multi-model entry; gocx remains the OpenCode Zen Go compatibility entry, and older single-model dscx-go, dfcx-go, and glcx-go wrappers are compatibility entries. Usage commands are in unidesk-ops skill.
dscxusesCODEX_HOME=/root/.codex-deepseek-v4-pro, modeldeepseek-v4-pro, Codex custom providerdeepseek, and local Moon Bridge athttp://127.0.0.1:38440/v1.mxcxusesCODEX_HOME=/root/.codex-minimax-m3, modelMiniMax-M3, Codex custom providerminimax, and local Moon Bridge athttp://127.0.0.1:38441/v1.acxusesCODEX_HOME=/root/.codex-acxand default modelgpt-5.5-only. GPT aliases use Codex custom providers that connect directly to their OpenAI-compatible Responses upstreams; OpenCode Zen Go aliases still use the local ACX router only to reachgocx/Moon Bridge.gocxusesCODEX_HOME=/root/.codex-opencode-go-all, default modelglm-5.1, Codex custom provideropencode, and local Moon Bridge athttp://127.0.0.1:38447/v1.dscx-gousesCODEX_HOME=/root/.codex-opencode-go, modeldeepseek-v4-pro, Codex custom provideropencode, and local Moon Bridge athttp://127.0.0.1:38443/v1.dfcx-gousesCODEX_HOME=/root/.codex-opencode-flash, modeldeepseek-v4-flash, Codex custom provideropencode, and local Moon Bridge athttp://127.0.0.1:38444/v1.glcx-gousesCODEX_HOME=/root/.codex-opencode-glm, modelglm-5.1, Codex custom provideropencode, and local Moon Bridge athttp://127.0.0.1:38446/v1.acxincludes all OpenCode Zen Go upstream slugs plusgpt-5.5-onlyandgpt-5.5-sub2apiin onemodel-catalog.jsonso Codex can use/modelor-m <model>within the same profile.acxroutes OpenCode Zen Go models to the existinggocxMoon Bridge. GPT models must not pass through Moon Bridge or the ACX router:gpt-5.5-onlyuses the directonlyOpenAI-compatible Responses endpoint andgpt-5.5-sub2apiuses the Sub2API pool endpoint, both with upstream modelgpt-5.5.- GPT direct providers must receive their API key through an environment-key path such as
ACX_GPT_DIRECT_API_KEY, read from the matching/root/.codex/auth.json.<profile>file by the wrapper. Do not let direct GPT calls fall back to/root/.codex-acx/auth.json; that file may contain only the local-router dummy key. - All wrappers read upstream API keys from profile auth files or wrapper-injected environment variables; generated Moon Bridge or router runtime configs live under the profile
.tmp/directory with mode0600. Do not copy upstream keys into documentation. - Each profile must include
model_catalog_jsoninconfig.tomlpointing to a profile-localmodel-catalog.jsonentry for its active model. Missing catalog metadata causes Codex to fall back to default metadata, which lowers the effective context window and printsModel metadata ... not found. - Profile context metadata must match the intended upstream limit closely enough for Codex auto-compact to fire before provider rejection. Keep the local profile metadata in sync with the actual model family you are routing to.
- Current master-server profile baselines:
- GPT profiles exposed through
acxusemodel_context_window = 272000andmodel_auto_compact_token_limit = 240000. This represents the Codex-facing input window for GPT-5.5, not the larger raw API model window. deepseek-v4-proanddeepseek-v4-flashusemodel_context_window = 1000000andmodel_auto_compact_token_limit = 900000.- Other local Moon Bridge profiles, including
glm-5.1,MiniMax-M3, and the non-DeepSeek OpenCode models exposed throughacx/gocx, usemodel_context_window = 200000andmodel_auto_compact_token_limit = 180000.
- GPT profiles exposed through
- Keep the wrapper-generated Moon Bridge/router metadata aligned with the profile
config.tomlandmodel-catalog.json. If these diverge, Codex and the local admission layer may disagree about compaction and request size behavior. hyueapi.com/.hyueapi.commust remain inNO_PROXY/no_proxyfor Codex API channels.
Moon Bridge
Moon Bridge is installed as /root/.local/bin/moonbridge. The binary exposes OpenAI Responses endpoints and bridges Codex to provider-specific upstream APIs. Operations commands are in unidesk-ops skill.
The local source copy for the installed patched build is /root/src/moon-bridge-sanitize. When changing Moon Bridge, keep the change narrow, run package-level tests, build a replacement binary, back up the previous binary, then restart affected profile bridges. Default master-server build restrictions still apply.
Profile architecture:
dscx bridge-startrenders profile config and starts Moon Bridge on127.0.0.1:38440.mxcx bridge-startrenders profile config and starts Moon Bridge on127.0.0.1:38441.acx route-startrenders the ACX router config and starts the local routing service on127.0.0.1:38448for non-GPT ACX aliases that still need the OpenCode Zen Go bridge path.gocx bridge-startrenders multi-model OpenCode Zen Go profile config and starts Moon Bridge on127.0.0.1:38447.dscx-go bridge-startrenders profile config and starts Moon Bridge on127.0.0.1:38443.dfcx-go bridge-startrenders profile config and starts Moon Bridge on127.0.0.1:38444.glcx-go bridge-startrenders profile config and starts Moon Bridge on127.0.0.1:38446.- The wrappers start Moon Bridge with
setsidand a profile-local PID file. - Logs are written under
<CODEX_HOME>/logs/moonbridge/. dscxroutes DeepSeek through Moon Bridge using Anthropic-compatible upstream +deepseek_v4extension.mxcxroutes MiniMax through Moon Bridge usingopenai-responseupstream passthrough.acxroutes OpenCode Zen Go models togocx/Moon Bridge.gocx,dscx-go,dfcx-go, andglcx-goroute OpenCode Zen Go through Moon Bridge usingopenai-chatupstream athttps://opencode.ai/zen/go/v1/chat/completions. The Codex side remainswire_api = "responses"against the local Moon Bridge URL.acxroutes GPT aliases directly to OpenAI-compatible Responses endpoints and must not send GPT traffic through Moon Bridge or through the local ACX router. In GPT mode,acx statusshould reportmode=gpt-direct,routerRequired=false, and no listener on127.0.0.1:38448.- OpenCode Zen Go model IDs must use the upstream slug, such as
glm-5.1; display names such asGLM-5.1are not profile model identifiers. - Do not keep local handwritten bridge scripts, static alternate
moonbridge.config.ymlfiles, or other sidecar proxy paths for OpenCode Zen Go profiles. The only supported runtime path is wrapper-generated.tmp/moonbridge.generated.ymlplus/root/.local/bin/moonbridge. - For OpenCode Zen Go profiles, set an explicit
user_agentin the generated Moon Bridge provider config. The upstream may reject default client signatures. - Moon Bridge now performs a local context-window admission check on the Responses path before forwarding oversized requests upstream. The expected failure shape for an oversized prompt is local HTTP
400withinvalid_request_errorand codecontext_length_exceeded, not an upstream-translated502 Bad Gateway. - Do not switch MiniMax to
openai-chatfor Codex CLI unless tool-enabled smoke proves it works.
Profile validation:
*-go raw-smokeverifies the upstream OpenCode Zen Go Chat Completions API directly.*-go bridge-smokeverifies local Moon Bridge's/v1/responsestranslation path.*-go exec '在吗'verifies the actual Codex profile. Passing output must not containModel metadata ... not found; latest session records should showmodel_context_windowderived from the profile catalog, not fallback metadata.acx status,acx models,acx gpt-only exec '在吗',acx gpt-sub2api exec '在吗', and defaultacx exec '在吗'verify GPT direct mode. Passing GPT verification should show a real Codex Responses turn and, for repeated or resume traffic, nonzerocached_input_tokens; it should not require a listener on127.0.0.1:38448.- For OpenCode Zen Go aliases exposed through
acx, useacx route-start,acx route-status,acx models, andacx -m <opencode-model> exec '在吗'to verify the router-to-gocxpath. gocx raw-smoke [model],gocx bridge-smoke [model], andgocx -m <model> exec '在吗'verify specific OpenCode Zen Go models. Omitting[model]uses the defaultglm-5.1.ReasoningSummaryDelta without active itemin Codex stderr is a separate adapter noise from reasoning summary events. It is not the same failure as missing model metadata and does not by itself prove the profile is unusable.
OpenAI Responses Tool Argument Sanitizer
Moon Bridge owns the online sanitizer for MiniMax-style bad tool argument JSON on the openai-response passthrough path. This is the first line of defense; wrapper-level session cleanup is only for JSONL that was already corrupted before the sanitizer was installed.
Sanitizer rules: recursively scans ResponsesRequest.input, repairs tool-call arguments before upstream, repairs response-side arguments in completed events (not delta chunks), falls back to {} on unrecoverable input. Response rewriting drops upstream Content-Length.
MiniMax Session Recovery
mxcx includes a cleanup and guard layer for corrupted MiniMax-backed session JSONL. Recovery operations commands are in unidesk-ops skill. This section only documents behavioral rules.
mxcx resumeauto-runssession-clean+session-guardbefore invoking Codex. UsesCODEX_HOME=/root/.codex-minimax-m3profile.session-cleanis strictly scoped to invalid tool-callarguments: malformed JSON, MiniMax sentinel text, and schema-invalid cases. Must preserve line order, non-tool messages, reasoning, outputs, token records, and session metadata. Must not compact/summarize/truncate/reorder transcript.- New invalid
argumentsshould be prevented online by Moon Bridge sanitizer. Usesession-cleanonly to recover already-written sessions. session-guardinjectsmxcx-minimax-tool-and-apply-patch-guard-v2, avoiding duplicates.
MiniMax Apply-Patch Operations
MiniMax-backed sessions must use the same UniDesk remote text patch contract as other agents: route first, operation second, and apply-patch v2 by default. The stable write shape is trans <provider>:/absolute/workspace apply-patch < patch.diff; read-only inspection may use trans <provider>:/absolute/workspace script -- 'nl -ba file' or equivalent bounded commands.
- If
apply-patchreportsfailed to find expected lines, first read the exact current target block, then retry with a smallerUpdate Filehunk, an@@ <unique anchor>hint, or multiple small hunks. This is normal stale-context recovery, not a reason to switch tools. - Do not recover text patch failures by using
download/upload, remote Python/Perl/sed heredocs,cat >/teewhole-file rewrites, orapply-patch-v1, unlessapply-patchitself is unavailable or the target is non-text / bulk mechanical generated content.