Hook additionalContext spilling breaks long-context memory plugins

Open 💬 2 comments Opened May 15, 2026 by permaevidence

What changed

Codex 0.130.0 appears to hard-limit hook-injected additionalContext to about 2,500 tokens per hook output. Larger hook context is written to a temp file and replaced in the model-visible context with a truncated preview plus:

Full hook output saved to: ...

Why this is a problem

This is a major limitation for memory plugins.

A useful long-term memory plugin often needs to inject substantially more than 2,500 tokens of structured context, for example:

  • durable user facts
  • recent cross-thread conversation history
  • project/task history
  • calendar or external state
  • summaries and archive references
  • post-compaction restoration context

The whole point of hook-based memory is that the plugin can rebuild model-visible context at lifecycle boundaries like SessionStart, UserPromptSubmit, and now PostCompact / post-compaction recovery.

If Codex silently replaces most of that context with a file path, the model no longer actually has the memory. It has to notice the path, decide to read it, and spend a tool call doing so. That changes memory from ambient context into an optional retrieval task, which is much weaker and less reliable.

Request

Please revert this hard limit, or make it configurable.

Ideally:

  • allow users/plugins to opt out of spilling for trusted hooks
  • or expose a configurable hook_additional_context_token_limit
  • or apply the spill only to UI/display output, not to model-visible additionalContext

I understand the motivation to prevent unbounded hook output growth, but a fixed ~2,500-token ceiling makes serious memory plugins much less useful.

Concrete use case

I maintain a Codex long-term-memory plugin that injects cross-thread history and user facts through hooks, and reinjects memory after compaction. The new PostCompact hook support is very useful, but the new spilling behavior undermines the same use case by preventing full memory from being placed back into context.

This is especially painful because compaction is exactly when memory restoration matters most.

View original on GitHub ↗

2 Comments

cowwoc · 2 months ago

Possible strong relation to #28736.

That bug reproduces duplicate SessionStart(source=compact) hook firings on later turns even when no new compaction happened. For memory hooks that restore long context after compaction, this could cause repeated restoration attempts, repeated spills, extra token cost, and more model-visible clutter on turns that are not true post-compaction turns.

nos1609 · 1 month ago

I can confirm this failure mode from two long-running private, app-server-backed sessions.

Observed in one post-compaction cycle:

  • The complete persisted handoff pack was 44,765 characters.
  • The hook returned a bounded 14,000-character additionalContext payload.
  • Codex reported an estimated 4,816 tokens and spilled that payload.
  • The model-visible replacement was a 7,904-character head/tail preview plus a path shaped like <temp_dir>/hook_outputs/<thread-id>/<uuid>.txt.
  • The agent continued without reading either the runtime spill file or the plugin's complete persisted pack, so restoration remained partial even though the full data was available locally.

There is also a compounding lifecycle constraint. The current strict PostCompact command-output schema only exposes universal output fields; it does not accept hookSpecificOutput.additionalContext. A plugin can reliably persist its handoff during PostCompact, but its first reliable injection point is a later SessionStart or UserPromptSubmit, where the 2,500-token cap applies. The delayed/duplicated compact-session timing tracked in #28736 makes this gap more visible.

As a mitigation, I changed the plugin to mirror Codex's current estimator (ceil(UTF-8 bytes / 4)), keep its model-visible anchor below 2,500 tokens, include the complete artifact path, and unconditionally instruct the agent to read that artifact before proceeding. This avoids a second runtime spill, but it still turns deterministic context restoration into optional tool-driven retrieval, which is the core reliability problem described here.

A configurable limit for trusted hooks, or a first-class file-context/artifact reference that the host loads before model execution, would preserve the safety bound without making restoration depend on the model noticing and following a path.