There is a point at which your AI coding assistant stops feeling like an occasional utility and starts behaving more like a member of the team. We reached that point recently with OpenAI’s Codex.
The trigger was mundane but revealing. Work on a live client project had paused because Codex was having trouble reaching its in-app browser. The practical workaround was to let it operate the browser and desktop directly on our team member’s main PC. That worked, but it also meant that they effectively lost the use of their own workstation while Codex completed its development rounds.
Nothing had gone catastrophically wrong. In fact, Codex handled the situation gracefully: when it encountered the problem with its in-app browser, it simply switched to using our team member’s PC and browser (Codex had full permission to control that machine). When our team member and I discussed the interruption in their productivity, it was clear that we needed a more efficient solution for Codex. It was time to give the wee tyke it’s own PC and toolchain.
The lesson was simply that an advanced AI tool capable of sustained development, browser work, visual checking, terminal operations, and long-running tasks deserves it’s own environment designed for those activities.
So we stood up a dedicated, full-time development PC for Codex in our Physics Lab.
This blog post describes what we learned while tooling that machine and migrating the first work-in-progress project onto it. The migration involved a real client project, but I have deliberately omitted its name, subject matter, filenames, URLs, credentials, and business content. Those details are confidential and, more importantly, have nothing to do with the method. The useful part is the process.
Why a dedicated Codex PC made sense
For our team members, their main Windows 11 Pro desktops and laptops remain the centre of their day-to-day work. Letting an AI assistant take over one’s browser, move between applications, run local tools, and perform visual checks is powerful, but it can also be disruptive. Even a perfectly successful twenty-minute development round is inconvenient if we need the same mouse, screen, or browser session.
A dedicated machine changed that relationship in several ways:
- Codex can perform longer development and verification rounds without monopolizing our primary workstations.
- Browser and computer-use tasks can run in an environment intended for development rather than alongside unrelated personal work.
- Tool versions, environment variables, filesystem conventions, Git identities, SDKs, and backup jobs can be standardized once.
- Development projects can be isolated from user Documents folders and consumer cloud-sync behaviour (lookin’ at you, OneDrive.)
- The development machine can remain available for scheduled or long-running work, while our team members retain control of approvals and consequential decisions.
- A narrower-purpose computer reduces operational confusion. It does not eliminate security risks, but it makes the boundary much easier to understand.
That last point matters. OpenAI’s permission documentation says that full access allows the desktop app to edit any file and run networked commands without approval, and warns that this “materially increases the risk of data loss, leaks, or unexpected behavior”. The recommended starting point for most users is “Ask for approval”. We chose broader access deliberately on a dedicated development machine, with backups, clear filesystem rules, and no assumption that “full access” means “no supervision.” Be sure to read and understand OpenAI’s permissions documentation before making the same decision as we did!
The machine we built
The hardware is intentionally practical rather than exotic: a solid Dell OptiPlex PC with a 12th-generation Intel Core i7-12700, 32 GB of RAM, a 512 GB NVMe SSD, and Windows 11 Pro, connected to our Physics Lab’s UniFi LAN via 1Gbps ethernet. We have found this is enough CPU and memory for simultaneous development tools, browsers, local builds, Android emulation, WSL2, and occasional containers.
We established C:\Codex as the sole Windows development base. Windows repositories live beneath C:\Codex\Projects, with one repository per project. Linux-native repositories live inside the Ubuntu filesystem under /home/development-1/code, not under /mnt/c, so Linux permissions, links, filesystem performance, and development tooling behave normally.
We also enabled Windows long paths and Developer Mode, verified symbolic-link creation, checked BitLocker protection (and backed up a copy of the key to our team Proton Pass!), configured System Protection for easy filesystem rollbacks, and recovery-tested the backup chain (to one of our NAS appliances.) The complete C:\Codex tree is covered by a daily Synology backup. WSL source is archived daily, the full distribution is exported weekly, and both enter the same NAS protection path.
Our tested software snapshot
These are point-in-time versions verified on DEVELOPMENT-1 on August 20, 2026. They are included to make this account reproducible, not to suggest that every reader needs exactly the same stack.
| Component | Tested version | Role |
|---|---|---|
| ChatGPT/Codex Windows app | 26.814.5517.0 |
Primary ChatGPT, Work, and Codex interface |
| Codex model used for this work | GPT-5.6 Sol, High reasoning | Planning, machine setup, auditing, migration, and verification |
| Windows 11 Pro | 10.0.26200 |
Host operating system |
| PowerShell 7 | 7.6.5 |
Windows-native automation and administration |
| Git for Windows | 2.55.0.windows.3 |
Source control |
| Git LFS | 3.7.1 |
Large binary asset management |
| GitHub CLI | 2.97.0 |
Repository and remote operations |
| Gitleaks | 8.30.1 |
Secret scanning |
Windows bsdtar / libarchive |
3.8.4 |
Preservation archives and verification |
| Node.js LTS | 24.19.0 |
Windows JavaScript runtime |
| Python | 3.14.7 |
Windows automation and development |
| uv | 0.12.5 |
Python environments and dependency management |
| WSL | 2.7.12.0 |
Linux development layer |
| Ubuntu | 24.04.4 LTS |
Linux-native development environment |
| Synology Drive Client | 8.0.3.17892 |
Daily NAS backup of the development roots |
We also installed Visual Studio Code, Visual Studio, Docker Desktop, Android Studio, browser-testing tools, archive utilities, media tools, and recovery utilities. The important practice was not installing everything imaginable; it was installing from trusted sources, verifying each installation with a version check or representative workflow, and keeping a living machine inventory.
Notably, we installed RustDesk for full remote access and remote control, as we do on all our devices. This allows our DEVELOPMENT-1 PC to be effectively headless and unattended, and our authorized team members can simply remote-in and drive Codex (and perform maintenance) over a dead-simple RustDesk session. Protip: stand up your own RustDesk cloud server (we use Azure) and license the software for best performance and availability.
The distinction that matters: projects are not chats
One of the most useful things we clarified was the relationship between a project, a chat, and the filesystem.
Inside the ChatGPT desktop app, a project is the durable organizational container. OpenAI describes projects as a way to keep related chats, files, instructions, and sources together. The Projects view includes both ChatGPT projects and local projects that connect to folders on the local computer. A local project can therefore give its chats access to a source tree or codebase. See OpenAI’s Projects and chats guide.
A chat (also called a task in parts of the Codex interface) is a particular conversation and outcome inside that project. One chat might investigate a bug, another might implement a feature, and another might prepare a release. Each chat keeps its own transcript, while chats in the same project can work with the same project files and instructions.
This led us to a simple operating rule:
Use one local project per repository, attach the repository root, and open a separate chat for each distinct outcome.
We maintain one pinned machine-management project with access to the broader C:\Codex tree. That is where tooling, troubleshooting, backups, and cross-project administration happen. Each development initiative gets its own local project attached directly to its repository root (not to the shared parent directory containing every project.)
ChatGPT’s Chat and Work can participate in the same project when they are creating work product for the same initiative. Codex handles source-oriented work. The shared project keeps the context together; separate chats keep the individual outcomes intelligible.
There is another important consequence: the chat transcript is not the repository, and the repository is not the whole project history.
The filesystem contains source and working artifacts. Git contains intentional source history. A chat may contain uploaded screenshots, clipboard images, pasted notes, generated files, decisions, and recovery clues that never entered the working tree. Migrating only the folder can therefore lose meaningful context. Migrating only the chats can lose the actual project. We found that a sound migration accounts for both.
We keep durable instructions in AGENTS.md, README.md, migration records, and other checked-in documentation rather than expecting a future chat to reconstruct rules from an old transcript. OpenAI’s AGENTS.md documentation explains how Codex layers machine-wide and repository-specific guidance.
Why we used SneakerNet (a portable SSD)
Our source project lived on the original PC in a cloud-managed Documents tree. We did not want to enable OneDrive on the new development machine. We’re not OneDrive haters (we actually love OneDrive and deploy it successfully across most of our client’s systems, as well as our own). But for Codex development OneDrive’s cloud placeholders and synchronization state had already contributed to access problems, and for this migration we wanted a transport whose contents could be enumerated, hashed, disconnected, and retained unchanged.
So we put on our sneakers, opened the disks drawer, and chose a 2 TB NTFS portable SSD.
This proved faster and simpler than using cloud storage, but its biggest advantage was awesome determinism. We could create an exact preservation set, calculate SHA-256 hashes, physically move it, verify it again, and keep it as an offline recovery copy.
One small operational detail turned out to be surprisingly important: identify removable media by volume label, not by drive letter. The same SSD appeared under one drive letter on the source PC and another on the new DEVELOPMENT-1 PC. Any migration script or prompt that hard-codes E: or G: is fragile. The volume label remained stable.
The SSD also solved a permissions-boundary problem. The source-PC Codex task initially had permission to write only inside the project workspace, while our safety instructions correctly prohibited placing the capture inside the source project. We created or opened the SSD capture folder as an authorized workspace, then resumed the capture. That preserved the boundary instead of weakening it merely to make the command succeed.
Two Codex instances, coordinated by prompts
We did not attempt to make the two computers share a live agent session, and we strongly recommend you also choose to avoid this approach. Even though it feels intuitive, Codex really likes to stake out its own turf on the local PC it is running on. So, we treated the Codex task running on each PC as an operator with different local visibility:
- Codex on the source PC could inspect the original project, its task history, its cloud synchronization state, and external files referenced during development.
- Codex on DEVELOPMENT-1 could inspect the destination toolchain, canonical folders, backup layout, GitHub configuration, and eventually the mounted SSD.
- Our human development head acted as the human-controlled bridge, carrying prompts, audit reports, and decisions between them. Using SneakerNet felt like pre-internet computing, and it was pretty fun to relive those days for a few hours.
The exchange looked like this:
- The destination Codex prepared a read-only audit prompt for the source PC.
- Our human pasted that prompt into a new Codex task on the source PC.
- The source task inspected the project and returned a factual report rather than immediately changing or archiving anything.
- Our human carried that report back to DEVELOPMENT-1, where Codex reviewed the evidence and prepared the next bounded prompt.
- The source task created and independently verified the SSD capture.
- After moving the SSD, DEVELOPMENT-1 Codex verified the capture again before constructing the active project.
- A final source-PC retirement audit checked for task-only evidence and anything that would become inaccessible after deleting the old tasks.
This “prompt relay” may sound manual, but it was a virtue. Every handoff created a natural review gate. Neither instance had to guess what the other computer contained, and no broad remote-control channel was needed between the machines. Our human development head remained responsible for sanity checking and approvals while Codex did the detailed inspection, command construction, verification, and documentation.
The most effective prompts shared three characteristics:
- They stated whether the phase was read-only or write-authorized.
- They defined exact source and destination boundaries.
- They demanded evidence! Counts, sizes, hashes, tool versions, discrepancies, and explicit confirmation of what had not changed.
“Copy this project” is a weak migration prompt. We found variations of “Audit these exact inputs without changing them, report every dependency, then wait” worked flawlessly.
How we performed the first migration
We eventually codified the work as eight gates. Our first pass was a little less tidy than the final method, which is precisely why the experience was valuable.
1. Establish identity and scope
Before moving data, we identified the source path, intended destination, project type, Git state, external systems, build requirements, browser and visual-QA needs, secret-bearing files, and any decisions that only our developers could make, such as repository visibility and licensing.
The destination convention was fixed in advance: Windows repositories belong at C:\Codex\Projects\<project-name>. This prevented the migration from creating another ad hoc folder structure.
2. Perform a read-only audit
The source Codex verified that the project files existed locally and were readable, that cloud-managed files were synchronized rather than offline placeholders, and that all referenced external exports were present. It inspected Git without repairing or initializing anything and recorded the state of untracked, ignored, large, and externally referenced material.
The audit also distinguished source files from caches, generated output, temporary probes, secrets, and material that belonged only in the preservation set.
3. Create a preservation capture
The source PC produced a compressed PAX archive with bsdtar 3.8.4, including the original .git directory. External project material was archived separately. CSV manifests recorded relative paths, byte sizes, timestamps, and SHA-256 hashes.
The archive was not trusted merely because it had been created successfully. Codex reopened it, enumerated it, extracted it into a bounded verification workspace, and compared the result with the manifest. Missing, additional, duplicate, unreadable, size-mismatched, timestamp-mismatched, and hash-mismatched files were all reported explicitly, even when every count was zero. Happily, we did not encounter a single error in our SneakerNet migration, and it was fast as heck.
4. Verify again after transport
Once the SSD was attached to DEVELOPMENT-1, the destination Codex resolved it by label and checked the README, archive sizes, and SHA-256 values before copying anything.
We retained three distinct layers:
- the original SSD capture;
- a received copy under the protected
C:\Codextree; - an immutable local migration snapshot separate from the active workspace.
Each local copy was verified against the transport manifest. Only then did we extract a working source copy.
5. Reconstruct a clean active workspace
This phase produced one of the migration’s more interesting findings. The source contained a substantial .git directory, but it did not contain usable commits, refs, or an index. It did contain valid loose objects and recovery evidence.
The wrong response would have been either to discard .git because it looked broken or to assume it represented healthy history because it existed. We preserved it byte-for-byte in the immutable snapshot, generated a recovery catalog, and then created a clean active repository with the decision documented.
We excluded caches, local-only state, temporary audit files, and sensitive preservation material from the active tree. We created an appropriate .gitignore, project instructions, setup documentation, migration records, and verification commands.
6. Scan before publishing
We ran Gitleaks over the candidate repository and supplemented it with project-specific signature checks. This layered approach mattered: a general scan returned clean, but targeted inspection found API-key-shaped material embedded in exact archival source files.
Those files remained in the restricted preservation set and outside Git. The possible credential was never printed into a chat, log, manifest, or commit. The safe, reviewed active content proceeded separately.
Large binary assets were classified before the first commit and assigned to Git LFS. Doing that early avoided a later history rewrite.
7. Establish and verify GitHub
Codex took the lead on Git because, well, it’s really good at Git and GitHub. It configured the repository, branch, identity, HTTPS remote, Git Credential Manager, and LFS policy; created intentional commits; established a private GitHub repository; pushed the branch and LFS objects; and then checked the remote state independently.
This was not simply “the push command returned zero.” We verified the branch, commit, working-tree cleanliness, object integrity, LFS integrity, and synchronization with the private remote.
8. Back up before retiring the old copy
Finally, we ran and verified our LAN-based Synology NAS backup after the active repository and preservation records were present. Only when the SSD, local preservation copy, GitHub repository, functional project, and NAS backup agreed did we retire the redundant source-PC Codex projects and files.
The old Codex tasks were deleted last because their removal was permanent. Cloud-managed source folders were treated separately because deleting them could propagate through synchronization.
The mistake that improved our runbook
Our initial source capture was complete and correctly verified, but we performed the deepest task-history retirement audit afterward. That later audit recovered additional clipboard uploads, pasted-text attachments, external references, and concise sanitized handoffs from old Codex tasks.
So we implemented an extra housekeeping and cleanup run, so that nothing was lost.
Our improved rule is now:
Audit for retirement before creating the first capture.
The complete pre-capture audit must cover the filesystem, Git, external assets, task uploads, pasted attachments, chat-only decisions, secrets, signing material, hosted systems, and recovery requirements. Once that inventory is complete, the preservation capture can be made in one pass.
That lesson alone will make our next migration faster.
Our practical migration checklist
For anyone planning a similar move, this is the condensed version of our method:
- Define the canonical destination before copying anything.
- Audit the source read-only, including Git, cloud placeholders, links, external files, and chat-only assets.
- Preserve an exact source snapshot before cleaning or repairing it.
- Keep exact preservation evidence separate from the active repository.
- Use SHA-256 manifests and verify archives after creation and again after transport.
- Resolve removable drives by label, not letter.
- Do not confuse the existence of
.gitwith valid Git history. - Scan the exact commit candidate for secrets, using both a general scanner and project-aware checks.
- Configure Git LFS before the first commit containing large binaries.
- Keep durable guidance in
AGENTS.mdand repository documentation, not only in chat transcripts. - Verify the project functionally on the destination machine.
- Verify GitHub and a covering backup before deleting source files or old Codex tasks.
What has changed for us
The most positive part of this experience was not that Codex (running 5.6 Sol High) issued commands precisely and quickly. It was the quality of our human-Codex collaboration.
When the original browser problem interrupted development, Codex Sol High did not bluff its way forward. It surfaced the constraint, protected the project, and helped convert an inconvenience into a more resilient development environment. During the migration it repeatedly favoured evidence over assumption: inspect first, preserve before repair, hash before trust, verify after transport, and delete last.
The result is not merely a second PC with ChatGPT installed. It is our deliberate Codex development system: one canonical project root, one repository per local project, separate chats for separate outcomes, durable instructions, verified source control, offline migration evidence, private remotes, and tested backups.
That structure makes us more comfortable giving Codex substantial responsibility (including full PC control), because the responsibility now sits inside boundaries we both understand.
Our next Codex project migration will follow the improved one-pass runbook. We expect it to be a walk in the park, and that is exactly what a Physics Services project will always achieve.
Further reading
- OpenAI: ChatGPT desktop app
- OpenAI: Projects and chats
- OpenAI: Custom instructions with AGENTS.md
- OpenAI: Permissions
This article describes our own operational experience as of August 20, 2026. Product behaviour and version numbers will change; consult current OpenAI documentation before reproducing our setup. Feel free to copy-paste this post as context!

