Skip to content

feat: add --ephemeral flag to task to avoid polluting Codex Recent - #779

Open
0dimen wants to merge 1 commit into
openai:mainfrom
0dimen:ephemeral-task-flag
Open

0dimen wants to merge 1 commit into
openai:mainfrom
0dimen:ephemeral-task-flag

Conversation

@0dimen

@0dimen 0dimen commented Sep 22, 2026

Copy link
Copy Markdown

Problem

Codex Companion's task command always creates a persistent Codex
thread, and this behavior is not changed by this PR — task still
persists by default.

For large or parallel fire-and-forget task runs — especially agent
orchestration workloads that dispatch many independent subtasks —
each task invocation shows up as its own persistent thread in
ChatGPT/Codex Recent, even when the caller only wants the result and
never resumes that particular thread. Persistent history is
unnecessary overhead in that case.

Solution

Add an opt-in --ephemeral flag to task. Existing task
behavior is unchanged.

Existing:
task ...
→ persistent (behavior unchanged)

New:
task --ephemeral ...
→ non-persistent Codex execution

This is a minimal change that reuses the existing persistence
architecture — runAppServerTurn's persistThread option, which
already maps directly to the app-server's ephemeral thread param —
rather than introducing a new thread/session abstraction.

Backward compatibility

  • Omitting the flag is byte-for-byte the same code path as before;
    existing task behavior is unchanged.
  • --ephemeral is strictly opt-in.
  • --resume / --resume-last are untouched and keep working exactly
    as before for persistent tasks.
  • --ephemeral combined with --resume/--resume-last is rejected
    with an explicit error — this combination is contradictory, since an
    ephemeral thread was never persisted and cannot be resumed.
  • Job records now carry an ephemeral bit so findLatestResumableTaskJob
    never offers an ephemeral run as a --resume-last candidate, and so
    status/result rendering stops suggesting codex resume <id> for a
    thread that was never persisted.

Tests

All 6 newly added tests pass:

  • ephemeral does not persist a thread
  • default task remains persistent (unchanged)
  • 3 concurrent ephemeral tasks stay independent, 0 persistent threads
  • ephemeral + --resume rejected
  • ephemeral + --resume-last rejected
  • an ephemeral task cannot subsequently be resumed via --resume-last

Also manually verified against a real Codex CLI (0.155.1, logged-in
ChatGPT account), reading ~/.codex/state_5.sqlite for a scratch
cwd's persistent thread count:

  • task --ephemeral: +0
  • task (no flag): +1
  • task --resume-last: +0 (resumes the same thread, context intact)
  • 3 concurrent task --ephemeral: +0 more
  • task --ephemeral --resume-last: validation error, +0

sqlite was used only for read-only verification of the outcome; the
implementation itself does not depend on it and only goes through the
existing/public Codex execution path (runAppServerTurn → app-server
thread/start with ephemeral).

Motivation / use case

Lets an orchestrating agent choose per task:

disposable work   → --ephemeral
resumable work     → existing persistent behavior (default)

so that dispatching many independent, fire-and-forget Codex subtasks
in parallel no longer pollutes Recent/history with threads nobody will
ever revisit or resume.

`executeTaskRun` hardcoded `persistThread: true`, so every `task` run
created a persistent Codex thread even for disposable, fire-and-forget
work (e.g. many parallel subtasks from an orchestrating agent), flooding
Codex Recent with `Codex Companion Task: ...` entries with no opt-out.

`runAppServerTurn` already supports a per-call `persistThread` toggle
that maps to the app-server's `ephemeral` thread param, and `codex exec`
already exposes `--ephemeral` at the top level. This wires the same
toggle into `codex-companion.mjs task` as an opt-in `--ephemeral` flag.

- Default behavior is unchanged: omitting the flag persists a thread
  exactly as before, and `--resume`/`--resume-last` are untouched.
- `--ephemeral` is rejected together with `--resume`/`--resume-last`,
  since an ephemeral thread cannot be resumed.
- Job records now carry an `ephemeral` bit so `findLatestResumableTaskJob`
  never offers an ephemeral run as a `--resume-last` candidate, and so
  status/result rendering stops suggesting `codex resume <id>` for a
  thread that was never persisted.

Verified against a real Codex CLI (0.155.1, logged-in ChatGPT account)
against `~/.codex/state_5.sqlite`: a single `--ephemeral` task added 0
rows for its cwd, a plain `task` added 1 (unchanged default), 3 parallel
`--ephemeral` tasks added 0 more, and `--resume-last` still resumed the
persisted thread with context intact.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@0dimen
0dimen requested a review from a team September 22, 2026 11:15
Edo771977 added a commit to Edo771977/codex-plugin-cc that referenced this pull request Sep 22, 2026
Import openai#779: --ephemeral on task, for runs nothing should come back to
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant