# Codex Windows Fast Patch

> Reapply and repair Windows Codex Desktop after Store upgrades, including custom provider models hidden by Statsig available_models filtering, the dependent blue-purple Power slider and its Ultra toggle, Fast Mode request/UI gates, locale i18n, plugin UI gates, Chrome/browser_use gates, Goal command gates, Windows Computer Use availability gates and plugin/runtime repair, phone remote-control pairing under third-party/API-key main app usage, Desktop dynamicTools/inputSchema thread-start schema drift, local conversation visibility recovery after model_provider switches, restored-conversation missing-cwd continuation repair, ASAR integrity repair, signing/installing patched MSIX packages, SDK cleanup, Fast Mode wire verification, local plugin marketplace registration, and optional custom model_instructions_file setup.

- Skill: `chen0416ccc-cpu/codex-windows-fast-patch` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add chen0416ccc-cpu/codex-windows-fast-patch`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chen0416ccc-cpu/codex-windows-fast-patch/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: chen0416ccc-cpu (https://skillmd.com/u/chen0416ccc-cpu)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/chen0416ccc-cpu/codex-windows-fast-patch

---


# Codex Windows Fast Patch

Use this skill when the user says Codex Desktop was upgraded and the Fast Mode / Plugins / Goal patch disappeared, asks to repatch Codex on Windows, asks to verify whether Fast Mode is really being sent, asks to restore/register the local plugin marketplace, asks to enable Chrome browser use or Windows Computer Use in Codex Desktop, or asks to enable/repair phone remote control while keeping third-party/API-key model access. Also use it when a custom provider or `/v1/models` exposes a new model but Desktop still hides it, when GPT-5.6 Sol/Terra/Luna are missing from the model picker, when the compact blue-purple Power slider falls back to the legacy Model / Reasoning / Speed menu because Statsig `available_models` filtering removed the required model combinations, or when the "Ultra in model picker slider" setting is visible but disabled because a third-party provider cannot load ChatGPT account user settings. Also use it when the language/locale setting reverts after restart, browser or plugin entries are hidden by availability gates, the Computer Control settings page shows "Any App" / "任意应用" as disabled by organization or unavailable in the current region, a Computer Use task reports native pipe, bundled plugin cache, helper path, package import, or runtime initialization errors, phone remote-control QR pairing spins/fails, post-pairing phone-created turns hit the wrong model API endpoint, Desktop new-chat/thread start fails with `missing field inputSchema`, local conversations disappear after switching `model_provider` / API account, restored conversations are visible but cannot continue because the current working directory is missing, or the user explicitly asks to configure the bundled custom `model_instructions_file` prompt asset.

## Platform Compatibility

This skill is Windows-only. It depends on the Windows Store/MSIX package layout, PowerShell, `Get-AppxPackage`, `makeappx.exe`, `signtool.exe`, Windows user environment variables, and Windows Computer Use helper paths.

Do not run this skill on macOS. A macOS adaptation needs a separate workflow for the Codex `.app` bundle, ASAR extraction and repacking, macOS code signing or quarantine handling, shell scripts, and macOS-specific Computer Use availability.

## Skill Root

Every command in this document refers to the skill directory as `$SkillRoot`. Resolve it once per session before running anything else. This skill does not care which harness loaded it, so the probe matches any agent home that follows the `~/<agent-home>/skills/<skill-name>` layout:

```powershell
$SkillRoot = $env:CODEX_WIN_FAST_PATCH_SKILL_ROOT
if (-not $SkillRoot) {
  $SkillRoot = (Get-ChildItem -Force -Path "$env:USERPROFILE\.*\skills\codex-windows-fast-patch\SKILL.md" -ErrorAction SilentlyContinue |
                Select-Object -First 1).Directory.FullName
}
if (-not $SkillRoot) {
  throw 'skill root not found; set CODEX_WIN_FAST_PATCH_SKILL_ROOT to the directory that holds this SKILL.md'
}
```

If the agent already knows the directory it loaded this `SKILL.md` from, assign that path directly instead of probing. When more than one harness has the skill installed, set `CODEX_WIN_FAST_PATCH_SKILL_ROOT` to pick one explicitly; the probe otherwise takes the first match.

## Self-Update Preflight

The skill directory is a git working tree, so updating is `git pull`. Run the cheap check first and skip the rest when nothing changed:

```powershell
git -C "$SkillRoot" fetch --quiet origin
git -C "$SkillRoot" rev-list --count 'HEAD..@{u}'
```

Keep `'HEAD..@{u}'` single-quoted. PowerShell parses a bare `@{u}` as a hashtable literal and fails before git runs at all. `HEAD..origin/HEAD` is equivalent here and needs no quoting.

A count of `0` means the skill is current: skip the update and start the task. For a non-zero count, read what actually changed, then pull, then reload this `SKILL.md`:

```powershell
git -C "$SkillRoot" log --oneline 'HEAD..@{u}'
git -C "$SkillRoot" pull --ff-only
```

If `@{u}` reports no upstream configured, substitute the tracking ref explicitly, for example `HEAD..origin/main`.

Rules:

- Never block the repair on the update. When `fetch` fails because the network is unavailable, GitHub is unreachable, or a proxy is down, continue with the installed version and state in the conclusion that the update was skipped.
- Local edits are preserved by git, not silently discarded. Inspect with `git -C "$SkillRoot" status --short` and `git -C "$SkillRoot" diff` before pulling. Uncommitted edits to files the update does not touch survive `git pull --ff-only` untouched. Uncommitted edits to a file the update also changes make git refuse the pull, name the blocking file, and leave the edit on disk; recover with `git stash`, `git pull --ff-only`, `git stash pop`, and expect `stash pop` to leave conflict markers when the local edit and the upstream change touch the same lines. Local commits make `--ff-only` refuse because the branches diverged; `git pull --rebase` replays them on top of the update. Never use `git reset --hard` or `git checkout -- .` to force a pull through, because local helper profiles and repair guards live in those edits.
- A fork is just a different remote. `git -C "$SkillRoot" remote set-url origin <fork-url>` pins the update source, and no extra configuration file is involved.
- Roll back with git. `git -C "$SkillRoot" log --oneline -10`, then `git -C "$SkillRoot" checkout <sha>` returns to any earlier version.
- When a patch step fails, check for updates again before concluding. A missing helper profile, a pattern that no longer matches, or an unrecognized Desktop build is exactly the case where upstream may already carry the fix, so repeat the fetch and log check at that point even if it already ran at the start of the task.
- If `$SkillRoot` has no `.git` directory, the copy was installed by copying files or through a harness plugin mechanism and can never self-update. Report that, keep working with the installed version, and suggest reinstalling with `git clone` so future updates work.

If the normal workflow does not explain a restriction, plugin gate, Computer Use failure, browser_use failure, or Fast Mode failure, read `references/restriction-debug-cases.md` before editing scripts or repatching.
If the task is phone remote control, QR pairing, mobile setup, isolated remote OAuth, remote-control WebSocket, or post-pairing API endpoint diagnosis, read `references/remote-control-debug-cases.md` before editing scripts or repatching.

## Config Backup Rule

Before any action that can modify, regenerate, or overwrite `$env:USERPROFILE\.codex\config.toml`, create one timestamped backup of the current file for the task. This applies whether the agent uses bundled scripts, writes TOML manually, runs another helper, registers a marketplace, changes MCP servers, or repairs Computer Use.

The bundled scripts already back up an existing `config.toml` once per script run before their first write. If not using those scripts, do the backup explicitly before touching the file:

```powershell
$config = Join-Path $env:USERPROFILE '.codex\config.toml'
if (Test-Path -LiteralPath $config -PathType Leaf) {
  $backupDir = Join-Path (Split-Path -Parent $config) 'backups\config'
  New-Item -ItemType Directory -Force -Path $backupDir | Out-Null
  $backup = Join-Path $backupDir ('config.toml.' + (Get-Date -Format 'yyyyMMdd-HHmmss-fff') + '.manual.bak')
  Copy-Item -LiteralPath $config -Destination $backup -Force
  Write-Host "config.toml backup before overwrite: $backup"
}
```

Do not proceed with a config write if the backup of an existing config fails. After writing, validate TOML syntax with `tomllib` when Python is available.

## Workflow Selection

Before choosing the full MSIX repack path, identify whether the current failure is a Desktop bundle gate or a local plugin/runtime repair. Do not treat a vague "Chrome/Computer Use is unavailable" report as enough evidence to run the full repatch.

- Use the Model Experience workflow for Fast Mode request/UI failures, new models hidden from the Desktop picker, the compact Power slider falling back to the legacy picker, or its Ultra setting being disabled under a custom provider. These symptoms share the same service-tier/model-picker area. Run `scripts\patch_codex_fast_mode_windows_msix.ps1 -OnlyModelExperience -DryRun` first; it checks the Fast request gate, Fast UI gate, model visibility filter, Electron Power slider `harborEnabled` gate, and Ultra setting persistence independently, then repairs only the broken parts in one MSIX repack. The Ultra fallback preserves the normal ChatGPT account API path and uses local `show-ultra-in-model-picker-slider` config only when ChatGPT user settings cannot load. `-OnlyCustomModels` remains a compatibility alias. Merge missing model metadata into `models_cache.json` only when read-only inspection proves the cache entry is absent; back up the cache first. The same area also covers the model picker offering only the Fast speed tier when the official catalog adds a second `ultrafast` tier for `gpt-5.6-sol` and a custom `model_catalog_json` predates it; that is a config-layer catalog backfill, not an ASAR repair — see the missing Ultrafast tier case in `references/restriction-debug-cases.md`.
- Use the full repatch workflow for locale, plugin UI gates, browser_use Desktop gates, Goal gates, ASAR integrity, settings/UI availability gates, or when Model Experience repair is required together with those features.
- Before a full repatch after a Store update, compare the current-user and `Get-AppxPackage -AllUsers` results. The patcher selects the highest-version valid current-user or SYSTEM-Staged package, plus running-process candidates; it uses WindowsApps-directory candidates only if the all-user query is unavailable. This prevents an older user-installed package from hiding a newer SYSTEM-Staged build without selecting a package registered only to another user. Check the `selected Codex app` log before proceeding. Use `-AppPath` only when an explicit source override is required.
- Use the Computer Use Only workflow first when evidence points to a local plugin/runtime problem: `codex plugin list` marketplace errors, missing `.agents\plugins\marketplace.json`, missing or partial `openai-bundled` plugin files, `bundled_plugins_marketplace_resolve_failed`, `EBUSY` on bundled plugin files, native pipe unavailable, `missing-helper-path`, stale Chrome native messaging host paths, bundled plugin cache drift, Chrome/browser cache link drift, stale `SKY_CUA_NATIVE_PIPE` config, `@oai/sky` import errors, or `setupComputerUseRuntime` import failure. This class does not require an MSIX uninstall/reinstall unless a later check also proves a Desktop gate is still closed.
- If a Store update breaks an already-configured MCP because its `command` points into a removed `%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\<old-runtime-id>` directory, use the retired CUA Node MCP case in `references/restriction-debug-cases.md`. This is a targeted `config.toml` repair, not evidence for a broad MSIX repatch or permission to install additional MCP servers.
- If app/window enumeration works but the first screenshot fails with `SetIsBorderRequired failed` and `0x80004002` on Windows 10, treat it as a native CUA screenshot-helper compatibility failure, not a cache path or Desktop gate. Read `references/win10-computer-use-screenshot-backend.md`, then use `scripts\patch-computer-use-helper-win10.ps1` only when its read-only status reports the exact supported original or patched hash. Unknown hashes require fresh analysis and must remain untouched.
- If `sky.list_windows()` succeeds but a later independent `sky.get_window_state()` or `sky.activate_window()` call fails with `node_repl exec context not found`, read the cross-call approval case in `references/restriction-debug-cases.md`. On the exact documented `@oai/sky 0.6.2` helper transport, the persistent helper's approval callback can inherit the previous JavaScript call's `AsyncLocalStorage` store. `install-computer-use-local.ps1 -VerifyOnly` applies the hash-guarded request-context patch; `-StrictVerifyOnly` only verifies it. Reset the current JavaScript kernel after repair, then prove the fix with real captures in later independent calls.
- Use the Phone Remote Control workflow when the user needs mobile pairing/control, the Connections page hides the phone setup card, the QR dialog spins, remote-control setup jumps to ChatGPT auth, the Allow dialog fails, the phone says the Codex environment version expired, or phone-created turns reach Desktop but send model requests to the wrong API endpoint.
- Use the Missing inputSchema decision workflow when Codex Desktop cannot create a new conversation or local task and the newest Desktop log reports `method=thread/start` with the phrase `missing field inputSchema`. Do not assume this is always MCP. First compare CLI/app-server smoke tests against Desktop logs and inspect whether Desktop is sending non-null app dynamic tools. If the failure follows a suspect MCP server, isolate MCP. If CLI thread start succeeds while Desktop UI fails and extracted ASAR has `webview\assets\app-server-dynamic-tools-*.js` returning a namespace-wrapped `dynamicTools` object, use the Dynamic Tools Schema workflow. Do not run Phone Remote Control or Computer Use repair for this symptom unless separate evidence points there.
- Use the Provider History Sync workflow when old conversations disappear from the official Desktop sidebar after the user changes `model_provider`, API account, or provider config, but local `sessions`, `archived_sessions`, or `state_5.sqlite` data still exists. Also use it when the conversations reappear but opening/continuing one fails with `当前工作目录缺失`, `current working directory missing`, or `invalid codex request` caused by a missing historical `cwd`. This workflow is data-layer repair; it does not require third-party recovery tools, does not patch ASAR, and must not modify `config.toml`.
- Use the targeted bundled marketplace repair when the newest Desktop logs show fewer descriptors than the current package marketplace, or show `not_in_bundled_marketplace_plugin_names` removing a plugin the user had already installed. Descriptor presence means a plugin is available; it does not authorize installing or enabling optional plugins such as `sites`, `latex`, `deep-research`, or `visualize`. This should not trigger a broad repatch or Phone Remote Control workflow. First rule out an account-gated descriptor gap: when the only missing descriptors are ones whose `isAvailable` predicate reads an account feature flag, such as `unified-computer-use` (`browserUseTinysky`) and `user-writing` (`userWriting`), the smaller set is expected on a third-party provider or API-key account and must not be repaired. Read the account-gated bundled descriptor case in `references/restriction-debug-cases.md` first.
- If the user asks for Phone Remote Control and ordinary Desktop features in the same repair, patch Phone Remote Control first, then verify Fast Mode/browser/Chrome/Computer Use. If the remote-control MSIX install disturbs Computer Use or Chrome native-host state, immediately run the Computer Use Only workflow and re-run `-StrictVerifyOnly`.
- Do not infer that a new `resources\codex.exe` PE file means `app.asar` is gone or that Computer Use needs binary patching. Inspect the current package resources first. If `app.asar` still exists and the symptom is a plugin/runtime import or cache failure, run `scripts\install-computer-use-local.ps1` before considering MSIX or binary changes.
- After a Computer Use-only repair, always run `scripts\install-computer-use-local.ps1 -StrictVerifyOnly`. Legacy layouts pass with `client import ok` plus `helper transport ok`; descriptor-only layouts pass with `runtime import ok` after importing the official `sky` export and calling `list_windows`. For a recognized cross-call request-context profile, strict verification must also report the exact patched helper-transport hash. These checks still do not replace a real screenshot in a later JavaScript call.
- Do not put Phone Remote Control into the default full repatch path unless the user asked for it. It is an opt-in workflow because it can require isolated remote-control OAuth, ASAR changes, a native app-server replacement binary, SQLite enrollment cleanup, and post-pairing API endpoint diagnosis.
- If evidence is mixed, use the lowest-disruption path first: run read-only triage, then `scripts\install-computer-use-local.ps1 -VerifyOnly` for local plugin evidence, restart Codex Desktop only if needed, and escalate to MSIX only when logs or extracted ASAR checks still show a closed gate.

The normal `scripts\repatch-codex-windows.ps1` preflight recognizes one package-gated Computer Use case: `installed app.asar does not preserve external NODE_REPL_TRUSTED_CODE_PATHS across Desktop config regeneration`. This means the installed app must be repatched before external D: marketplace/cache roots can survive Desktop config regeneration. For this exact message only, the wrapper records the fallback and continues into its MSIX dry run or install; unrelated Computer Use failures still stop the workflow. After installation, the wrapper runs the normal Computer Use refresh and strict verification. During a dry run, post-dry-run local verification is skipped only for this recognized case because the currently installed package is intentionally still unpatched.

## External Executor For Desktop-Restarting Repairs

If a repair can stop, uninstall, reinstall, repackage, or relaunch Codex Desktop, do not run it from the Codex Desktop session being repaired. Use an external Windows PowerShell session, the VS Code Codex extension, or another agent environment that will survive the Desktop restart.

The target state is the Desktop Codex home: normally `$env:USERPROFILE\.codex`. Do not use an isolated CLI entrypoint for Desktop repair decisions; if that wrapper sets `CODEX_HOME` to `$env:USERPROFILE\.codex-cli` or another isolated directory, it is not the Desktop plugin, marketplace, MCP, remote-control, or login state.

Before starting from VS Code Codex or external PowerShell, confirm no User-level or Machine-level `CODEX_HOME` is set. Do not set global `CODEX_HOME`, do not copy `.codex` into `.codex-cli`, and do not expose or commit `auth.json`, API keys, OAuth tokens, MCP credentials, browser profiles, or local credential stores. Start with a Desktop-state backup, run read-only package/config/log checks, then run the relevant `-DryRun`. Only use `-Install`, full `repatch-codex-windows.ps1`, or targeted `*-windows-msix.ps1 -Install -Launch -InstallPrerequisites` after the dry run finds and validates the intended targets.

An external executor has no Desktop `node_repl` JavaScript kernel, so the normal real-acceptance path for Computer Use and Chrome is unavailable. Do not downgrade acceptance to `-StrictVerifyOnly` output alone, and do not claim an end-to-end result the environment cannot produce. Drive the official CUA runtime from separate short-lived `node.exe` processes for read-only Computer Use calls, keep a capture and any `element_index` input that consumes it inside one long-lived process, and report the Chrome/browser layer as gate-and-configuration verified with the tab-read smoke test explicitly not run. The external-executor Computer Use acceptance case in `references/restriction-debug-cases.md` gives the required load order, object shapes, approval stub, `CODEX_CLI_PATH` prerequisite, and the benign input call that turns a read-only probe into acceptance.

## Default Workflow

1. If the task may modify `config.toml`, skills, marketplaces, or MCP server settings, create a state snapshot first:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\manage-codex-backups.ps1" -Action Backup
```

2. Inspect current-user and all-user package status so a newer SYSTEM-Staged Store build is visible:

```powershell
Get-AppxPackage -Name OpenAI.Codex | Select-Object Name,PackageFullName,Version,SignatureKind,InstallLocation
Get-AppxPackage -Name OpenAI.Codex -AllUsers |
  Select-Object Name,PackageFullName,Version,SignatureKind,InstallLocation,PackageUserInformation
```

The MSIX patcher automatically chooses the highest-version candidate whose `app` layout is complete, even when the current-user query returns an older installed build. Confirm its `selected Codex app` and `source package` log lines before installation. An explicit `-AppPath` remains authoritative.

3. Run read-only feature triage before any package reinstall. Capture the decision evidence, especially for Chrome/Computer Use:

```powershell
codex plugin list
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\install-computer-use-local.ps1" -StrictVerifyOnly
```

If `-StrictVerifyOnly` fails on a missing marketplace manifest, missing plugin files, stale `latest` link, stale Chrome native messaging manifest path, `allowed_origins`, registry value, or `extension-host-config.json` runtime path, missing helper path, or `@oai/sky` import/runtime issue, run the Computer Use Only repair first:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\install-computer-use-local.ps1" -VerifyOnly
```

This local repair may update config, plugin cache, Chrome native host paths and origins, user environment, and helper runtime files, but it does not uninstall or reinstall the Codex MSIX package. It invokes the current Chrome plugin's official `scripts\installManifest.mjs` with a user-local Codex CLI whose hash matches the installed package and with matching current `cua_node` `node.exe` / `node_repl.exe` paths. That official installer writes the outer native-host manifest, registry value, and required `extension-host-config.json`. The repair also synchronizes the current schema-2 app-server entry into both `%LOCALAPPDATA%\OpenAI\Codex\chrome-native-hosts-v2.json` and `$env:USERPROFILE\.codex\chrome-native-hosts-v2.json` using the current plugin's NUL-separated SHA-256 identity contract. Strict verification requires the exact current origin set from `scripts\extension-ids.json`, a stable current-version Chrome cache, existing current runtime paths in the host config, and a valid current entry in both v2 state files. On `26.814`-style builds, that entry must include both `browserClientPath` and `browserServicePath` in the same stable cache; omitting the service path passes byte checks but fails the trusted RPC dependency gate. When the stable cache resolves through a junction outside `CODEX_HOME`, the repair also writes its physical marketplace/cache roots to the user-level `NODE_REPL_TRUSTED_CODE_PATHS`. A full MSIX patch is still required so Desktop appends that parent environment value when regenerating the Node REPL config; strict verification requires `CODEX_NODE_REPL_TRUSTED_PATHS_V1` in the installed ASAR for this external-root layout.

The repair must preserve the installed package's `plugins\chrome\scripts\browser-client.mjs` bytes exactly. Earlier Node REPL builds expose privileged browser capabilities only when the imported browser-client SHA-256 matches the trust list embedded in the installed `app.asar`; rewriting a `node:process` import or process shim changes the hash and causes `Browser use requires privileged node_repl capabilities` before Chrome discovery. Codex Desktop `26.814` instead delivers `browserClientPath` through the official native-host configuration and no longer embeds the client hash as ASCII in `app.asar`. Normal repair restores the packaged bytes to both the stable marketplace and versioned cache. Strict verification requires both copies to match the packaged SHA-256 and then requires either the legacy ASAR hash or the complete native-host path contract; an unknown or partial shape remains unsupported.

4. Before choosing a full MSIX repack, check whether this is the bundled marketplace fast path. Compare the package's `.agents\plugins\marketplace.json` names with the Desktop reconcile log. If descriptors are missing, or `not_in_bundled_marketplace_plugin_names` removes a plugin the user had already installed, run only the targeted bundled marketplace patch on a large local drive:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\patch_codex_fast_mode_windows_msix.ps1" -OnlyBundledMarketplaceCopy -DryRun -OutputRoot "<large-local-build-root>"
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\patch_codex_fast_mode_windows_msix.ps1" -OnlyBundledMarketplaceCopy -Install -Launch -InstallPrerequisites -CleanupAfter -CleanupWindowsSdkAfterInstall -OutputRoot "<large-local-build-root>"
```

After relaunch, run `scripts\install-computer-use-local.ps1 -VerifyOnly` and `scripts\install-computer-use-local.ps1 -StrictVerifyOnly -VerifyAllBundledPluginsAvailable`. The local repair preserves each unrelated optional plugin's installed/enabled state and refreshes an optional cache only when that plugin was already installed. The availability check requires every current descriptor name and version to match the installed package and to appear with that version in the CLI's installed-or-available JSON without calling `plugin add`.

5. Escalate to MSIX only when the evidence points to package-gated Desktop code: Fast Mode request/UI gates, locale gate, Goal/plugin UI gate, browser_use availability with `reason=statsig-disabled`, Computer Use/Any App disabled by settings/UI availability gates after local repair, ASAR integrity failure, a stable Browser cache junction whose physical target is rejected by the trusted RPC dependency gate after local repair, or Phone Remote Control package patches. For the junction case, require the full patcher's `Node REPL trusted-paths patch result`, restart Desktop, and confirm the regenerated config retains the resolved external roots. Otherwise do not run the full repatch just because a plugin is unavailable.

Run a dry run first after every Codex upgrade when MSIX escalation is justified:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\repatch-codex-windows.ps1" -DryRun
```

6. If the dry run finds all patch targets, run the full repatch:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\repatch-codex-windows.ps1"
```

The wrapper calls the bundled patch script at `scripts\patch_codex_fast_mode_windows_msix.ps1` with these defaults:

- `-InstallPrerequisites`
- `-Install`
- `-Launch`
- `-CleanupWindowsSdkAfterInstall`
- `-CleanupAfter`
- `-VerifyFastModeRequest`

It also verifies and writes the local marketplace config at `$env:USERPROFILE\.codex\marketplaces\openai-curated-local`, including `source_type = "local"` and the exact `source` path.
It also syncs the installed `openai-bundled` marketplace from the current Codex package into a stable local root, overlays a local `computer-use@openai-bundled` compatibility plugin, writes that marketplace into config, and registers `browser@openai-bundled` through the user-accessible Codex CLI. Pass `-VerifyAllBundledPluginsAvailable` to add an availability assertion for every complete descriptor currently offered by the installed package, including version-dependent plugins such as `deep-research` and `visualize`. The assertion itself uses `plugin list --available --json`; it does not download from the network, call `plugin add`, or change unrelated optional plugin state. The surrounding wrapper still performs its requested repair or DryRun behavior. When `.codex\.tmp` is a junction, the stable root is created beside the junction target so an existing non-system-drive layout stays off C:; otherwise it uses `.codex\marketplaces\openai-bundled-local`. It also repairs stable `browser` / `chrome` plugin cache copies so their `latest` junctions do not point at the mutable `.tmp` marketplace mirror, and enables `CODEX_ELECTRON_ENABLE_WINDOWS_COMPUTER_USE=1` for the current user so the Desktop app can expose Windows Computer Use after restart.
It patches Fast Mode in both the request path and the settings UI path. The request patch removes the ChatGPT-only branch while still reading host/model feature requirements; the UI patch removes the matching ChatGPT-only availability check in service-tier settings.
It also forces the configured custom model IDs through the Desktop model visibility filter. By default these are `gpt-6-astra`, `gpt-5.6-sol`, `gpt-5.6-terra`, and `gpt-5.6-luna`. This patch only unhides catalog entries that already exist for the current build; it never creates one. A slug the active catalog does not contain stays absent from the picker no matter how often the bundle is repatched, so confirm the entry exists before reading a missing model as a patch failure. The CLI builtin catalog is embedded in `codex.exe` and ships not-yet-rolled-out models with `"visibility": "hide"`, which is exactly the shape this patch is for; a user `model_catalog_json` replaces that builtin catalog instead of extending it, so it must carry the new entry itself. On builds containing the compact Power slider, it also opens the Electron-specific `harborEnabled` gate so the matching GPT-5.6 model and reasoning combinations use that slider instead of the legacy model/effort/speed-only menu.
On builds where the Ultra slider setting reads only ChatGPT account user settings, it adds a local fallback for third-party providers. The toggle then reads and writes `show-ultra-in-model-picker-slider` locally, survives restart, and feeds the same Ultra inclusion value used by the actual model picker. Normal ChatGPT-authenticated users retain the official account setting path.
It patches the locale i18n gate that can force the Desktop UI back to English after restart when `enable_i18n` is disabled in the shipped webview bundle.
It patches Chrome/browser_use gates in both the webview assets and the main Electron feature sender/receiver path, covering in-app browser, browser pane, and external browser availability. This only unlocks the local Desktop gates; Chrome extension and native messaging files still need to exist and should be verified separately.
It also patches the Desktop webview gates that otherwise hide or disable Windows Computer Use behind the `computer_use` experimental feature and Statsig gate `1506311413`, and it writes `features.computer_use = true` into `$env:USERPROFILE\.codex\config.toml` without replacing the rest of the `[features]` table.
It also writes `[windows] sandbox = "unelevated"` into `$env:USERPROFILE\.codex\config.toml`. On Windows, this avoids the elevated sandbox setup refresh path that can fail with `spawn setup refresh` / OS error 740 and break Computer Use startup.
It also repairs local marketplace manifest layout when a local root has only a legacy root `marketplace.json`; the current Codex CLI expects `.agents\plugins\marketplace.json`, and missing that file can make `codex plugin list` fail for all configured marketplaces.
It does not install the bundled custom `model_instructions_file` prompt by default. Only install it when the user explicitly requests that optional configuration.
Any bundled script write to an existing `config.toml` first creates one timestamped backup for that script run under `.codex\backups\config\`.

## Phone Remote Control

Before repairing phone remote control, read `references/remote-control-debug-cases.md`. Keep these boundaries explicit:

- Remote-control pairing/control transport can legitimately call `https://chatgpt.com/backend-api/wham/remote/control/...`. Do not rewrite that transport to a third-party model API endpoint.
- After phone pairing works, verify the actual model sampling request URL. If it goes to the wrong model API endpoint, treat that as a post-pairing configuration diagnosis, not as part of the remote-control pairing implementation.
- Remote-control OAuth is isolated: use `.codex\remote-control-oauth.json` and `.codex\remote.json`; never use `.codex\auth.json` for the remote-control bearer injection path.
- An alternate build root is mandatory when the user says not to consume the system drive. Pass `-WorkRoot` / `-OutputRoot` on the requested large local drive and keep Cargo, Rustup, temp, target, MSIX, and source checkout under that root. Do not hard-code a drive letter into the workflow.

If `Settings -> Connections -> Control this computer` is visible but the device list says to sign in to ChatGPT again, verify the normal remote-control bearer before repatching MSIX again:

```powershell
python "$SkillRoot\scripts\refresh-remote-control-auth.py" --verify-only
```

If that reports `remote_json_disabled`, `access_token_expired`, `endpoint_http_error`, HTTP 401/403, or a token-refresh diagnosis such as `refresh_token_reused`, regenerate only `.codex\remote.json` with the same script. It uses the official Codex OAuth client, requests `openid profile email offline_access api.connectors.read api.connectors.invoke`, backs up the old `remote.json` under `.codex\backups\remote-control-auth`, defaults to proxy `http://127.0.0.1:10808`, and must not write `.codex\auth.json` or `config.toml`.

If `remote.json` verifies successfully but clicking `Add` or opening `Control this computer` falls back to a new conversation/main chat page, inspect `$env:USERPROFILE\.codex\remote-control-flow.log` and direct endpoint results for an expired `remote-control-oauth.json` enroll token shadowing the normal bearer. The ASAR patcher must skip expired JWTs before returning an isolated bearer and should verify `remote_control_auth_token_expired_skipped` in the patched ASAR. Do not delete `.codex\remote-control-oauth.json` blindly; keep it for fresh step-up/enroll flows and let valid `.codex\remote.json` satisfy read/MFA endpoints.

If the Allow dialog fails and the newest native app-server logs show `remote control requires ChatGPT authentication; API key auth is not supported`, ASAR patches and `.codex\remote.json` refresh are not enough. Build a patched native `app\resources\codex.exe` from the Codex Rust source with the reference native patch, using a large non-system work root when requested:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\build-remote-control-native-replacement.ps1" -WorkRoot "<large-local-build-root>\native-remote"
```

If the phone reports the Codex environment is expired after a native replacement, inspect the original installed native version before building. Use only an exact mapped Desktop/native/source-tag combination. For example, Desktop `26.715.2305.0` ships `codex-cli 0.145.0-alpha.18` and Desktop `26.707.3748.0` ships `codex-cli 0.144.0-alpha.4`:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\build-remote-control-native-replacement.ps1" -WorkRoot "D:\CodexData\rc145" -CodexSourceRef "rust-v0.145.0-alpha.18" -AppServerVersion "0.145.0-alpha.18"
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\build-remote-control-native-replacement.ps1" -WorkRoot "D:\CodexWork\phone-remote-26.707\native-remote-0.144.0-alpha.4" -CodexSourceRef "rust-v0.144.0-alpha.4" -AppServerVersion "0.144.0-alpha.4"
```

The build helper keeps the clone, Cargo cache, Rustup cache, temp directory, target directory, and any bootstrapped Windows SDK packages under `-WorkRoot`. When `-CodexSourceRef` and `-AppServerVersion` are omitted together, it copies the installed WindowsApps `app\resources\codex.exe` into `WorkRoot\tmp`, runs `--version` only on that copy, and selects a bundled version mapping; it never executes the WindowsApps binary in place. Desktop `26.715.2305.0` maps to `rust-v0.145.0-alpha.18`, `references\remote-control-native-replacement-0.145.0-alpha.18.patch`, and workspace version `0.145.0-alpha.18`. Desktop `26.707.3748.0` maps to `rust-v0.144.0-alpha.4`, `references\remote-control-native-replacement.patch`, and workspace version `0.144.0-alpha.4`. For historical `rust-v0.142.4`, matching parameters select `references\remote-control-native-replacement-0.142.4.patch`; that patch has passed clean patch-apply validation, but has not yet completed the same end-to-end native compilation validation as the newer mappings. Other source versions require matching explicit version parameters plus a validated `-PatchPathOverride`. Do not use GNU toolchain output for Windows MSIX replacement; use the MSVC target.

If MSVC is present but `kernel32.lib` is missing, the helper first searches for one coherent existing Windows SDK root/version containing matching x64 `kernel32.lib`, `ucrt.lib`, and headers; it does not mix independently discovered installed SDK versions. Only when no usable SDK exists, it downloads `Microsoft.Windows.SDK.CPP` and `Microsoft.Windows.SDK.CPP.x64` version `10.0.26100.4188` into `<WorkRoot>\cache\windows-sdk-cpp`. Downloads use `.partial` files, validate the archive and expected payloads, and replace the cache only after validation; corrupt cached packages are deleted and downloaded again. On Windows PowerShell 5.1, extract NuGet packages with checked `tar.exe`; `Expand-Archive` can fail while cleaning a deep `_rels\.rels` tree. The two packages use a split layout, so accept the matching NuGet roots `c\um\x64\kernel32.lib`, `c\ucrt\x64\ucrt.lib`, `c\Include\<version>\um\Windows.h`, and optionally `c\bin\<version>\x64\rc.exe` instead of requiring one traditional installed-Kits tree. Downloads honor existing `HTTPS_PROXY` / `HTTP_PROXY`; when neither is set, the helper uses `http://127.0.0.1:10808` only if that port is listening, otherwise it downloads directly.

Keep `-WorkRoot` short as well as off the system drive. A deeply nested D-drive root can still fail while Cargo checks out Git dependencies with `path too long`; the validated `0.145.0-alpha.18` build succeeded under `D:\CodexData\rc145`. When retrying after an interrupted or timed-out external run, first confirm the child PowerShell process has exited and use a unique `WorkRoot` / `OutputRoot`; a timed-out parent can leave a child cleaning the previous root.

Run a dry run first. Do not pass `-KeepWorkDir` unless you need to inspect failed patch artifacts; successful dry-runs should clean generated package and ASAR extraction output:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\patch-remote-control-windows-msix.ps1" -DryRun
```

If the machine needs a larger temporary build location, pass it explicitly:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\patch-remote-control-windows-msix.ps1" -DryRun -OutputRoot "<large-local-build-root>"
```

If a patched native `app\resources\codex.exe` was built from the Codex Rust source, pass it explicitly:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\patch-remote-control-windows-msix.ps1" -DryRun -ReplacementResourceCodexExe "<path-to-built-codex.exe>"
```

Only after dry-run markers pass, install and relaunch:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$SkillRoot\scripts\patch-remote-control-windows-msix.ps1" -Install -Launch -InstallPrerequisites -ReplacementResourceCodexExe "<path-to-built-codex.exe>"
```

When `makeappx.exe` / `signtool.exe` are missing, the install path downloads Windows SDK BuildTools from NuGet under `-OutputRoot\.remote-control-temp`, not `%TEMP%`. Do not hard-code a local proxy for this download. Use the default direct/env-proxy path first; only pass `-BuildToolsProxy "http://127.0.0.1:10808"` or set `CODEX_WINDOWS_SDK_BUILDTOOLS_PROXY` when that proxy is known to be listening. Proxy URIs and credentials are never printed. `curl download failed with exit code 7` usually means the selected proxy endpoint refused the connection.

Run disruptive install commands from an externa

…(truncated)
