Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[Critical workflow bug] Auto-compaction silently abandons active delegated tasks; Responses repair destroys handover semantics

Chiusa
#6,764 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
18/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
typescript

Direzione di ricerca

Start with the repro fixture: it imports externalTaskInputContent from src/responses/task-input.ts and repairUnidentifiedToolOutputItems from src/adapters/openai-responses/tool-output-recovery.ts, and the two disagree on the same function_call_output seed. Then check src/adapters/openai-responses/passthrough.ts, where the repair runs after the routed-compaction request is built. Done means external task input survives repair with its provenance intact, and a regression fixture (completed A, authorized B, compaction, continuation) keeps B active and does not repeat A.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug
Client or integration

Codex App; independently investigated with isolated HTTP protocol tests.

Area

Proxy and routing / Responses adapter / automatic compaction.

Summary

Critical autonomous-workflow failure: after automatic compaction, an agent can silently abandon its active, human-authorized delegated task, answer an already-completed initial request again, and end the turn with unfinished work outstanding. There is no transport failure or explicit failed-task signal: the requests succeed. The failure occurs in task ownership and continuation semantics.

The observed Codex App conversation first completed a small browser check, then accepted an explicitly authorized task handover from another chat and worked on it for roughly 32 minutes. Immediately after auto-compaction, it repeated the original browser check and ended its answer, leaving the active task and a pending review unfinished.

This breaks a central promise of long-running agent workflows: compaction must preserve what the agent is currently supposed to finish. A clean API completion can conceal abandonment of the real job. Please prioritize this as a serious workflow-integrity bug, rather than a cosmetic repeated answer.

Confirmed OpenCodex defect

Two code paths interpret the same valid Codex external-task input differently:

{
  "type": "function_call_output",
  "id": "fco_synthetic",
  "name": "send_message_to_thread",
  "namespace": "codex_app",
  "output": "<codex_delegation>Human-authorized task B</codex_delegation>"
}

There is deliberately no call_id: this is externally submitted task input, not the result of a call made by the destination agent.

  • externalTaskInputContent() recognizes it as external task input; the common parser converts it to a user-role message.
  • repairUnidentifiedToolOutputItems() instead converts it to a user message prefixed [tool output for unknown call], discarding the protocol fields that distinguish an authorized handover from an ordinary orphaned result.
  • The Responses passthrough runs that repair after constructing the routed-compaction request. Thus the summarizer sees the external task misclassified as unidentified tool output.

I reproduced this inconsistency by executing the installed 2.80.0 functions directly. The repair function still has this behavior on current main (250f17afd8ff44c93c620d87c1f346ef56f64fb4).

Relevant sources:

Related earlier contract fixes: #3732, #3735, #3807. This report concerns semantic degradation and silent abandonment, rather than their explicit missing-call_id rejection.

Reproduction

Run this TypeScript fixture against the repository, or adapt the import paths to the installed package:

import { externalTaskInputContent } from './src/responses/task-input';
import { repairUnidentifiedToolOutputItems } from './src/adapters/openai-responses/tool-output-recovery';

const seed = {
  type: 'function_call_output',
  id: 'fco_synthetic',
  name: 'send_message_to_thread',
  namespace: 'codex_app',
  output: '<codex_delegation>Human-authorized task B</codex_delegation>',
};

console.log(externalTaskInputContent(seed));
// Correctly recognized as external task input.

console.log(JSON.stringify(repairUnidentifiedToolOutputItems({ input: [seed] })));
// Incorrectly labelled "[tool output for unknown call]".
Behavioral reproduction and controls

The isolated fixture contains:

  1. User task A: inspect example.txt.
  2. Recorded successful tool result and assistant confirmation: A is completed.
  3. A valid external-task envelope: human-authorized task B, synthetic ticket 1731, with reviewer pass 2 pending.
  4. Assistant acknowledgement that B is active.
  5. A real remote-compaction request through /v1/responses using compaction_trigger.
  6. Continuation with the retained original user message and returned compaction item, mirroring the observed replacement-history shape.

The fixture explicitly tells the model what Codex's external-task protocol means. Both native GPT and routed Claude choose B with the full history, establishing a valid pre-compaction baseline. Tool calls only record the selected next action; no real files, tickets, browser actions, or reviews are changed by these tests.

Route / condition Observed continuation
Native OpenAI/GPT compaction, no proxy B continued in both tested runs
OpenAI/GPT through OpenCodex B continued
Claude through OpenCodex → Meridian Both tested runs abandoned B and answered completed A
Handover normalized to user input before Claude summarization, but only original A retained afterward Both tested runs selected A again, despite a correct summary identifying B as active
Direct user message naming B retained after compaction Claude continued B
Explicit new user instruction: A is done; do not repeat A; continue B Claude continued only B in both tested runs

These are small controlled tests, not statistical reliability estimates. Preliminary fixtures that lacked valid handover semantics were excluded from this comparison.

Switching the compaction model to GPT does not suffice

I tested a portable GPT-generated prose checkpoint followed by Claude continuation, using OpenCodex's COMPACT_PROMPT and an ocx1: envelope. This emulates the cross-provider portable-summary path; I did not change the live compactionRouting setting.

Two results:

  1. With the unchanged external-task item, GPT sees [tool output for unknown call] and questions whether B was authorized. Changing the summarizer cannot restore protocol information already removed upstream.
  2. With the handover normalized before GPT summarization, GPT correctly identifies B as active and A as completed. Claude nevertheless selects A again after replay. So there is also a continuation/task-selection issue beyond summary accuracy.
Limits of attribution

The inconsistent external-task handling above is a concrete OpenCodex defect. The additional failure after replay of a correct summary is reproduced in the Claude/Meridian route, but is not fully isolated between message framing, Meridian and Claude behavior.

In the original App failure, the complete summary was preserved word-for-word in the actual Claude input and correctly named the active task. Codex continued the same turn. This rules out simple summary truncation or a new user turn as the explanation for that incident. The retained old request and decoded summary arrived as one user message after Meridian translation.

Native OpenAI's successful controlled compaction is a useful control, not proof that native Codex can never have a similar failure.

Expected behavior / suggested investigation
  • Reuse external-task recognition in the Responses passthrough before generic orphan-output repair; preserve authorized-task provenance. Do not promote arbitrary tool output based only on delegation text or XML.
  • Preserve the active authorized task through both summarization and replay, including a clear distinction between completed requests and the current job.
  • Add a regression fixture with completed A → authorized external B → compaction → continuation. Assert that B remains active and A is not repeated. Cover both correct-summary replay and cross-provider compaction.
Version

2.80.0

Operating system

macOS 27.0.1, build 26A434

Provider and model

meridian/claude-opus-5-5 through OpenCodex → Meridian 1.79.0. Native/control model: gpt-6.1-sol.

Logs or error output
externalTaskInputContent(seed): external user task recognized
repairUnidentifiedToolOutputItems({input:[seed]}): [tool output for unknown call]
Before compaction: continue_review({ticket:1731})
After routed compaction: answers already-completed task A; B remains unfinished
Transport: successful completion, no explicit failure signal
Screenshots and supporting files

The deterministic TypeScript reproduction, source permalinks, behavioral controls and test matrix are included above. No private conversation logs are attached.

Additional environment details
  • OpenCodex: 2.80.0.
  • Codex App bundled CLI reported by the affected rollout: 0.160.1.
  • Meridian: 1.79.0.
  • OS: macOS 27.0.1, build 26A434.
  • Routed selector: meridian/claude-opus-5-5; Meridian telemetry reports opus[1m].
  • Native/control selector: gpt-6.1-sol.
  • Auto-compaction token limit in the observed App configuration: 350000.
  • No compaction-routing override configured during the original incident.
Redacted configuration shape
{
  "providers": {
    "meridian": {
      "adapter": "openai-responses",
      "baseUrl": "http://127.0.0.1:3456/v1"
    }
  }
}

Codex's OpenAI base URL points to the OpenCodex loopback listener. All reproduction content above is synthetic or anonymized; no account identifiers, credentials, customer data, private repository URLs, or private chat logs are included.

Checks
  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.
Lingua principale
TypeScript
Stelle
16.9k
Fork
1.3k
Merge medio
9h 39m
PR unite (30g)
633

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di lidge-jun/opencodex

Tutte le issue di lidge-jun/opencodex

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.