Skip to content
← All insights
AI-assisted engineering13 min read

Using Codex on a real codebase without losing engineering control

How to give Codex useful repository context, shape bounded tasks, review its evidence and keep responsibility for architecture, security and production behaviour with the engineering team.

Treat Codex as an agent working inside a real system

Codex can explore a codebase, build features, review changes and investigate failures. The useful shift from autocomplete is that it can gather context, use development tools and work through several connected steps toward an outcome.

That does not turn a vague request into a sound requirement. The agent sees the repository and tools it is given, not the unrecorded product decisions, production history or organisational constraints held by the team.

A task with an observable boundarytext
Add validation to the account creation endpoint.

Required behaviour:
- Reject blank display names with HTTP 400.
- Preserve the existing response schema.
- Do not change persisted account documents.
- Add focused controller and service tests.

Run the relevant checks and summarize any assumptions.

Repository instructions remove repeated guesswork

Build commands, test conventions, architecture boundaries and prohibited technologies should live close to the code. Codex can follow repository instruction files and existing conventions more reliably than facts repeated incompletely in each prompt.

Keep those instructions testable and current. “Write clean code” provides little direction; naming the formatter, relevant test command and boundary that must not import a framework gives the agent something it can verify.

Useful repository guidancemarkdown
# Repository guidance

- Run `npm run typecheck` after TypeScript changes.
- Use `npm run generate` for route or content changes.
- Keep API credentials in server runtime configuration.
- Do not add a dependency when an existing utility covers the need.
- Preserve unrelated working-tree changes.

Ask for investigation before a risky implementation

For an unfamiliar failure, request a diagnosis supported by files, logs and tests before authorising a fix. This separates evidence from a plausible-looking patch and makes hidden assumptions easier to challenge.

For larger work, define checkpoints: understand the path, agree the boundary, implement the smallest change, then verify it. A long autonomous run is most useful when success can still be measured by concrete tests and output.

Review the diff and the evidence

A passing test suite is evidence, not proof. Review public contracts, failure paths, permissions, migrations and operational behaviour. Generated tests can reproduce the implementation rather than independently protect the requirement.

Ask what was run, what could not be verified and which assumptions remain. Inspect the actual diff instead of relying on a summary, particularly when changes touch authentication, data deletion, deployment or dependencies.

  • Does the change solve the stated behaviour?
  • Are unrelated files untouched?
  • Do tests fail for the regression they claim to protect?
  • Are external inputs and failure paths handled?
  • Did the agent verify the production-shaped boundary?
  • Can another engineer understand and own the result?

Permissions are part of the engineering model

Coding agents can modify files and may be able to run commands or access connected tools. Give the narrowest access that permits the task, review escalations and keep destructive or external actions explicit.

Secrets should not be placed in prompts, repository instructions or test fixtures. Treat generated terminal output and patches as material that can accidentally expose credentials, personal data or internal endpoints.

Use Codex where feedback can close the loop

Good tasks have an inspectable starting point and a reliable feedback loop: a failing test, build error, reproducible bug, bounded refactor or documented UI requirement. Open-ended architecture and product decisions still require accountable human judgement.

The aim is not to maximise generated code. It is to shorten the path from evidence to a reviewed change while keeping ownership of correctness with the people operating the software.