# Installation and Development Replacement

## Requirements

- Linux with `/proc` available for reliable zombie detection.
- Bash for the installer and installed command wrappers.
- Python 3.11 or newer.
- Git.
- Codex CLI exactly 0.149.0 with the reviewed experimental app-server schema.
- Switchyard 0.2.0 for profiles that bind one or more models through a `switchyard` route.
- npm only when using `--install-codex`.
- Rust/Cargo 1.96.1 or newer only when using `--install-switchyard` (the
  Switchyard 0.2.0 crate's declared minimum Rust version).
- A local model server when a selected profile uses one.

## Default per-user paths

```text
Install: ~/.local/share/codex-mmo
Config:  ~/.config/codex-mmo
State:   ~/.local/state/codex-mmo
Binaries: ~/.local/bin
```

The installer creates `catalog.d/`, `profiles.d/`, and `tool-mcp.d/` beneath the configuration root. Tool MCP definitions are operator configuration and are preserved across a current-generation reinstall.

The installer follows XDG Base Directory 0.8 for `XDG_DATA_HOME`, `XDG_CONFIG_HOME`, and `XDG_STATE_HOME`: an unset, empty, or relative value is ignored and the documented absolute fallback is used. `XDG_BIN_HOME` is a Codex MMO installer extension, not an XDG Base Directory variable; it follows the same absolute-value rule and otherwise falls back to `~/.local/bin`.

The 8.0.0 release targets Python 3.11 semantics and was tested locally on Python 3.14.7, Codex 0.149.0, Switchyard 0.2.0, Git 2.55, GNU tar 1.35, and Info-ZIP 6.00. The optional Cargo path pins Switchyard 0.2.0 because generated route syntax is verified against that exact release; building that crate requires its declared Rust 1.96.1 minimum (tested locally with Rust/Cargo 1.97.1). An operator-supplied newer Switchyard must pass `doctor --live` (including its native dry run) before use. Codex is deliberately exact-pinned: every session admission, reattachment, and replacement host checks the reported 0.149.0 version, while `doctor --live` additionally requires 401 generated experimental schema files with digest `fcfeaf23728b96ab73916a21302eb7a16629e67ee99f7ee47b60fad6b6e5ee1a`. Any other Codex version is rejected; this development release has no compatibility reader or migration path. Provider services remain authoritative for live model/account availability.

## Verify the archive before installation

From beside an extracted source tree, verify both downloaded formats when available:

```bash
python3 codex-multimodel-orchestrator-8.0.0/scripts/verify_release.py \
  --source-tree codex-multimodel-orchestrator-8.0.0 \
  codex-multimodel-orchestrator-8.0.0-linux.tar.gz \
  codex-multimodel-orchestrator-8.0.0-linux.zip
```

The command rejects incomplete archives, extra or missing files, implicit or extra directory entries, digest mismatches, file/directory mode drift, traversal, links, special files, and manifest/source differences.

## Standard installation

Inspect installer options without changing the system:

```bash
./install.sh --help
```

```bash
tar -xzf codex-multimodel-orchestrator-8.0.0-linux.tar.gz
cd codex-multimodel-orchestrator-8.0.0
./install.sh
```

Install optional tools when missing:

```bash
./install.sh --install-codex --install-switchyard
```

Custom paths and binary names:

```bash
./install.sh \
  --install-root /opt/user/codex-mmo \
  --config-root "$HOME/.config/codex-mmo" \
  --state-root "$HOME/.local/state/codex-mmo" \
  --bin-dir "$HOME/bin" \
  --codex-bin /usr/local/bin/codex \
  --switchyard-bin "$HOME/.cargo/bin/switchyard-server"
```

The installer first requires every declared payload file/directory to exist and rejects source symlinks and special files. It then stages and validates the payload before an atomic replacement. A nonempty existing install root is replaced only when its generation-8 ownership manifest identifies that same canonical path; an unrelated or corrupt tree is left untouched. Existing owned installs are moved to timestamped state backups. Existing settings and credentials are preserved only when they already satisfy generation 8. Optional npm/Cargo installers receive a filtered environment, and a zero package-manager exit is accepted only when the requested Codex or Switchyard executable can then be resolved.

Finish, gracefully stop, or cancel active sessions before replacing the installed development build. A detached run
whose workers are still active is not quiescent. Process identity, app-server control sockets,
thread-host metadata, and runtime documents are build-specific. Generation 8 deliberately does not
adopt older process trees or load older records. Preserve evidence outside the active MMO state root,
remove the obsolete runtime state, and start one new generation-8 session from an explicit handoff.

## PATH

The installer warns on stderr when the selected binary directory is not already on `PATH`. Ensure
the default directory is available in future shells:

```bash
export PATH="$HOME/.local/bin:$PATH"
```

After installation, use `codex-mmo --help` for the user-facing command map. The
`codex-mmoctl` entrypoint exposes the same control commands but intentionally fails when no command
is given instead of starting an interactive session. See [Command-line interface](CLI.md).

## Credentials

Edit:

```bash
${EDITOR:-vi} ~/.config/codex-mmo/credentials.env
```

Bundled routes may use:

```dotenv
ZAI_CODING_API_KEY=
OPENCODE_API_KEY=
OPENROUTER_API_KEY=
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
# Optional only for an explicitly selected Z.AI General API route:
ZAI_API_KEY=
```

Unused values should remain empty. File permissions are `0600`.

Third-party Tool MCP credentials use the same file, but their variable names come from the operator registry rather than a profile pack. See [Tool MCP servers](TOOL_MCP.md) for the registry and per-role grant format.

OpenCode uses one `OPENCODE_API_KEY` for both Zen and Go. OpenRouter uses `OPENROUTER_API_KEY`. Every bundled GLM-5.3 role uses the Z.AI Coding Plan Responses route and exactly `ZAI_CODING_API_KEY`; `ZAI_API_KEY` is a separate General API credential and is never a fallback. Obsolete credential names are not recognized or rewritten.

## Built-in ChatGPT/Codex authentication

```bash
codex-mmo auth login
codex-mmo auth status
```

The base Codex home defaults to `~/.codex` and is configurable in `settings.toml`. It must expand to an absolute path; relative values are rejected so authentication and the Codex keyring namespace cannot vary with the caller's working directory. Generated homes receive file-backed `auth.json` using `auth_link_mode = "shared"` (the default symlink), `"copy"` (an explicit `0600` per-home copy), or `"none"`. Authentication is never copied into profile packs or snapshots.

Codex 0.149 scopes keyring entries to the canonical `CODEX_HOME` path. A login stored only in the base home's keyring is therefore not visible from an isolated generated home. Configure `cli_auth_credentials_store = "file"` in the base Codex configuration and log in again before using a built-in profile. `codex-mmo doctor` distinguishes a valid-but-keyring-only base login from file auth that the generated home can actually use.

## Local model example

The bundled Qwen profile expects an OpenAI-compatible llama.cpp server on `127.0.0.1:8001` with the stable model alias `qwen3.5-9b`. For a current llama.cpp installation, adapt this command to the local model path:

```bash
llama-server \
  --model /path/to/qwen3.5-9b.gguf \
  --alias qwen3.5-9b \
  --ctx-size 32768 \
  --jinja \
  --reasoning off \
  --no-mmproj \
  --host 127.0.0.1 \
  --port 8001
```

The upstream Qwen3.5-9B model card documents a native 262,144-token context, multimodal input, thinking, and tool use. The bundled `llama_cpp_local_openai_chat__qwen3_5_9b` entry is intentionally a smaller deployment contract: text-only, 32,768 total context, 8,192 advertised output, and no reasoning control. The explicit flags above make the current llama.cpp server match that resource-bounded contract; an operator who provisions more context or modalities should define a separately validated catalog entry.

Keep the endpoint on loopback unless it is separately authenticated and protected. llama.cpp flags can vary by version; its own help output is authoritative. The profile compiler validates declared capabilities, but the live smoke test is what proves the selected GGUF chat template and tool calling are usable.

## Initial validation

```bash
codex-mmo version
codex-mmo profile list
codex-mmo catalog inventory
codex-mmo tool-mcp validate
codex-mmo validate --all-profiles
```

Check the selected profile and provider path:

```bash
codex-mmo doctor --profile adaptive-engineering
codex-mmo doctor --profile adaptive-engineering --live
codex-mmo doctor --profile adaptive-engineering --live --probe
```

`--probe` performs a real root-model call and may consume quota. For a goal-mode root, the bounded probe exercises the real `update_goal(status="complete")` lifecycle before accepting the exact terminal marker.

## Live smoke test

Run from a small disposable Git repository or a repository you are comfortable exposing to the selected providers:

```bash
codex-mmo profile smoke adaptive-engineering --cwd "$PWD"
```

For a hybrid profile, smoke tasks explicitly select native and MCP paths where needed.

## Switching profiles

Changing the default affects new sessions only:

```bash
codex-mmo profile use adaptive-engineering
codex-mmo
```

Run a different profile once:

```bash
codex-mmo run --profile high-confidence-debugging
```

Running sessions remain pinned to their original immutable snapshot.

## Installing a profile pack

```bash
codex-mmo profile install ./my-profile
codex-mmo profile install ./my-profile.tar.gz
codex-mmo profile install ./my-profile.zip
```

Profile archives must contain exactly one `profile.toml`. Unsafe paths, symlinks, hard links, devices, scripts, unsupported files, and excessive nesting are rejected.

The profile must declare the exact active package version (`8.0.0`). Reinstalling identical content
is a no-op. Different current-generation content is rejected unless `--replace` is supplied; replacement
is staged, validated, and atomically selected. Profile installation has no upgrade, downgrade, or
migration path while this project is in active development.

A profile pack may refer to a Tool MCP server ID, but it cannot carry a server command or endpoint. Define and review that server first under `~/.config/codex-mmo/tool-mcp.d/`; profile validation rejects unresolved grants.

Clone a bundled profile before editing:

```bash
codex-mmo profile clone adaptive-engineering my-engineering-team
${EDITOR:-vi} ~/.config/codex-mmo/profiles.d/my-engineering-team/profile.toml
codex-mmo profile validate my-engineering-team
codex-mmo profile use my-engineering-team
```

## Catalog overlays

Add local models or endpoint overrides without modifying installed files:

```text
~/.config/codex-mmo/catalog.d/20-local.toml
```

Fragments use MMO schema 8 and are merged lexically. A later fragment can override an exact route, model, or resource entry.

Discover account-specific Codex models:

```bash
codex-mmo catalog refresh --install-codex-overlay
```

The generated overlay is:

```text
~/.config/codex-mmo/catalog.d/90-codex-discovered.toml
```

Remove it to return to the bundled baseline.

## Replacing the active development build

Run the current source installer with the same paths only after retiring active work. The installer:

1. Preserves user settings and credentials.
2. Validates the staged release.
3. Moves the old install to a state backup.
4. Atomically activates the new install.
5. Rewrites launchers to the new install path.

All MMO-owned documents use schema 8 and profiles require version `8.0.0`. The installer does not
rename `active-profile`, add retired aliases, parse earlier configuration or runtime records,
rewrite model keys, or migrate runtime state. Incompatible configuration must be recreated directly
in generation 8. If the preserved selection names a profile that no longer exists, choose a current
ID explicitly:

```bash
codex-mmo profile use adaptive-engineering
```

After replacement:

```bash
codex-mmo validate --all-profiles
codex-mmo catalog verify --remote --codex
```

Profile snapshots are addressed by content and package metadata. Any runtime document outside the
active schema/package generation is rejected at load time, including inspection and resume. Keep
historical evidence in an external/manual archive, not in the active sessions, jobs, snapshots, or
gateway directories. Canonical current sessions contain exactly one immutable run; terminal sessions
cannot be resumed.

## Uninstallation

Remove installed binaries and payload while preserving configuration and state:

```bash
codex-mmo-uninstall
```

Remove configuration:

```bash
codex-mmo-uninstall --purge-config
```

Remove state:

```bash
codex-mmo-uninstall --purge-state
```

Remove all three:

```bash
codex-mmo-uninstall --purge-config --purge-state
```

The package never removes Codex, Switchyard, npm, Cargo, provider accounts, or local model files.

Recursive removal requires the install's valid generation-8 ownership manifest. Explicit configuration, state, or binary roots must exactly match that manifest. When configuration or state is retained, the uninstaller writes a protected ownership record there so a later explicit purge remains possible after the payload itself is gone. A retained record is considered only while the recorded install path is absent; a successful fresh installation removes retained records because its live generation-8 payload manifest becomes authoritative. If the install path has been recreated independently, that live tree must carry its own valid manifest. An arbitrary, corrupt, or unrelated replacement `--install-root` is refused before any deletion.
