Goals: active goal continuation prompt and audit requirements can be lost after mid-turn compaction
@etraut-openai first off, incredible work on the new goals feature. This fixed the most painful part of using Codex: having the model sandbag its work and not actually complete what you want fully. This is genuinely life changing stuff.
There is quite a persistent issue with it, however. That issue is that after compaction, the goal is sometimes not carried through cleanly to the new agent.
I have been using the goals feature extensively over the past few days, and none of the times I have ran it on ambitious work has the work been completed, and that is due to one specific reason: compaction.
Often, the compaction message does not carry the goal task through cleanly, and more specifically it often does not carry through cleanly the most important "perform a completion audit against the actual current state" requirement of the goal prompt.
This leaves a concrete failure mode: the agent is busy finishing up a local task of its own -- for example running tests and verifying its changes. Compaction happens in the model of this finishing up process, and the compaction message conveys to the agent with fresh context that this specific task is almost done, the previous agent was just verifying their changes, continue with the verification and subsequent completion. This new agent then proceeds to perform the verification process, and after it is done mark the goal as complete because it was only fed that the local task and not the global goal and the audit requirements of it (the bigger picture).
I have found this to be the root cause of the agent prematurely stopping:
- After compaction in these circumstances, the new agent often sends a message to the commentary channel before running any tools like "Let me finish running tests so I can wrap this goal up". The agent then runs the tests, looks at the
git statusand a few modified files, and that evidence is enough to satisfy its confirmation bias to mark the goal as complete. This is a red flag as it shows the agent has treated completion of the goal as a foregone conclusion, then interpreted circumstantial evidence as confirmation. - I have reverse engineered the opaque compaction message in these scenarios, and it clearly does not convey the completion audit requirement of the goals prompt effectively, if at all.
I have implemented a fix locally for this where the active goal continuation prompt is now reattached during mid-turn compaction for both local and remote compaction paths, using the persisted active goal and only when the current turn is the synthetic goal-continuation turn. Manual/pre-turn compaction stays unchanged to avoid duplicate prompts.
I have ran many ambitious, long-horizon tasks after this change and the rate of premature closure has dropped significantly due to these changes eliminating the primary failure mode.
This is the correct solution as:
- The continuation prompt without the
{{ objective }}placeholder is 462 tokens (viao200k_base). Add a relatively average user goal prompt and that is likely 500-1000 tokens. This is a perfectly acceptable amount of tokens to inject after compaction. - This keeps the persisted goal table as the source of truth and avoids depending on the compacted summary to remember the active objective.
- The orthogonal-to-this-solution way to fix this failure mode is essentially adding a tool to retrieve the goal prompt for the new agent to call, which is the wrong fix as if the agent already has the goal in their context, this tool is practically useless. The only scenario the agent will not have the goal in its context is compaction, which makes the correct fix injecting the goal directly after the only time the model may lose it.
An alternative acceptable solution is making and injecting after compaction a brand new compaction-centered message with the goal. This is still not the optimal fix in my opinion as the current continuation prompt is short and is already in the optimal shape for a post-compaction injection ("Continue working toward the active thread goal."), and this would just be reinventing a prompt to achieve the exact same outcome as the current continuation prompt.
I have a small local patch of roughly 193 lines for this and would be happy to open a PR or discuss the approach further, since I understand goals is a WIP and likely still evolving.
26 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
@Chriss4123, thanks for trying out the new
/goalsfeature. I appreciate the feedback!I've done quite a bit of testing with the feature, and I haven't observed the failure mode that you're describing. I also haven't received any reports of this from other OpenAI employees who are testing the feature.
I did discover a problem with the implementation that could cause the behavior you're seeing, but it's not related to compaction. I have a PR posted with a fix, and it's currently awaiting code review. You're welcome to give it a try if you don't mind building the CLI from source. Or you can wait until the fix makes its way into an upcoming release. I'm hopeful that this will address the problem you're seeing.
Out of curiosity, which model and reasoning level were you using for your experimentation? I've done most of my testing with gpt-5.5 xhigh. It's possible that the behavior changes from one model to another.
@etraut-openai same as you, I use gpt-5.5 xhigh (exclusively in my case).
One theory I have is the potential structure of the work is different. What I do is write Markdown docs or have Codex write them around the architecture I want, and tell
/goalsto go implement it fully.Oftentimes these docs can get big for complex work, sometimes reaching 20K tokens. This is likely harder to carry through via compaction.
Also the nature of the work. The tasks I am assigning to
/goalsare often prohibitively complex (requiring a lot of work across hundreds of files and tens of thousands of lines of code added) and on behemoth codebases such as Chromium. The huge codebases I work on means compaction is much more frequent for me.The nature of my work introduces a much more complex decision to make when ending the task: are the docs fully and optimally implemented end-to-end? This is much harder as there is no easy signal to ascertain whether the goal is actually complete -- something like carrying a migration to completion or fixing a regression has a clear finished signal. That completion signal is likely much harder to carry through in repeated compactions if the model did not end its turn (did not get the continuation prompt in between the two compactions) and is therefore relying on a summary-of-a-summary. This is also frequently when this issue occurs -- after 20 or so compactions without the model yielding.
I want to leave you with something more than "trust me, bro", however for some reason the threads with
--enable goalson my testing of this feature a few hours after your PRs got merged are just... not there. I do still have reviews from that day.Here's a screenshot of when I asked an agent in a fresh chat to check if a document was fully actioned. It was around a pathological full saturation of the CPU in Zed when opening extremely large repos with many nested sub-repos. The solution was a full overhaul of the "hydrate all info at startup" to a lazy-loading model. The task was extreme in scale, spanning the whole Git backend and all UI consumers (basically the whole editor).
/goalswithout my remediation worked for around 6 hours on it before calling it done.<img width="1901" height="564" alt="Image" src="https://github.com/user-attachments/assets/bb9e18d8-6cba-4bc3-9407-6aa2a030569f" />
It still had legacy code, legacy structs interleaved with new methods, and missing pieces.
I ran
/goalsagain on the report that agent returned, and it still was not finished in the end (legacy stuff still present, etc.). An independent agent reported a 65-70% completion this time, with all the hardest work still undone or falling back to legacy paths.I took a snapshot of that state, and then I ran
/goalswith my fix, and it worked for longer than the cumulative duration of the previous two/goals, and got me ~95% way to completion. As a more accurate A/B, I plan to run the exact task on the goals with my fix starting from scratch and look at the differences between that one goal prompt with my fix and two goal prompts without it. I'll let you know once I do this.I then ran Codex on Chromium with an absolute monster of a task. The first
/goalsrun without my fix got ~20% of the way there, and worked for 12 hours. I ran/goalswith my fix on the existing state, and it worked for 46 hours and got very close to the final goal.---
As an aside, another thing I noticed which is very annoying is that the models are very afraid to start complex work, even with
/goals. I've had instances where I see 5+ hours of work where the model accomplishes nothing: it just surgically isolates and does the smaller parts of the task and returns while leaving the bigger stuff undone. I think this is because the model cannot complete some of the work in one turn, and it doesn't want to leave the workspace in an unclean state. It often just puts stubs, reinterprets stuff to avoid hard work, does an easier implementation to avoid hard work. I think some prompting that the model should attack the work systematically and that it can work over as many turns as needed (tell it a bit how the/goalsworks) would be great. Not sure if you've heard anything about this, but I can definitely show you a lot of frustrating model behavior in/goalsrelated to this that is in the codebase even after the goal is "completed" (stubs, "runtime available" checks that just immediately return false as the feature is unimplemented, pragmatic subsets, complete reinterpretations to avoid hard work). Let me know if you've heard this. Sorry if I went on a tangent.I've started to manually prompt models to work systematically and tell it how
/goalswork, and based on vibes, it feels like the model is more willing to tackle complex work even if it heavily disrupts the codebase initially. Just saying that it can work over as many turns as it wants and that is does not have to accomplish everything in one turn seems to help a lot.---
Anyways, I'm going to try and get some concrete, clean A/B examples for you soon so you can see for yourself rather than relying on my word. These ultra-long tasks are expensive even on the 200$ plan so I'll try and slot them in while not tanking my limits.
Also, another thing in favor of attaching the goal after compaction: the prompt is capped at 4000 chars. That's around 1000 tokens worst-case, added to the baseline tokens of the continuation prompt without the placeholder, is ~1462 tokens, which is not that much to attach (~1/180 of GPT-5.5's context in the worst-case scenario).
I've looked at your PR and it looks positive and a definite improvement, although I don't think it will fix what I am facing as it fixes a different class of issue. I'll compile and use that CLI in my A/B tests as I am confident that will get merged -- I don't see any blockers with your PR from my end.
@etraut-openai another very, very weird thing with the current way we do goals is that the model always responds to the last user message (not the goal prompt, that's a developer message) immediately after compaction rather than carrying on with the goal. This happens literally every time I have a prompt and then a
/goal. It also happens every time I send a steering message mid/goal(after compaction it ALWAYS just immediately responds to that steering message rather than carrying on with the goal). Here's an example (I asked a question, then ran/goal, and it is answering that question I asked while the goal is active after compaction):<img width="1920" height="511" alt="Image" src="https://github.com/user-attachments/assets/64c16bcb-0b65-41c1-88e2-4d35c71141ec" />
... some more work...
<img width="1920" height="396" alt="Image" src="https://github.com/user-attachments/assets/88f04cb9-0441-4ff7-940c-0807448c052d" />
... some more work...
<img width="1915" height="745" alt="Image" src="https://github.com/user-attachments/assets/ec73860e-987b-4487-ba8a-e494fa6534a9" />
(it did this for each and every compaction in the chat during the time
/goalwas active, so about 20 more times of the same, repeatable behaviour of it responding to the last user message).Usually, my prompt will be "Audit the codebase and determine if plan.md was fully implemented. Flag pragmatic subsets, placeholders, stubs, hacks, and all bullshit."
Then I'll do
/goal Fully fix all of these issues. If the code is doing something different replace it fully with the optimal solution rather than grafting on to it.(my prompt is longer than this with multiple attempts of trying to get the model not to do hacky things and spawn verification subagents and not manipulate said subagents to return clean and etc.).But then after each and every compaction, it will literally just respond to my last prompt (not the
/goalone). Then it will get a kick from the continuation prompt to keep working.This is fixed by doing the fix I described in this issue (injecting the continuation prompt after compaction). Interestingly, it is also fixed when I changed the continuation prompt to not be a developer message and instead be a user message. My theory is that compaction probably doesn't summarize developer messages or at least not to the same degree as user messages therefore the continuation is just not carried through compaction.
If my theory that compaction doesn't summarize developer messages that well is true, that is an extremely plausible explanation for the behavior I describe in this issue where after compaction with
/goalthe model often prematurely completes the goal and just seems to get lobotomized in a way that does not happen with compaction outside of/goal.For example, I specifically instruct the model to never do a pragmatic subset of the task: it can end its turn with the code not compiling, unclean, whatever, as long as it is making progress towards the actual goal. It does that wonderfully up until compaction kicks in, afterwards it starts with its normal behavior of putting stubs, reinterpreting the task, and such.
Empirically, switching the continuation prompt to a user prompt makes the model perform meaningfully better after compaction and it actually remembers the stuff I told it.
I actually think this might be the best fix: change the continuation prompt to a user message rather than a developer message. There is basically no reason to use a developer message as it does not benefit from Follow all applicable instructions, and it performs meaningfully worse than user messages in my empirical testing.
@etraut-openai simple A/B with the current latest Codex binary from upstream and the one with my modifications where I change the continuation prompt to a user message (
<untrusted_objective>to<objective>, removing the "untrusted user input" line, and some additional task-agnostic prompt modifications explaining how goals work works which makes it incredibly more effective at very complex ambitious tasks). Both intentionally run with-c model_auto_compact_token_limit=20000:Official latest binary:
<img width="1920" height="941" alt="Image" src="https://github.com/user-attachments/assets/cf18450c-1085-4e0b-bf17-e1da8af15cb6" />
As you can see, it compacted and then immediately answered my first prompt and ended its turn. Then the goal continuation prompt kicked to make it continue work.
My binary:
<img width="1920" height="830" alt="Image" src="https://github.com/user-attachments/assets/ebf0f915-6206-4db8-b801-e7c1a63cf6fa" />
I strongly believe the current changes I have is the best way forward. I am going to run many A/B tests on very long-horizon, complex work with both the current upstream binary and my binary so I can prove how effective these changes are.
I'd like to request permission to open a PR so we can collaborate on this further because I genuinely believe that goals can be substantially improved with a few modifications.
@Chriss4123, I appreciate the analysis and feedback!
The behavior you're describing about responding to the last steer message after compaction isn't specific to goals. That's a general issue with compaction, and we're thinking about ways to address that. I don't want to permute the goal implementation to work around a (hopefully short-lived) limitation of the current compaction approach.
A goal will work best when you give it a concrete (and preferably measurable) objective. Some of the objectives you've mentioned above are subjective and ambiguous, which I think is what's leading to the behavior you're seeing. For example, "Fully fix all of these issues" does not define a clear definition of completion.
I've played around with changing the goal continuation prompt from a developer message to a user message. Here's a draft PR if you'd like to play with it. I'm a bit worried about making such a change because user messages are treated differently (lower priority) than developer messages by the models, so moving it to a user message could reduce the effect of the injected message.
You mentioned that you also applied "some additional task-agnostic prompt modifications explaining how goals work". Can you share what you modified there?
@etraut-openai I disagree on the "subjective and ambiguous" part. My prompts aren't "Fully fix all of these issues". My prompts are "take this well defined prescriptive spec, and implement it fully". It is measurable because if I ask an agent in a new chat "was this doc fully actioned", it will say no it wasn't. If the agent can grade whether a task is complete, it should be able to do that task. No, I'm not saying P=NP as in this scenario both grading the task and doing it are fully possible in reasonable time.
Here is my current continuation prompt. I've been iterating on this for a very long time with a wide variety of large, ambitious, yet well defined tasks. I have kept all changes relatively task-agnostic so as to not overfit to any one specific task:
I also removed time being exposed to the model as it is irrelevant to how the model operates and creates unnecessary time pressure. Timekeeping is done cleanly in the TUI and the model being forced to say the amount of time it took is redundant. If you want to keep that "model says the amount of time", it is already returned when the model marks the goal as "complete", therefore there is no practical benefit to having it in the continuation prompt.
I've done a synthetic test where I set the amount of time to 1 hour and 50 hours in a half-completed
/goal, and the model with the 50 hour elapsed time finished dramatically quicker and left more work undone compared to the 1 hour model (both on upstream binary, not my custom one). Yes, these models are not deterministic but I am suspicious they are treating the elapsed time as a proxy for how close the goal is to completion. The through-line is the elapsed time is really not relevant in the continuation prompt and can be removed without regressions even if you wanted to keep the model reporting total time at goal end.---
Yes, developer messages supersede user messages in The chain of command. That means that if a user message and a developer message conflict, the developer message will win.
That priority rule only tells us how to resolve conflicts. It does not imply that the model will inherently optimize harder for an instruction solely because it appears in a developer message. Compare two otherwise identical prompts: one where instruction X is delivered as a developer message, and one where the same instruction X is delivered as a user message. If X is valid in both cases and no higher-priority instruction conflicts with it, the formal chain-of-command rule alone gives no reason to expect materially different behavior.
Empirically, in the
/goalsworkflow, the user-message placement has performed better for me. I have not seen a degradation from moving the continuation prompt out of the developer channel; across my testing, the user-message version has produced a real positive uplift.There is a potential factor of generalization. From Where the goblins came from:
The concern for me is that training on the chain of command may generalize beyond conflict resolution. Even if developer messages are only supposed to have priority when instructions conflict, the model may learn a broader heuristic that developer-channel instructions deserve greater weight, causing stronger adherence even when the same instruction in a user message would be non-conflicting and valid.
However, I feel like the chance this is meaningful is rare. These models are excellent instruction followers. After all, why wouldn't we make all user prompts developer messages wrapped in
<untrusted_input>if the difference was that meaningful?---
Circling back to my modifications. I am running the exact same
/goalprompt with my modifications on the same task that an independentgpt-5.5 xhighagent reported was 60% complete when I ran with upstream Codex (the first screenshot in this message).The upstream binary worked for around 6 hours on that goal before marking it complete. My binary has been working on this goal for 17h 8mins on fast mode (!!). Multiply that time by 1.5 and you get 25h 42m (!!) which is a better apples-to-apples comparison vs the six hour run. Keep in the goal is still active and the model is still working; I am fully confident it will genuinely complete the task once it marks the goal as complete.
<img width="1919" height="968" alt="Image" src="https://github.com/user-attachments/assets/70f566af-a123-42b1-be10-d7479eafbe53" />
Running an independent audit agent right now while the agent on my custom binary is still working on the goal and has not concluded (I am doing this to quickly reply to your message. I will do another audit when it marks the goal as complete and concludes).
<img width="1920" height="630" alt="Image" src="https://github.com/user-attachments/assets/606d1a61-430b-4f8e-9913-d89fd8addb4d" />
Yes, 90%. And it is still working.
I have got other A/B tests running right now that I will update you with once they conclude.
I really hope you can hear me out here because I think these changes substantially improve
/goal. Once again, if you'd like I can open a PR. Appreciate your time.If I understand you correctly, there are two primary changes you've made:
Are there additional changes?
Have you done any experiments that demonstrate the relative impact of 1 and 2, out of curiosity? My intuition is that 2 provides most of the benefits that you're seeing.
Yes, that’s right. The two primary changes are:
The main additional change is provenance/display plumbing for that user-role prompt. Since it is not actually typed by the user, I added an internal marker so Codex treats it as runtime-owned contextual input: it does not emit/render as a normal user-authored message, and the marker is stripped before model-facing input. So the model sees a clean user-role continuation prompt, but the UI/history do not present it as if the user sent it.
There are also smaller cleanups around removing elapsed-time/timestamp metadata from goal prompts/tool output.
I have done some controlled ablation of 1 vs. 2 but none as scientifically rigorous as I'd like (still working on this). Initially, I modified the prompt and kept it as a developer message. This helped immediately and meaningfully but still got derailed a bit by compaction. I then changed the prompt to a user message and modified it even more and this was when the magic seemed to kick in and is what I am working with now. The effects seem to be multiplicative, however take this with a grain of salt as I haven't done very clean ideal A/B comparisons yet between 1 and 2 with the latest version of the prompt (I haven't tested the latest version I pasted above as a developer message yet).
I like many of the changes to the continuation prompt. I'm experimenting with them now and will likely incorporate many of them.
An ablation would be useful, so thanks for doing that.
@etraut-openai I recommend running my prompt wholesale as all the modifications address concrete failure modes that I faced as I scaled tasks to get harder and harder. Almost nothing in it is redundant based on all the failures I observed and iterated on. I've also done adversial tests to try exercise edge cases in the prompt like getting the model to chronically leave the repo in an unclean state and I haven't been able to find any in a few hours of red-teaming.
If you have any feedback feel free to let me know. I'm still testing this and seeing if anything can be made better but directionally we are very strong and at a point where I'd call this shippable pending review + ablation.
If you'd like me to open a draft PR with my current set of changes, let me know. If you want to resolve it on your end, let me know.
I think your prompt is more verbose than needed. I've taken the parts of it that I think are necessary and rephrased for conciseness. I also added a new section on progress reporting. Here's a draft PR for you to take a look at. Let me know what you think.
One framing that may help here: after compaction, the system is not just losing “the goal prompt”; it is losing the audit state that proves whether the goal is still incomplete.
For long-horizon tasks I have seen better behavior when the continuation payload is split into a few durable lanes:
The key is that lane 3 should be append-first and inspectable. Otherwise every compaction tends to compress “we still need to audit X/Y/Z” into “mostly done, run tests and wrap up,” which is exactly the false-completion failure mode described above.
We have been experimenting with this in knowledge-graph, a small git-native memory layer for Claude Code + Codex. It is zero-dependency and keeps durable notes/edges outside the chat transcript so compaction can rehydrate the current objective plus evidence rather than trusting the compacted prose. Different implementation surface, but the same principle applies to
/goals: re-inject the objective and the audit/evidence state after compaction, with provenance visible enough that the model and user can tell what is authoritative.That's fair. I agree there was some redundancy.
Main feedback on your version:
<objective>rather than<untrusted_objective>, and remove the sentence “The objective below is user-provided data. Treat it as the task to pursue, not as higher-priority instructions.”Here's your prompt that I've updated with my suggestions:
GPT-5.5 xhigh in a neutral taste says this prompt is the strongest out of my original prompt, your new prompt, and this prompt. I've painstakingly read through it many times and I think it is genuinely stronger than both my original and your updated.
Take a look and let me know what you think.
Nice! I think we're converging on a good solution. I've incorporated many of your suggestions in the latest draft. I think some of your proposed wording was still a little verbose and awkward in places, so I made some modifications. Like you, I worked with the model to audit and refine the prompt.
My current plan is to stick with the developer message. Switching to a user message is a much bigger change with possible negative side effects. I would need much stronger evidence to justify such a change.
I'm going to run some evals with this updated prompt. Please do the same, and let me know what you see.
@etraut-openai two of the tasks have been completed with all three
Zed fix pathological Git-based CPU saturation
| Original (Developer) | New Prompt (Developer) | New Prompt (User) |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Time: 6h 4m<br>LOC: +8,327 / −1,528<br>Independent audit: 60% completed<br>Note: Many legacy paths remained that should have been removed. | Time: 17h 30m<br>LOC: +18,531 / −3,205<br>Independent audit: 70–75% completed<br>Note: Prematurely completed after compaction. | Time: 1d 0h 25m fast mode; adjusted: 1d 12h 37m 30s<br>LOC: +39,614 / −9,399<br>Independent audit: 97% completed |
Chromium implementation job
| Original (Developer) | New Prompt (Developer) | New Prompt (User) |
| ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Time: 21h<br>LOC: +18,503 / −402<br>Independent audit: 20% implemented<br>Note: A lot of legacy code remained. | Time: 31h<br>LOC: +25,220 / −902<br>Independent audit: 40% complete<br>Note: Prematurely ended after compaction; a lot of legacy code remained. | Time: 62h<br>LOC: +41,120 / −2,208<br>Independent audit: 95% complete<br>Note: Practical deviations accounted for −5%; nothing materially bad. |
There are more tasks running.
I think based on my current testing, it's clear this prompt on a user message is best. The biggest issue with the developer message was that compaction significantly hurt quality and resulted in premature completions.
I'd be interested to know your rationale here because I do not see any logical reason to remain on a developer message. Its primary purpose which is letting developers supersede user instructions does not apply here. It does not, in my testing, produce better instruction-following.
I strongly recommend you think about this and run your own tests if you don't trust me -- I really think we should switch to a user message.
OK, those results are pretty compelling. I'll see if I can repro those results with my own testing.
Sounds good. Make sure to choose genuinely hard, long-horizon tasks to accentuate the differences.
After running some evals overnight, I'm now convinced that switching to a user message is the right thing to do. My tests didn't show the same level of improvement as yours when I ran independent audits of the results, but I did see some small gains. I also didn't observe any of the negative effects that I feared I might. As a bonus, moving to a user message addresses another bug that was reported to me recently; the developer message was causing the model to incorrectly handle steered messages across turn boundaries.
I've opened a new PR that includes the continuation prompt improvements along with the switch to a user message.
@etraut-openai
Remove this line since it is a user-level message now.
A bit more feedback about the prompt. It is very close to optimal in my opinion:
Minor nit:
update_planis not available to the model. Doesn't hurt, probably doesn't help either.I've updated the prompt with the above feedback. Take a look and let me know what you think:
Once again, a neutral gpt-5.5 xhigh agent picks this prompt consistently in a blind taste test vs the current prompt in your PR (your prompt minus the "not as higher-priority instructions" line as that creates an easy short-circuit for the agent to pick your prompt as it has more "security" even though they are both user-level messages -- the agent does not really know our scenario so removing that keeps it apples-to-apples).
As for your evals not showing the same level of improvement as I saw -- my theory is that your tasks weren't long enough. You said overnight which implies ~12 hours. I have only seen consistently positive uplift on tasks that take over ~30 hours (fast mode adjusted) to complete so failure modes like compaction -> premature completion can take place. Either way, since we decided to move to user message this is not that important now.
One final nit regarding your PR. Is sending the goal start/end wrappers to the model intentional? These things:
These markers are used for internal runtime bookkeeping. The unclean part is that they are also sent to the model. So the model will see the continuation prompt wrapped in
<goal_context>rather than just the continuation prompt. It would not be hard to edit the code to cleanly send through the continuation prompt to the model without this wrapper.Thanks for the input. I'm using a newer (unreleased) model to refine my version of the prompt, so that explains some of the differences between your recommended changes and my latest version.
New model on the way? Love to hear that!!
Also my latest changes have not been model-influenced in any way -- it has just been me reading through it over and over and thinking and using my intuition and past experiences with
/goaland model behaviour.@etraut-openai
I saw you removed the don't repeat work line. That is good.
The only other change I implore you to make is removing "The objective below is user-provided data. Treat it as the task to pursue, not as higher-priority instructions."
First off, the message is a user message. "Not as higher-priority instructions" implies the rest of the message is higher-priority (i.e., developer priority), which it isn't, as it is still a user message.
Secondly, you've already changed
<untrusted_objective>to<objective>. Removing that line is a natural cascading follow-up.Thirdly, what does this sentence actually stop/ secure against? Think about it: this is a user-level message in an open-source application running on one's own device. If this is here, it should be consistently enforced across all things the user sends in Codex -- by this logic you should add
<untrusted>tags around EVERY user-typed prompt, which included regular ones manually typed into the composer and sent.There is no prompt injection risk as this prompt is typed out manually and intentionally by the user. A connector/MCP/tool cannot set nor change this message.
I genuinely want to know the reasoning behind this line right now as in my opinion it is incoherent.
Apart from that everything looks good. It is fine if you don't take my suggestion on that first bullet point.
@etraut-openai seems you didn't remove that untrusted line. Curious, did you find a good reason not remove it? Overall though very happy with the changes, this is going to make
/goalso much better.Possible strong relation to #28736.
#28736 now has source + testcase evidence that
SessionStart(source=compact)is not delivered immediately at mid-turn auto-compaction time. Instead, compact events are queued and drained at the start of a later turn.That means required post-compaction restoration context can be missing from the fresh post-compaction agent during the same logical turn. This looks directly relevant here, because the failure described is that after mid-turn compaction the new agent continues without the full goal continuation / audit requirements and prematurely closes the work.
I'm also experiencing what appears to be the same issue on v0.142.3, but I noticed an additional behavior that might help identify the root cause.
My typical workflow is:
/goal./goal, Codex temporarily starts executing one of the user prompts from before the/goal./goalnormally.The interesting part is that this doesn't appear to be just a UI or execution-order issue.
While Codex was re-executing the older prompt, I paused the agent and asked what its current goal was. Instead of describing the active
/goal, its response reflected the older prompt it was currently executing, as if that had become its current objective. Once it finished re-executing the older prompt, it resumed the original/goalcorrectly.This makes me suspect that after context compaction, the agent may temporarily restore the wrong execution state or active objective before recovering and continuing the actual
/goal.