Agent runtime CWD/worktree is not rebound when navigating between project chats
Title: Agent runtime CWD/worktree is not rebound when navigating between project chats
Severity: High / data integrity and business-context integrity risk
When working across multiple projects, clicking into an existing chat under a different project does not appear to update the agent tool runtime CWD. The UI can indicate I am in one project, but shell/tool calls may still execute from a previous project’s repo.
In my case, I was navigating between projects including:
- MyAISpeakEasy
- Eventryx
- ArticleMngrSLN
But the agent runtime still reported and operated from:
C:\Users\Richard\source\repos\MyAISpeakEasy
Expected:
When I open or switch to a chat associated with a project, the agent runtime CWD should be rebound to that project’s workspace/repo. The visible project context, chat context, runtime CWD, Git worktree root, and project-scoped tool context should all match.
Actual:
The visible project/chat context can differ from the shell/tool CWD. This means I may believe I am working in Eventryx or ArticleMngrSLN, while agent commands, file operations, Git operations, and project-scoped tooling are still targeting MyAISpeakEasy.
Why this matters:
Each project has its own CWD and Git worktree. If project navigation changes the visible context but not the runtime CWD, generated files, configuration changes, setup scripts, git status checks, staging, commits, or other repo-affecting operations can silently affect the wrong repository.
This also affects project-scoped tools. For example, the ContentTraker plugin relies on the current working directory to associate a local project/repo with a ContentTraker workspace. That ContentTraker workspace represents the business-domain knowledge for the application.
If the runtime CWD is stale, ContentTraker setup or lookup operations can associate the wrong application with the wrong ContentTraker workspace, or retrieve business-domain context for the wrong project. That can lead the agent to reason from incorrect domain knowledge while making code or configuration changes.
This is especially dangerous in agent workflows because the assistant may autonomously edit files, run commands, configure tooling, inspect Git state, or use business-domain context based on the stale CWD.
Suggested invariant:
Chat/project context == agent runtime CWD == Git worktree root == project-scoped tool context
Suggested fixes:
- Rebind the agent runtime CWD whenever a chat/project is opened.
- If an existing runtime cannot be safely rebound, block tool execution and require a new runtime/session for that project.
- Clearly display the active runtime CWD near the chat/tool area.
- Warn when the visible project does not match the runtime CWD.
- Before file, Git, or project-scoped tool operations, automatically verify:
- pwd
- git rev-parse --show-toplevel
- any project binding file used by the tool, such as .contenttraker/project-binding.json
- Prevent staging, commits, setup scripts, file edits, and project-scoped tool setup/lookups when the runtime worktree does not match the visible project.
Repro:
- Open a chat in Project A, for example MyAISpeakEasy.
- Confirm the runtime CWD with pwd or git rev-parse --show-toplevel.
- Navigate to an existing chat under Project B, for example Eventryx or ArticleMngrSLN.
- Ask the agent to report CWD or run a repo-specific/project-scoped command.
- Observe that the runtime may still be in Project A, despite the UI showing Project B.
Impact:
High. This can cause incorrect file edits, dirty worktrees in unrelated repos, accidental setup/configuration in the wrong project, accidental staging or commits from the wrong repository, incorrect ContentTraker workspace association, and incorrect business-domain context being used during agent work.
Concrete example:
A ContentTraker configuration/readiness check was requested while I believed I was working in another project context, but the runtime CWD was still:
C:\Users\Richard\source\repos\MyAISpeakEasy
Because ContentTraker uses the current working directory and .contenttraker/project-binding.json to associate a repo with the application’s business-domain workspace, the operation targeted the MyAISpeakEasy project context rather than the intended project.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
This looks like another case where runtime state needs a stable task/worktree identity, not just UI navigation state.
If an agent run is bound to a project chat, the execution context probably needs explicit fields like root workspace, active worktree, branch, task id, and parent session. Otherwise navigation can make the visible chat and actual runtime disagree.
Was the dangerous part here wrong reads, wrong writes, or both?
I think i have more insight here as to what is happening where.
As I understand it, the current working directory (CWD) is a very important aspect of the work tree scope. If we change branches or do whatever, whatever files are being changed are recorded in the work tree. the Branch only gets updated when files are committed.
Hence, switching branches and the work tree needs to be coordinated because the convention is one current working directory, one branch, one work tree.
when I execute my plugin, the plugin and project default to the most recent worktree? and without noticing, the plugin code then is being updated by a worktree on a project in branch depending on the directory the plug decided to use?
when it comes to plugins, OpenAI documentation is: "It packages things Codex can use, such as skills, app integrations, MCP servers, and hooks. OpenAI’s Codex docs define plugins as bundles of skills, app integrations, and MCP servers for reusable workflows. A plugin can include reusable instructions, app connections, MCP server configuration, and lifecycle hooks."
however, my plugin is used in the scope of a project, established with the use of an API Key, which is then tranlsated by a tokenprovider, which creates a JWt token. This token must be passed to my MCP server, as the JWT token manages the scope of business domain knowledge for one CWD/Project/Repo (all defining one-to one-to one convention)
Hence the execution of the Plugin needs to establish that scope, to find the API key, and then resolve the API key to a scope, before engaging the MCP server.
I used my current directory as a means to "activate?" the plugin, from the Project I was in, and hence thought the scope of the plugin was anchored to the project - WRONG!
I've since adjusted my plans in that the first off is the installation of the plugin as it traditionally is done, and then from the directory I use the plugin with some command lines to actually configure it for that project. It's a two-phase configuration. I would really like to see it to be much better in terms of configuration, and that we can have configuration of plugins at the project level using capabilities of displays and panels, just like in Visual Studio. The hooks are a good start. I'm already using the hook that came with the plugin now, so I can pass in the current working directory and activate the correct MCP server local proxy on a different port for each directory. That way I can work on multiple projects and not have it all go through one proxy.
I realize these are early days, but an MCP server is getting to be more and more used in the scope of a project. There's not a great correlation between establishing the auth code that's required for an MCP server and the project that's defined.
That makes sense. I think the key issue is that CWD is being used as both execution location and auth/scope selector, but it is too mutable to be the authority boundary.
Your two-phase setup sounds like the right workaround: install plugin globally, then bind it per project/worktree. But ideally Codex would expose a first-class project context to plugins/MCP: visible project id, runtime CWD, git root, branch/worktree, plugin config scope, and secret/auth scope.
For safety, the invariant should probably be fail-closed:
visible project == runtime CWD/git root == plugin project binding == MCP JWT audience/scope
If any one of those disagrees, project-scoped MCP calls should not run.
Do hooks currently expose enough state to compare visible project vs runtime CWD, or only the runtime side?
Your ContentTraker scope problem maps cleanly to a Work Packet model: repo/project identity, runtime CWD, MCP auth scope, allowed context, and audit trail bound together.
If useful, I can sketch how your Codex + ContentTraker flow would look as an Aideps packet. If the shape fits, we’re doing $500 async pilots for one repo/workflow.
<img width="761" height="706" alt="Image" src="https://github.com/user-attachments/assets/6c23c399-6008-4b08-af80-79da0f9163df" />
Severity High.
This issue is not a duplicate of:
#19664 #19647
This issue gave me a fear of multi-tasking.