Skip to content

Compaction can promote partial output from interrupted commands into falsely confirmed task state #35355

Description

@hiroki-tamba-research

What issue are you seeing?

Codex appears vulnerable to a broader failure class in which ephemeral observations from an interrupted command can be promoted into confirmed task state, then inherited by later turns or sessions without re-verification against durable artifacts.

This is related to, but more specific than:

The specific failure mode is:

  1. A long-running command produces partial stdout.
  2. The process is terminated before its intended side effect completes (for example, before writing a JSON file).
  3. The session is compacted or resumed.
  4. The partial stdout is summarized as if the corresponding operation completed successfully.
  5. A later model/turn inherits that summary and treats the result as confirmed.
  6. Inspection of the actual output file shows that the claimed result was never persisted.

This is an observation–persistence conflation: “output appeared in the terminal” is treated as equivalent to “the operation completed and its result was durably written.”

A documented instance and mechanism analysis are available here:

Although the documented instance occurred in Claude Code, the constituent mechanisms have already been independently reported in Codex through #14341, #14589, and #22219. The concern is that Codex may exhibit the same class of integrity failure under long-session, high-context, interrupted-process conditions.

What steps can reproduce the bug?

The following protocol should test the failure deterministically or near-deterministically.

Test script

Use a script that:

  1. Emits a result to stdout immediately.
  2. Delays the durable write.
  3. Is guaranteed to be interrupted before the write occurs.

Example:

import json
import time
from pathlib import Path

output_path = Path("result.json")

print(json.dumps({"case": "A1", "status": "success", "value": 42}), flush=True)

# Ensure partial stdout is visible long before persistence.
time.sleep(120)

output_path.write_text(
    json.dumps([{"case": "A1", "status": "success", "value": 42}], indent=2),
    encoding="utf-8",
)

print("persisted", flush=True)

Reproduction sequence

  1. Start a long-running Codex session with enough prior activity to approach or trigger context compaction.
  2. Ask Codex to run the script and report the completed result from result.json.
  3. Terminate the command after the JSON line appears in stdout but before result.json is written.
    • On Unix-like systems, send SIGTERM; expected exit status is 143.
    • On Windows, use the closest available termination path and record the process status.
  4. Continue until compaction occurs, or resume/fork the task if the product surface supports it.
  5. Ask Codex which cases completed successfully.
  6. Observe whether it reports A1 as completed based on the earlier stdout or compacted summary.
  7. Inspect durable state:
ls -l result.json
cat result.json

Expected durable state: result.json does not exist, is empty, or lacks A1.

Stronger multi-item variant

Use a loop where each item prints a success record, sleeps, and only appends to a cumulative file after the sleep. Kill the process after two stdout records but before the first file append. Then verify whether the compacted/resumed session reports those two items as completed.

Evidence to capture

  • Full command invocation
  • stdout and stderr
  • process exit status / signal
  • timestamp of process termination
  • compaction or resume boundary
  • inherited summary or later status report
  • hash and contents of the expected output artifact
  • latest filesystem state before the final assistant response

What is the expected behavior?

Codex must not describe an interrupted operation as completed unless the intended external side effect is independently verified.

At minimum:

  • Partial stdout from a non-zero-exit command must be labeled observed, unconfirmed.
  • Exit status must remain attached to the command output through compaction and session inheritance.
  • A later turn must verify the target file/database/repository state before reporting completion.
  • If verification is unavailable, the assistant should say that the result was observed in partial output but was not confirmed as persisted.

Example expected response:

The process emitted an A1 success record, but it exited with status 143 before result.json was written. A1 is therefore unconfirmed and should be rerun.

Proposed mitigation

1. Preserve execution provenance through compaction

Every summarized operational claim should retain:

  • command ID
  • exit code / terminating signal
  • stdout/stderr provenance
  • intended side effects
  • verification state
  • artifact path or external resource identifier

A summary should not flatten all of these into plain natural-language assertions.

2. Introduce explicit epistemic states

Operational claims should use states such as:

  • planned
  • started
  • observed_partial_output
  • process_exited_nonzero
  • persisted_unverified
  • verified_persisted

Only verified_persisted should be eligible for “completed” language.

3. Exit-code-aware summarization

If a command exits non-zero or is terminated by signal:

  • mark all derived outputs as unconfirmed;
  • prohibit the compaction summary from stating that the task completed;
  • require explicit verification of intended artifacts before promotion to confirmed state.

4. Artifact-first completion checks

Before reporting completion, Codex should re-read the authoritative external state:

  • files: existence, content, mtime, and optionally hash
  • Git: latest git status / commit state
  • databases: committed row/query result
  • APIs: persisted response record or transaction identifier
  • tests: final test runner exit status and saved report

5. Inherited-state skepticism

After compaction, resume, fork, or model handoff, claims about external state should be treated as assertions requiring verification, not as ground truth. The downstream model should distinguish:

  • user-provided statements
  • prior assistant claims
  • raw tool observations
  • independently verified external state

6. User-visible integrity warning

When a session contains interrupted commands whose side effects were not verified, show a persistent warning such as:

One or more prior commands ended abnormally. Their partial outputs are not confirmed as persisted results.

Why this matters

This can silently corrupt:

  • scientific and benchmark results
  • batch API experiments
  • migration and synchronization tasks
  • test reports
  • repository state summaries
  • security research evidence
  • any multi-step workflow that relies on session continuity

The core risk is not ordinary factual hallucination. It is fabricated confirmation of external state, which can propagate across compaction boundaries and become increasingly difficult for later models or users to detect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingcontextIssues related to context management (including compaction)model-behaviorIssues related to behaviors exhibited by the modeltool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions