Builder tools
Use Codex to Fix a Failing Test Without Weakening It
Summary
Cihan's view: Give Codex the failing test and expected behavior, ask for a diagnosis before an edit, then inspect the diff and rerun the original assertion. A green test is useful only when the test still checks the right behavior. Keep the test protected, record the exact command, and ask a human to resolve any conflict between code and business rules.
A failing test creates pressure to make the test pass quickly. That can produce a weaker test instead of a correct fix. Codex can inspect a repository, change files and run local commands, so give it a narrow question and keep the assertion under review.
This is a documentation-based builder lesson with a complete fictional repository and an illustrative review record. No Codex session is claimed. Checking the supplied fixture locally is separate from having Codex diagnose or fix it.
What you will make
You will create a review record for one failing test. The record contains the expected behavior, the likely cause, the files changed, the test command and the human decision to accept or reject the patch.
Evidence label: documentation-based and illustrative. The current Codex CLI documentation describes inspecting code, making changes, running local tools and reviewing changes with /review. The repository and review record below are fictional, not captured Codex output.
Before you start
You need a terminal, Node.js 22 for this fixture, a disposable Git repository and Codex CLI access if you want to try the agent workflow. The fixture uses Node’s built-in test runner and no external dependencies. Do not use production credentials or a working tree with unrelated changes.
Create this complete practice repository:
price-tool/
src/discount.js
test/discount.test.js
package.json
The requested behavior is: a gold customer receives a 10 percent discount, while every other tier receives no discount. The assertion expecting 90 from a price of 100 is already correct. The bug is in the implementation, which still applies a 5 percent discount and returns 95.
Save package.json:
{
"name": "price-tool-practice",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "node --test"
}
}
Save the intentionally faulty src/discount.js:
export function discountFor(tier, price) {
return tier === "gold" ? price * 0.95 : price;
}
Save test/discount.test.js:
import test from "node:test";
import assert from "node:assert/strict";
import { discountFor } from "../src/discount.js";
// Keep the original assertion syntax without adding a test dependency.
function expect(actual) {
return { toBe(expected) { assert.equal(actual, expected); } };
}
test("gold receives a 10 percent discount", () => {
expect(discountFor("gold", 100)).toBe(90);
});
test("non-gold tiers keep the full price", () => {
expect(discountFor("silver", 100)).toBe(100);
expect(discountFor("guest", 100)).toBe(100);
});
test("a zero gold price stays zero", () => {
expect(discountFor("gold", 0)).toBe(0);
});
The expect helper wraps Node’s strict equality assertion. It is not an installed Jest package. The package script makes npm test the exact command for this fixture; it needs no npm install or --runInBand argument.
Initialize a local baseline before involving Codex:
git init
git add package.json src/discount.js test/discount.test.js
git commit -m "Add fictional discount fixture"
Use your normal local Git identity. If Git needs identity configuration, resolve that locally before continuing; do not put credentials in the practice files.
Three steps
1. Confirm the failure and boundary
From the repository root, record the starting state:
git status --short
npm test
For this exact fixture, the expected initial result is one failing gold test and two passing tests. The failed assertion compares actual 95 with expected 90. Save the actual exit code and failure text from your own terminal. If your result differs, investigate before asking for a patch. Do not edit the test to make the failure disappear.
2. Ask for a diagnosis before a patch
Start Codex with codex and paste:
Work only in this repository. Do not edit files yet.
The requested behavior is: gold receives a 10 percent discount, and every
other customer tier receives no discount.
The failing assertion is:
expect(discountFor("gold", 100)).toBe(90);
Inspect the implementation, this test, related tests, and package scripts.
Return:
1. the likely cause of the failure;
2. the smallest file change that could satisfy the request;
3. any missing edge-case test;
4. the exact test command;
5. a warning if the request is ambiguous.
Do not weaken, delete, skip, or rewrite the assertion to hide the failure.
Stop before editing.
Review the diagnosis against the requested behavior. If the implementation is correct and the test encodes an old rule, record that conflict for the owner instead of asking Codex to alter the assertion automatically.
3. Apply and review one bounded fix
After a person approves the diagnosis, use a second request:
Apply only the approved implementation fix.
Keep test/discount.test.js unchanged, including the original assertion and
non-gold checks. If the business rule is disputed, stop for a separate owner
decision instead of changing the test. Do not change package scripts, remove
tests, add dependencies, or edit unrelated files.
Show the diff. Run the original test command. Then report:
- files changed;
- test command and result;
- whether the gold case still returns 90;
- whether a non-gold case remains unchanged;
- any check you could not run.
Stop for review before committing.
Use Codex’s review flow or inspect the diff yourself. The documented review guidance says to check findings against the diff, expected behavior and tests before deciding on a fix.
Illustrative review record
The bounded before/after patch for this fixture changes only the gold multiplier:
--- a/src/discount.js
+++ b/src/discount.js
@@ -1,3 +1,3 @@
export function discountFor(tier, price) {
- return tier === "gold" ? price * 0.95 : price;
+ return tier === "gold" ? price * 0.90 : price;
}
The following record is fully illustrative. Its outcomes describe what this fixture should produce, not commands or results captured from Codex. Replace each expected result with your own observed result, or write UNKNOWN if you cannot run the check.
Status: needs human decision
Requested behavior: gold pays 90 from 100; non-gold pays the full price.
Cause: implementation still applies a 5 percent discount to gold.
Changed files: src/discount.js only, multiplier 0.95 -> 0.90.
Protected assertion: expect(discountFor("gold", 100)).toBe(90);
Protected files: test/discount.test.js and package.json unchanged.
Before command: npm test
Illustrative before result: exit 1; gold actual 95, expected 90; 1 fail, 2 pass.
After command: npm test
Illustrative after result: exit 0; 3 tests pass, 0 fail.
Gold check: 100 -> 90; zero price -> 0.
Non-gold checks: silver 100 -> 100; guest 100 -> 100.
Diff commands: git diff -- src/discount.js; git diff --exit-code -- test/discount.test.js package.json
Illustrative diff result: only the multiplier changes; protected-file diff is empty, exit 0.
Codex session or captured Codex execution: UNKNOWN, not run for this guide.
Uncovered behavior: negative prices, rounding, taxes and tier normalization are unspecified.
Evidence: fictional review record, not Codex execution proof.
You can run the supplied fixture and patch locally to check the expected outcomes without invoking Codex. Keep that local terminal evidence separate from any agent-session record. The illustrative record alone does not prove that your code passed or that an agent kept the test unchanged.
Acceptance checks
Accept the patch only when:
- The requested gold behavior is explicit.
- The original assertion and both non-gold checks remain unchanged; a disputed business rule is escalated separately.
- The diff contains only the approved file or files.
- The original test command runs and its result is recorded.
- Both supplied non-gold cases and the zero-price case pass without changing the test file.
- No dependency, credential, destructive command or unrelated refactor appears.
A passing test does not approve a production release. Check the business rule and the diff yourself.
Troubleshooting
- Codex edits the test first: stop and restore the test from the disposable copy, then request diagnosis only.
- The test command is unknown: inspect
package.jsonand existing instructions. Do not guess a command or claim a pass. - The failure comes from a stale expectation: record the product decision and obtain human approval before changing the test.
- The diff includes unrelated files: discard or separate the extra work before review.
No-code alternative
Read the failing test and implementation side by side, write the expected behavior in one sentence, then make the smallest manual edit. Run the repository’s documented command and inspect the diff with Git.
Limits and privacy
Codex can inspect local code and run available commands, but it cannot decide whether a business rule is correct. Keep secrets out of prompts and use a disposable repository until the workflow is familiar.
For a practical data workflow, join The Weekly Verdict.