Document (and optionally control) where UserPromptSubmit `additionalContext` lands relative to the user's prompt
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What happened
A UserPromptSubmit hook returning hookSpecificOutput.additionalContext has its text delivered as a separate role: "developer" message appended after the user's prompt. Because the injected block is then the last thing the model reads, it can be mistaken for the task itself.
Observed on codex-cli 0.149.1, gpt-5.6-sol (high). A hook injected a style directive ("write in prose, not fragments…"). The model replied:
Understood. Ready for the task.
…and performed no work. The user's actual prompt was one position earlier and lost the attention contest to the trailing developer message.
Why this is a docs bug, not just a model quirk
The hooks reference says only that output is "added as extra developer context". It does not specify:
- the role the text is delivered under, or
- its position relative to the user's prompt.
Hook authors therefore have no way to know their text lands in the final, highest-salience slot of the context — which is exactly the position prompt-engineering guidance recommends for the one instruction you most want obeyed. Injected context placed there competes with the task instead of qualifying it.
The role: "developer" placement is visible in the transcript excerpt in #16933, but that issue is about TUI visibility, so the mechanism is only documented there by accident.
Contrast with Claude Code
Claude Code injects UserPromptSubmit context as a <system-reminder> inside the user turn, so it reads as an annotation on the prompt and the prompt stays last. Codex's hook input/output contract is otherwise Claude-compatible — the same hook scripts run unmodified in both — which makes this one silent divergence easy to hit when porting hooks.
Workaround
Prepending a task anchor to every Codex-bound injection, which re-points the model at the prompt:
[Directive attached to the user's message above — NOT a message of its own;
do not acknowledge it. The user's message is the task: execute it now, with
the directive below applied.]
This works, but it costs tokens on every turn and has to be applied by each hook author independently. Note that it must be phrased as an annotation; framing it as an out-of-band system command instead tends to trip the model's prompt-injection defenses, so it surfaces the text to the user rather than acting on it.
Requests
- Document the role and the position of
additionalContextrelative to the user's prompt, for each event that supports it. - Optionally, offer in-turn placement — e.g. a
placementfield onhookSpecificOutput, or matching Claude Code's in-user-turn shape — so cross-harness hooks don't each need their own anchor.
Related
- #16933 — transcript excerpt showing the
role: "developer"message (visibility ask, not placement) - #16486, #20766, #21696 — all TUI-visibility asks; none change what the model sees
- #19385 —
PreToolUsedoesn't supportadditionalContext
Environment
- codex-cli 0.149.1, Linux
- Model: gpt-5.6-sol, reasoning effort high
- Hook:
UserPromptSubmit, JSON output withhookSpecificOutput.additionalContext
Contributor guide
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.
Research direction
Start with the hooks reference and the transcript excerpt in #16933, then trace which events support hookSpecificOutput.additionalContext. Done means documenting the delivered role and its position relative to the user's prompt for each supported event; treat optional in-turn placement as a separate proposal rather than assuming its design.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, cli, documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 67/100