[Critical workflow bug] Auto-compaction silently abandons active delegated tasks; Responses repair destroys handover semantics
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 18/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- api, authentication, backend
Research direction
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.
Written by the indexing model from the issue text.
Description
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:
- User task A: inspect
example.txt. - Recorded successful tool result and assistant confirmation: A is completed.
- A valid external-task envelope: human-authorized task B, synthetic ticket 1731, with reviewer pass 2 pending.
- Assistant acknowledgement that B is active.
- A real remote-compaction request through
/v1/responsesusingcompaction_trigger. - 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:
- 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. - 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 reportsopus[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.
- Dominant language
- TypeScript
- Stars
- 16.9k
- Forks
- 1.3k
- Avg merge
- 7h 34m
- Merged PRs (30d)
- 667
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lidge-jun/opencodex
-
Transient OAuth login failure persists in getLoginStatus and masks active account in dashboardMay be free again A pull request for this issue was closed without being merged. Openaccount-pool bug gui
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
lidge-jun/opencodex#7378 · 2 comments ·
Maintainers usually reply within 1 day
-
account-pool enhancement needs-design proxy
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
lidge-jun/opencodex#6737 · 1 comment ·
Maintainers usually reply within 1 day
-
fix(google-antigravity): discoverAntigravityProject fails with missing_project when project is not auto-discovered, rejecting valid tokensPossibly taken @yobushka claimed this today. Openaccount-pool bug
Difficulty 3/5 1-2 days Newbie friendliness 35/100
lidge-jun/opencodex#7382 · 2 comments ·
Maintainers usually reply within 1 day
-
account-pool bug needs-design provider proxy
Difficulty 4/5 3-5 days Newbie friendliness 42/100
lidge-jun/opencodex#7380 · 3 comments ·
Maintainers usually reply within 1 day
-
account-pool bug
Difficulty 4/5 3-5 days Newbie friendliness 48/100
lidge-jun/opencodex#7377 · 2 comments ·
Maintainers usually reply within 1 day
All issues in lidge-jun/opencodex
Similar issues
-
[测试] 等待仓库加载后再记录多仓库排序基线Possibly taken @myot233 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
area:arcade p3-medium ready-for-agent testing type:docs
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
fderuiter/deruiter.dev#2369 ·
Maintainers usually reply within 1 day
-
area:devenv origin:agent type:bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
overengineeringstudio/effect-utils#1949 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
ccch1mneyyy/dsh-TUI#1631 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
MiniMax-AI/minimax-code#507 ·
Maintainers usually reply within 1 day