Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
In OpenClaw v2026.5.18, the legacy mirrored-history fallback in extensions/codex/src/app-server/run-attempt.ts:1088-1092 calls:
projectContextEngineAssemblyForCodex({
assembledMessages,
originalHistoryMessages,
prompt,
})
without passing maxRenderedContextChars.
When omitted, projectContextEngineAssemblyForCodex normalizes the optional arg back to DEFAULT_RENDERED_CONTEXT_CHARS = 24_000 per extensions/codex/src/app-server/context-engine-projection.ts:17 and :362-369.
The active-context-engine branch already passes a budget-scaled cap at extensions/codex/src/app-server/run-attempt.ts:1024-1036:
maxRenderedContextChars: resolveCodexContextEngineProjectionMaxChars({
contextTokenBudget: params.contextTokenBudget,
reserveTokens: resolveCodexContextEngineProjectionReserveTokens({
config: params.config,
}),
})
That parity fix landed in PR #80761, closing issue #80760. It does not cover the legacy mirrored-history fallback call site.
Steps to reproduce
- Use OpenClaw v2026.5.18.
- Configure an agent using:
provider=openai-codex
modelApi=openai-codex-responses
modelId=gpt-5.5
contextTokenBudget=272000
plugins.slots.contextEngine unset
- Because
plugins.slots.contextEngine is unset, the context engine defaults to legacy per src/plugins/slots.ts.
- Continue a session until a new Codex thread is established while prior user turns already exist.
- Trigger a mid-session Codex thread rebuild, for example by clearing/losing the startup binding or by hitting a dynamic-tool fingerprint mismatch so
shouldProjectMirroredHistoryForCodexStart returns true.
- Observe that the fallback rebuild uses the 24,000-character default projection cap rather than a cap derived from the 272,000-token budget.
Expected behavior
The legacy mirrored-history fallback should pass maxRenderedContextChars derived from contextTokenBudget, matching the active-context-engine branch behavior added in PR #80761.
For a 272,000-token budget, resolveCodexContextEngineProjectionMaxChars computes:
(contextTokenBudget - reserveTokens) * 4
clamped to:
[DEFAULT_RENDERED_CONTEXT_CHARS=24000, MAX_RENDERED_CONTEXT_CHARS=1000000]
With the default reserve, a 272,000-token budget reaches the MAX_RENDERED_CONTEXT_CHARS = 1,000,000 clamp, or roughly 250,000 tokens of rendered history capacity.
Actual behavior
The legacy mirrored-history fallback omits maxRenderedContextChars, so projectContextEngineAssemblyForCodex falls back to:
DEFAULT_RENDERED_CONTEXT_CHARS = 24000
That is roughly 6,000 tokens of rendered history. In production observations on v2026.5.18 with provider=openai-codex, modelApi=openai-codex-responses, modelId=gpt-5.5, and contextTokenBudget=272000, a channel whose behavior is consistent with legacy fallback rebuilds shows much lower retained context than a stable channel. Two snapshots from the same agent at different times, both on v2026.5.18:
Snapshot pair A (earlier):
Rebuild-heavy channel Stable channel
Context 36k / 272k (13%) 118k / 272k (43%)
Compactions 0 0
Snapshot pair B (later):
Rebuild-heavy channel Stable channel
Context 36k / 272k (13%) 90k / 272k (33%)
Compactions 0 0
The retained-context ratio is consistently in the 13% band on the rebuild-heavy channel and in the 33-43% band on the stable channel. The rebuild-heavy channel was observed not to grow past ~36k of total context usage, which is consistent with each new-thread turn re-rendering projected history at the 24,000-character cap plus normal system/tool/current-message overhead.
The fresh-input size is consistent with the code path:
24,000 rendered chars ~= 6,000 tokens of projected history
+ ~25k-30k tokens of system prompt, developer instructions, tool schemas, and current user message
= ~31k tokens fresh input per fallback turn
OpenClaw version
v2026.5.18
Operating system
Darwin 25.4.0
Install method
npm global
Model
openai-codex/gpt-5.5 via Codex app-server
modelApi=openai-codex-responses
contextTokenBudget=272000
Provider / routing chain
openclaw -> openai-codex (Codex OAuth) -> OpenAI Codex Responses API
Additional provider/model setup details
effective plugins.slots.contextEngine = "legacy"
plugins.slots.contextEngine is unset in the user openclaw.json. legacy is the resolved default per src/plugins/slots.ts:17-20 (default contextEngine: "legacy"). No third-party context-engine plugin installed.
Relevant prior merged work:
#80760 / PR #80761:
Active context-engine branch was changed to pass a context-budget-scaled
maxRenderedContextChars. The same fix was not applied to the legacy fallback branch.
#83127:
Fixed truncation direction inside projectContextEngineAssemblyForCodex via the
new truncateOlderContext helper (context-engine-projection.ts:385-402).
Applies to both branches because the helper is inside the projection function.
#83466 (issue) / PR #83516 / commit 491ce8b753:
Fixed inbound image attachment delivery on provider=openai modelApi=openai-responses.
Does not address this legacy-fallback projection-budget gap.
Logs, screenshots, and evidence
v2026.5.18 source references:
extensions/codex/src/app-server/run-attempt.ts:1088-1092
Legacy mirrored-history fallback calls projectContextEngineAssemblyForCodex without maxRenderedContextChars.
extensions/codex/src/app-server/run-attempt.ts:1024-1036
Active-context-engine branch passes maxRenderedContextChars derived from contextTokenBudget and reserveTokens.
extensions/codex/src/app-server/context-engine-projection.ts:17
Defines DEFAULT_RENDERED_CONTEXT_CHARS = 24_000.
extensions/codex/src/app-server/context-engine-projection.ts:29-40, :362-369
Normalizes missing/optional maxRenderedContextChars to DEFAULT_RENDERED_CONTEXT_CHARS.
extensions/codex/src/app-server/context-engine-projection.ts:385-402
Tail-preserving truncateOlderContext helper from #83127, applied to both branches.
src/plugins/slots.ts:17-20
Default `contextEngine: "legacy"` when no slot or plugin selection is configured.
Empirical production observation on v2026.5.18 (two consecutive snapshots across two channels under the same agent, same workspace, same OpenAI Codex OAuth profile):
Configuration (both channels):
provider=openai-codex
modelApi=openai-codex-responses
modelId=gpt-5.5
contextTokenBudget=272000
effective plugins.slots.contextEngine=legacy
Channel A (rebuild-heavy):
Snapshot 1: Context 36k/272k (13%), Compactions 0
Snapshot 2: Context 36k/272k (13%), Compactions 0
Channel B (stable thread):
Snapshot 1: Context 118k/272k (43%), Compactions 0
Snapshot 2: Context 90k/272k (33%), Compactions 0
Suggested fix shape, not normative:
Copy the existing maxRenderedContextChars kwarg from run-attempt.ts:1024-1036
into the legacy fallback call at run-attempt.ts:1088-1092.
No new helper appears necessary because the active branch already has the required expression.
Impact and severity
The default legacy context-engine path can rebuild Codex mirrored history using a 24,000-character projection cap even when the model has a 272,000-token context budget. Affected: any agent on the Codex app-server runtime with default legacy context-engine config (no third-party context-engine plugin installed) on long-running channels that re-establish Codex threads mid-session.
Observed impact in v2026.5.18 production:
Context retained held at 36k / 272k (13%) on the rebuild-heavy channel
across two snapshots taken on the same day.
The same agent on a different channel without projection rebuilds reached
90-118k / 272k (33-43%) in the same period.
No compactions occurred, so the observed reduction was not caused by compaction.
Active-context-engine users already receive the budget-scaled cap from PR #80761. The gap is limited to the legacy mirrored-history fallback call site.
Additional information
Scope guard: this issue is only about the projection budget used by the legacy mirrored-history fallback.
The separate root cause for why some channels frequently re-establish Codex threads is not part of this issue and should be filed separately after this lands. One observed trigger shape is dynamic-tool fingerprint churn when room_event inbound forces message_tool_only and changes the message tool direct/deferred spec, but that is not part of this issue and would benefit from its own investigation.
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
In OpenClaw v2026.5.18, the legacy mirrored-history fallback in
extensions/codex/src/app-server/run-attempt.ts:1088-1092calls:without passing
maxRenderedContextChars.When omitted,
projectContextEngineAssemblyForCodexnormalizes the optional arg back toDEFAULT_RENDERED_CONTEXT_CHARS = 24_000perextensions/codex/src/app-server/context-engine-projection.ts:17and:362-369.The active-context-engine branch already passes a budget-scaled cap at
extensions/codex/src/app-server/run-attempt.ts:1024-1036:That parity fix landed in PR #80761, closing issue #80760. It does not cover the legacy mirrored-history fallback call site.
Steps to reproduce
plugins.slots.contextEngineis unset, the context engine defaults tolegacypersrc/plugins/slots.ts.shouldProjectMirroredHistoryForCodexStartreturns true.Expected behavior
The legacy mirrored-history fallback should pass
maxRenderedContextCharsderived fromcontextTokenBudget, matching the active-context-engine branch behavior added in PR #80761.For a 272,000-token budget,
resolveCodexContextEngineProjectionMaxCharscomputes:clamped to:
With the default reserve, a 272,000-token budget reaches the
MAX_RENDERED_CONTEXT_CHARS = 1,000,000clamp, or roughly 250,000 tokens of rendered history capacity.Actual behavior
The legacy mirrored-history fallback omits
maxRenderedContextChars, soprojectContextEngineAssemblyForCodexfalls back to:That is roughly 6,000 tokens of rendered history. In production observations on v2026.5.18 with
provider=openai-codex,modelApi=openai-codex-responses,modelId=gpt-5.5, andcontextTokenBudget=272000, a channel whose behavior is consistent with legacy fallback rebuilds shows much lower retained context than a stable channel. Two snapshots from the same agent at different times, both on v2026.5.18:The retained-context ratio is consistently in the 13% band on the rebuild-heavy channel and in the 33-43% band on the stable channel. The rebuild-heavy channel was observed not to grow past ~36k of total context usage, which is consistent with each new-thread turn re-rendering projected history at the 24,000-character cap plus normal system/tool/current-message overhead.
The fresh-input size is consistent with the code path:
OpenClaw version
v2026.5.18
Operating system
Darwin 25.4.0
Install method
npm global
Model
Provider / routing chain
Additional provider/model setup details
plugins.slots.contextEngineis unset in the useropenclaw.json.legacyis the resolved default persrc/plugins/slots.ts:17-20(defaultcontextEngine: "legacy"). No third-party context-engine plugin installed.Relevant prior merged work:
Logs, screenshots, and evidence
v2026.5.18 source references:
Empirical production observation on v2026.5.18 (two consecutive snapshots across two channels under the same agent, same workspace, same OpenAI Codex OAuth profile):
Suggested fix shape, not normative:
Impact and severity
The default legacy context-engine path can rebuild Codex mirrored history using a 24,000-character projection cap even when the model has a 272,000-token context budget. Affected: any agent on the Codex app-server runtime with default legacy context-engine config (no third-party context-engine plugin installed) on long-running channels that re-establish Codex threads mid-session.
Observed impact in v2026.5.18 production:
Active-context-engine users already receive the budget-scaled cap from PR #80761. The gap is limited to the legacy mirrored-history fallback call site.
Additional information
Scope guard: this issue is only about the projection budget used by the legacy mirrored-history fallback.
The separate root cause for why some channels frequently re-establish Codex threads is not part of this issue and should be filed separately after this lands. One observed trigger shape is dynamic-tool fingerprint churn when
room_eventinbound forcesmessage_tool_onlyand changes themessagetool direct/deferred spec, but that is not part of this issue and would benefit from its own investigation.