In an era where LLM models are released one after another, how do we keep our product codebase in sync?
Honestly, this question has been quietly nagging at me lately.
The ai-workflow-agent I'm developing is a workflow engine that automatically handles planning → design → implementation → testing → documentation based on GitHub Issue content. Internally, it uses both OpenAI's Codex model and Claude, with the Codex default model being gpt-5.1-codex-max.
Then gpt-5.2-codex was released.
"We should probably upgrade," I thought, but how to safely switch model names scattered across 16 files—that's today's story.
Started with Information Gathering (and Got Trapped)
The first thing I did was ask ChatGPT about the gpt-5.2 model lineup.
When I asked "What lightweight model should I use for 5.2?", the initial response was "There's gpt-5.2-mini." But when I asked again, it corrected itself: "gpt-5.2-mini doesn't exist in the official API."
This is the trap.
When you ask an LLM about LLM model information, hallucinations can creep in. Especially for newly released models, which are likely not in the training data, always verify with official documentation as the final step. I also confirmed through OpenAI's API documentation and model list page before making decisions.
Ultimately, I settled on this approach:
- Top-tier model (max): Replace
gpt-5.1-codex-max→gpt-5.2-codex - Lightweight model (mini): Keep
gpt-5.1-codex-minias-is
The reason is simple: there wasn't yet an official lightweight Codex model in the 5.2 series. Can't switch to a model that doesn't exist. "Upgrade only the top tier, keep the lightweight"—mundane but the most realistic decision.
The Alias System as "Insurance"
Let me talk a bit about the design here.
In this project, instead of hardcoding model names directly into the code, we insert an alias system as middleware. This is defined in codex-agent-client.ts.
export const CODEX_MODEL_ALIASES: Record<string, string> = {
max: 'gpt-5.2-codex', // Default, for complex tasks
mini: 'gpt-5.1-codex-mini', // Lightweight, cost-efficient
'5.1': 'gpt-5.1', // General purpose
legacy: 'gpt-5-codex', // Backward compatibility
};
Users specify with aliases like --codex-model max or --codex-model mini. This constant handles all resolution to actual model IDs.
graph LR
A[User Input] --> B{Alias?}
B -->|max| C[gpt-5.2-codex]
B -->|mini| D[gpt-5.1-codex-mini]
B -->|legacy| E[gpt-5-codex]
B -->|Full ID| F[Pass through]
This design was introduced during the gpt-5-codex → gpt-5.1-codex-max migration (Issue #302), when I thought "this will happen again." Like learning to ride a bike—once you learn the pattern, it gets easier next time. Indeed, this migration only required changing the alias resolution in one place for the core logic to be complete.
The legacy alias is surprisingly crucial. When you want to lock a workflow to the previous version, --codex-model legacy lets you instantly roll back. It's insurance against "what if the new model has issues?"
Automatic Model Selection Based on Difficulty
Another feature: the project has a mechanism to automatically switch models based on Issue difficulty (Issue #363).
graph TD
A[Issue Difficulty Assessment] --> B{Difficulty}
B -->|simple| C[All phases: mini]
B -->|moderate| D[Phase-specific distribution]
B -->|complex| E[All phases: max]
D --> F[Strategy phase: execute→max / revise→mini]
D --> G[Code phase: execute→max / revise→max]
D --> H[Documentation phase: all steps mini]
The key point: review steps always use mini regardless of difficulty. Review is "verification," not "creation," so a lightweight model suffices. Conversely, code phase revise (corrections) uses max even for moderate difficulty. Skimping here degrades correction quality and ultimately costs more due to rework.
These trade-offs are the result of operational tuning. We didn't have perfect distribution from the start—it was through repeated cycles of "mini produced sloppy revisions" and "max costs spiked" that we reached the current configuration.
The Actual Migration: Bulk Replace with Claude Code
Now, the actual migration. I used Claude Code (Sonnet 4.5) to proceed.
First, scope confirmation. Searching for gpt-5.1-codex-max yielded 261 hits. Breakdown: 3 code files, 5 test files, 8 documentation files (16 files total).
The work itself was as simple as telling Claude Code "I want to replace gpt-5.1-codex-max with gpt-5.2-codex," and it sequentially updated code, type definitions, and documentation. However, I hit one snag here.
Where I Actually Got Stuck
The initial npm test resulted in 18 test failures.
The cause: test cases for whitespace handling in test files weren't fully caught. For example, tests like this:
// Test for alias with leading whitespace
expect(resolveCodexModel(' max')).toBe('gpt-5.1-codex-max'); // ← This changes too
// Test for alias with tab characters
expect(resolveCodexModel('\tmax\t')).toBe('gpt-5.1-codex-max'); // ← This too
Since we changed max → gpt-5.2-codex, all tests validating max alias resolution need their expected values updated. It's obvious in hindsight, but the initial replacement updated the "main max alias test" while missing the "whitespace-prefixed max" tests.
Two lessons learned:
- Simple string replacement isn't enough. Tests validating alias resolution must be searched by resolved model name, not alias name, to catch all cases
- More tests is justice. We had 30 unit tests, which is why we caught the omission. Without tests, this would've become a production bug like "wait, whitespace-prefixed input is using the old model?"
After corrections, retest. All 72 Codex model-related tests passed. Build succeeded.
Test Suites: 1 passed, 1 total
Tests: 30 passed, 30 total
Incidentally, other tests (rewrite-issue.test.ts, Git permission tests) failed during full test runs, but these were unrelated pre-existing environment issues. Separation is easy with git diff to check changed files.
Final Change Summary
The commit message looked like this:
feat: Update Codex default model to gpt-5.2-codex
- Change DEFAULT_CODEX_MODEL from gpt-5.1-codex-max to gpt-5.2-codex
- Update 'max' alias to resolve to gpt-5.2-codex
- Update all documentation to reflect the new default model
- Update test expectations to match the new model
16 files, 56 lines changed. Equal insertions and deletions (56 insertions, 56 deletions) perfectly represents the nature of this work: not adding new features, but replacing existing values.
I was conscious of change priorities:
- Core code (
codex-agent-client.ts,commands.ts,agent-setup.ts) — this is the heart - Test files (5 files) — updating expectations
- Documentation (8 files) — README, CHANGELOG, CLI reference, etc.
This order avoids the scenario where "core is updated, tests are mid-way" if problems arise. Core and tests should pass together; documentation comes last.
Retrospective: Making Model Migration "Not Scary"
What I felt anew through this migration: the importance of not scattering model names throughout the codebase.
Without the alias system, this would've been manually rewriting 16 files at 56 locations, visually confirming each one. Thanks to aliases, the substantial changes were just 1 line in CODEX_MODEL_ALIASES and 1 line in DEFAULT_CODEX_MODEL. Everything else was updating tests and documentation referencing those values.
Another point: caution when using LLMs to gather LLM model information. While convenient, especially for newly released models, hallucinations are common. ChatGPT's response wavering confirmed the importance of "verify with official documentation."
When gpt-5.3-codex becomes available in the API, we'll just repeat the same procedure. Rewrite alias resolution, run tests, update documentation. Having a design where this cycle works smoothly might be the biggest takeaway from this migration.
After migration, the workflow runs fine with the new model:
2026-02-09 13:09:32 [INFO ] Using model override for Codex Agent: gpt-5.2-codex (phase=implementation)
2026-02-09 13:09:32 [INFO ] [CODEX EVENT] type=thread.started
2026-02-09 13:09:36 [INFO ] [CODEX REASONING] [item_0] **Clarifying file write approach**
2026-02-09 13:09:36 [INFO ] [CODEX EXEC] [item_1] Completed ✓
DevLoop Runner, a development automation tool based on ai-workflow-agent, has also been updated to gpt-5.2-codex in line with this migration. Check it out if you're interested:
Reference Books
For those who want to deepen their understanding of Claude Code development and refactoring practices, the following books are highly recommended:
[📦 商品リンク: moshimo-book-9CeFY]
[📦 商品リンク: moshimo-book-fINTJ]
[📦 商品リンク: moshimo-book-5line-refactoring]
Reading these while experimenting in real projects will help you build a better toolkit for design decisions.