Skip to content

Opening any review launches Codex: model discovery runs while the AI runtime is constructed #1144

Description

@rNoz

What happened?

Opening a plan, annotate, or code review builds the shared AI runtime, and the runtime calls every registered provider's fetchModels() while constructing itself. The Codex provider's implementation starts a throwaway codex app-server process, so opening a review executes Codex even when Ask AI is never opened and Codex is never selected.

The process is short lived and is cleaned up, so on most machines nothing is visible and this looks like nothing is wrong. It becomes visible when starting the Codex binary itself prompts: on macOS with a quarantined Homebrew payload that is a Gatekeeper confirmation dialog in front of the review that was actually requested. Even when it is invisible it is an unnecessary subprocess for a provider nobody selected.

This is a regression from #971 (2026-06-28), which moved the codex-sdk provider onto codex app-server. Before that commit the Codex provider had no fetchModels() at all, so runtime construction started no process. Anyone who used Plannotator before late June and saw nothing was not missing it: there was nothing to see.

The editor's automatic /api/ai/capabilities probe has the same effect, because it awaits the same discovery.

Reproduction, with no real Codex install needed. Any executable named codex on PATH shows the launch:

  1. Create a fake codex that records its invocation.

    mkdir -p /tmp/codex-probe
    printf '#!/bin/sh\necho "$@" >> /tmp/codex-probe/invoked.log\nsleep 30\n' > /tmp/codex-probe/codex
    chmod +x /tmp/codex-probe/codex
  2. With /tmp/codex-probe first on PATH, construct the shared AI runtime the way a review does, and do nothing else.

    const { createAIRuntime } = await import("./packages/server/ai-runtime.ts");
    await createAIRuntime({ cwd: process.cwd() });
  3. /tmp/codex-probe/invoked.log exists and contains app-server, before any review UI has loaded and before any AI session exists.

Observed on a pristine clone of main a54b46bb with its own bun install: {"afterConstruct":true,"afterCapabilities":true}, and the fake recorded the argument app-server. Repeating it with the real Homebrew binary (codex-cli 0.144.6) and a 60ms process poll caught /opt/homebrew/bin/codex app-server running during createAIRuntime(). Both packages/server/ai-runtime.ts and apps/pi-extension/server/ai-runtime.ts behave this way.

Expected: opening a review does not start Codex; the automatic capabilities probe stays metadata-only; Codex stays visible as an available provider on its static fallback model metadata; dynamic model and reasoning-effort discovery happens only after Codex is explicitly selected for a session, runs at most once per server, and on failure leaves the fallback in place rather than blocking the session; both runtimes behave the same.

Other providers are cheaper to probe and are not part of this report. The specific cost here is that Codex discovery spawns a process, so deferring only the provider whose discovery has a side effect keeps the change small.

Preconditions, for anyone trying to reproduce: a codex executable on PATH, and AI features enabled. With PLANNOTATOR_AI=disabled no runtime is built, so nothing launches.

Plannotator version

0.25.0 (reproduced from source at main a54b46bb).

OS

macOS. The eager launch is platform independent; the Gatekeeper dialog is the macOS-specific symptom.

Agent

Claude Code, but the launch happens for any agent: it is the shared AI runtime, and it fires whenever a codex executable exists on PATH.

Where did it happen?

Plan review, and equally annotate and code review, since all three construct the same runtime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions