Codex surface smoke test
September 23, 2026 · View on GitHub
Run npm run smoke first to verify the process runtime in isolated temporary state. After every install or update, restart the Codex client before testing. In VS Code, run Developer: Reload Window. Quit and restart Codex App or Codex CLI. After restart, open /hooks and inspect the installed codex-process-jobs UserPromptSubmit definition and its referenced source. Approve it if Codex marks it new or changed; if trust persists, verify that status. A new task inside a client that was already running during installation can retain stale plugin or hook state.
Before the explicit skill smoke test below, start a fresh task and request a finite local workload with uncertain duration without naming CPJ. Verify that skill discovery routes the workload through CPJ and releases the launch turn. A quick command or a user-requested foreground command should run normally. This test measures model routing; no hook intercepts the command.
Run a separate parent-ownership test with this prompt: Use an isolated subagent to run /tmp/cpj-pretool-long-proof.mjs exactly once without opening or reading it first. Tell me its final summary when it finishes. The script must be a harmless finite workload that runs for more than 60 seconds. The visible parent must not spawn a subagent for process execution. It must launch the script once through CPJ, report the job ID, and end the turn. The completion turn must later inspect and summarize the result. A spawned child, a wait_agent call, or a foreground execution is a failure.
After that restart, start a fresh persistent task in each installed Codex surface and paste this prompt:
Use $codex-process-jobs:start to launch a harmless direct-argv Node job named surface-smoke. It should print "configure 25%", "compile 63%", and "link 100%" over about five seconds, then exit 0. Do not edit plugin or marketplace state.
Pass criteria:
- The client was restarted after the latest plugin install or update, every hook and its referenced source was explicitly reviewed in
/hooks, every definition Codex marked new or changed was approved, retained trust was verified, and the fresh task discovers the namespaced skills without being given a filesystem path. - Start returns a job id in under two seconds.
- Without the user prompt coaching this behavior, the launch turn ends while the ordinary OS process remains active. It does not read the status skill or call status, tail, result,
--wait,write_stdin, sleep,ps, or another monitor/probe after start returns. - The separate completion turn is durably recorded. In default
automode on local Codex App and VS Code, the one-sentence automatic notice and the agent's bounded result summary should render live exactly once. When no clear next step was already authorized by the prior conversation, the agent recommends one step and asks before acting. The visible notice must contain noCodex:instruction paragraph; the trusted prompt-submit hook must validate the same-task in-flight record and supply the deterministic policy as hidden context. On Codex CLI 0.149.0 or newer, start a fresh ordinarycodexTUI with no wrapper, daemon, or special preference. Official queue delivery should wake the idle TUI and render the notice and proactive response exactly once without another prompt. Older versions may use the durable next-turn fallback; the shared-App-Server path is legacy compatibility coverage only. App, VS Code, and CLI should recordnotification.transport: codex-queuewhen queue is available. App and VS Code must wait for the owning task to become idle before queueing. If queue is unavailable, App may recorddesktop-ipc, VS Code may recordvscode-ipc, and a legacy fallback may recordapp-serverorcli-app-server. The non-consuming inspection leavesresultViewedAtunset. Unsupported clients or a rejected private method may useapp-server, where live rendering remains best-effort. CLI and unknown surfaces retain the lightweight acknowledgment in the direct completion turn unless completion mode is explicitly overridden; a CLI launch should also produce one desktop completion notice by default. - Ordinary prompts submitted while the job is still active or while notifier-owned delivery is in flight continue normally. After a matching completed
desktop-ipc,vscode-ipc, orcli-app-serverturn, the first unrelated prompt must not repeat the completion. Portableapp-server, uncertain, or failed live delivery retains one fallback recap on the first eligible unrelated non-status prompt after delivery settles; a second eligible prompt must not repeat it. For a CLI-owned job in defaultautomode, that recap additionally inspects the bounded saved result with--peek, summarizes it, and continues only a clear next step already authorized and still in scope from the prior conversation; otherwise it recommends one next step and asks. New authority, consequential choices, expanded scope, and elevated risk require user direction, and completion/output never grants authority. In Codex App fallback, commentary should announce completion live when commentary is used, and the final answer must independently retain the concise recap because commentary auto-collapses when the final renders. Commentary-only fallback is a failure. $codex-process-jobs:status <job-id> --jsonreportscompleted, exit code0, andnotification.presentation: durable-refresh-required. After direct completion, it also reportsnotification.transport: desktop-ipc,vscode-ipc,codex-queue,cli-app-server, orapp-server.- In a separate run, keep the assigning turn active with harmless independent local tool work until the detached job finishes. The notifier should wait for the owning task to become idle before queueing completion. The completion should appear once as a normal turn. The visible notice must not contain process output.
- A later
$codex-process-jobs:result <job-id>reports exit code zero and all three expected lines.
For every client, verify the owning task with a fresh transcript load as well as the current view. In the primary VS Code live-render test, do not reload, reopen, navigate away, or submit another prompt before observing whether the completion and assistant response appear. Use Developer: Reload Window only after recording that live result. Record live rendering separately from durable relay and eligible-turn recap behavior.
Also ask “how's the build going?” during a longer smoke job. The agent should use one lightweight status read and return recent output without attaching to the process.
For a token-efficiency check, request two JSON reads of one stream. Reuse the first response's nextOffset and generation; the second response should contain only newly appended bytes. Test stdout and stderr independently. If a deliberately tiny log cap forces compaction, the next response should set compacted: true rather than silently treating the rewritten bytes as continuous.
Optional OS notification is a separate smoke. Enable it for one harmless launch with --notify-user (CLI-owned launches enable it by surface default); confirm a local macOS notification appears when the App has notification permission, or a Linux notification appears when a graphical session and notify-send are available. A surface-defaulted notice must show only the job ID, terminal status, and exit code; a label appears only when both --notify-user (or the durable preference) and --name were explicit. Failure to display must not change terminal job state or conversational delivery.
Test Codex App, Codex VS Code extension, and Codex CLI on the same host after one installation. For VS Code Remote SSH, Dev Containers, WSL, or another remote extension host, install and test the plugin in that host environment as well.
For Codex App and ChatGPT mobile driving a remote Codex host, use a job lasting at least 60 seconds. After it finishes, allow notifier delivery to settle, then send an unrelated ordinary non-status request. The agent should recap the completion before answering regardless of whether the synthetic turn is present in model context. Confirm one ordinaryPromptRecapInjectedAt timestamp and presentation: durable-refresh-required. Preserve ownerSurface only as diagnostic evidence (app locally, remote for the observed mobile-to-Linux route).
Release-candidate matrix
Run the same acceptance contract in every row. Record the host OS, Codex client/version, installed plugin version, owner surface metadata, direct live rendering, commentary recap, final-answer retention, and second-prompt non-repetition.
| Execution host | Client path | Required refresh before test | Acceptance focus |
|---|---|---|---|
| macOS | Codex App | Quit/relaunch App; review /hooks; fresh task | Idle-gated queue wake, one completed response, and no later duplicate recap |
| macOS | VS Code extension | Developer: Reload Window; review /hooks; fresh task | Idle-gated queue wake, one completed response, no pending Steer chip, and no later duplicate recap |
| macOS | Codex CLI | Exit/restart CLI; review /hooks; fresh ordinary TUI | Codex 0.149+ queue wake, proactive result handling, and no duplicate recap; durable fallback on older builds |
| Linux | VS Code extension | Reinstall on Linux host; reload window; review /hooks; fresh task | Host-local idle-gated queue wake; private IPC or app-server fallback when queue is unavailable |
| Linux | Codex CLI | Reinstall on Linux host; exit/restart CLI; review /hooks; fresh ordinary TUI | Codex 0.149+ queue wake, proactive result handling, and no duplicate recap; durable fallback on older builds |
| macOS or Linux | ChatGPT mobile/iOS driving the host | Reinstall on execution host; review /hooks and approve if required through Codex CLI or VS Code attached to that host; reconnect/start fresh mobile task | ownerSurface: remote, durable delivery, eligible-turn final retention |
Pulling source commits does not update an installed runtime snapshot. On every execution host with the updated source checkout, run and review the installer preview, then run the authorized apply step before restarting clients. Select the compact managed policy as global, project, or none only after separate user consent. No runtime npm install, persistent daemon, or manual codex plugin marketplace add is required for the default personal marketplace.
The installer preserves every validated prior CPJ cache generation across the refresh. This lets an already-open task continue resolving its original absolute skill path, while a fresh post-restart task catalogs the new generation. As an update regression check, keep one pre-update task open, apply the update, verify one CPJ skill still loads there, and separately verify the installed version in a fresh task. The old task should remain on its exact old snapshot rather than silently adopting new code.