A coding agent can do exactly what you asked and still be completely wrong.

It can run a valid test command that bypasses required setup, edit the correct file in the wrong worktree, or introduce a reasonable abstraction that violates an unwritten architectural decision. It can repeat a reviewer subagent’s confident hallucination as fact. It can declare the task complete while CI is still glowing red.

Those failures do not necessarily mean the model cannot code. More often, repository knowledge is implicit and the workflow depends on the agent recalling prose at exactly the right moment.

We treat reliability as a prompting problem: write better instructions, lengthen the system prompt, or repeat important rules in bold. That helps, but prose cannot guarantee compliance during a large change.

Reliability improves when we stop relying exclusively on agent memory and begin engineering the environment in which the agent acts.

Move more of the workflow out of prose and into repository-owned controls and execution boundaries: AGENTS.md, specialized skills, permissions, sandboxing, hooks, validation planning, review contracts, synchronization tooling, and CI.

These controls primarily reduce accidental noncompliance and workflow drift. They do not make an untrusted agent or compromised toolchain safe.

The result is not a magical autonomous programmer. It is something much more useful: a paved road where the easiest workflow is also the correct workflow.

The repository itself becomes the harness.

Treat the repository as the control plane

A reliable coding-agent setup is not one enormous instruction file. It is a collection of layers, each responsible for a different kind of control.

LayerPurpose
AGENTS.mdDurable project constitution
SkillsSpecialized procedural playbooks
Tool permissions and sandboxingLimits available resources and operations
HooksImmediate deterministic reflexes
Validation plannerDetermines the evidence required by a change
ValidatorExecutes the planned checks
Review contracts and subagentsIndependent judgment with explicit evidence requirements
CINon-negotiable merge backstop
Sync and harness testsConfiguration management for the control plane

By “validation planner,” I mean a repository-owned tool that maps changed files and change categories to the checks required as evidence. Implementations vary by agent product: some support hooks or repository-local skills, while others expose only a subset of these controls. Assign each requirement to the most deterministic layer available.

Permissions determine what the agent can do. Hooks inspect what it is attempting to do. Validation establishes what the change actually did. CI determines whether it may merge.

A useful design rule is:

Put each requirement in the cheapest, most deterministic layer capable of enforcing it reliably.

An architectural constraint may remain in documentation because it requires judgment. A forbidden patch path belongs in a hook because it is deterministic to detect. A security boundary belongs in application code and tests, while a merge requirement belongs in CI because local tooling can be missing or bypassed.

That creates a natural progression:

  1. Explain the intended behavior.
  2. Make the intended behavior easy.
  3. Block predictable mistakes.
  4. Demand stronger evidence for riskier changes.
  5. Refuse to merge without the required proof.

The mistake is expecting any one layer to do all five jobs.

What this looks like end to end

Suppose an agent changes an API schema.

The post-edit hook records the changed schema paths and operation types. The validation planner consults the repository’s impact map and requires schema validation, client generation, frontend type-checking, and contract tests. The validator runs those checks during implementation. A reviewer inspects a stable committed head revision and cites the generated client and its consumers. CI independently derives the same plan and exposes one aggregate required check to branch protection.

No single prompt has to remind the agent about every downstream consequence. The repository carries that knowledge forward.

AGENTS.md is a constitution, not a prompt scrapbook

A useful AGENTS.md provides the repository’s durable written context by answering a small set of high-value questions:

  • What is this product, and which documents are authoritative?
  • Where does each kind of code belong?
  • How should work proceed, and how is the repository validated?
  • Which product, architecture, privacy, and security invariants must not change casually?
  • Which durable documents must change when behavior changes?
  • What must an agent never do?

The goal is not to dump every command, convention, and historical anecdote into one file. The strongest instructions encode workflow and intent:

  • Confirm the current worktree and isolate concurrent work before editing.
  • Keep patches repository-relative.
  • Use a topic branch and open a draft pull request.
  • Continue until CI is green and the branch is mergeable.
  • Update durable documentation in the same change as the behavior it describes.

The agent is told not merely how to modify files, but what completion looks like. Because commands and layouts change, the constitution should focus on durable decisions, with narrower guidance closer to the code it governs.

A useful test is whether a statement requires interpretation.

“Authentication remains local-only in version one” is an architectural invariant. It belongs in AGENTS.md and architecture documentation.

“Do not invoke raw pytest; use the repository validator” is mechanically detectable. It may begin as prose, but it should eventually graduate into a hook.

“Any schema change requires generated-client verification” belongs in the validation planner and CI.

Prose is the starting point, not the final enforcement mechanism.

Hooks should prevent cheap, predictable mistakes

Hooks are most useful when they behave like reflexes: fast, local, deterministic, and actionable. They should catch mistakes that are easy to identify and annoying to recover from, not attempt to replace application security, code review, or comprehensive validation.

A practical hook loop might be:

  1. Before applying a patch, reject unsafe paths.
  2. Before command execution, block unsupported validation commands.
  3. After edits, queue the evidence implied by the changed files.

Patch-path containment

An agent working in the wrong directory can still produce a syntactically correct patch, which makes the failure look legitimate. A patch-path hook can parse added, updated, deleted, and moved paths, then reject absolute paths, .. traversal, and targets whose resolved path escapes the repository root. It does not need to understand the change; it only needs to enforce containment.

Validation-command routing

A repository’s preferred validation entrypoint may establish environment variables, select tests, generate clients, start dependencies, or coordinate packages. Running pytest or npm test directly can produce a green result while skipping part of that contract.

A useful command hook therefore needs to recognize wrapped and indirect invocations such as:

python -m pytest
bash -lc 'npm test'
env FOO=bar pytest
pytest && ruff check .

Shells, environment tools, command chains, and package runners bypass hooks that compare only the first token. Rejection should point to the supported repository-owned validation entrypoint, turning enforcement into navigation.

Queue evidence instead of running everything

The obvious post-edit hook is “run all tests.”

It is also often the wrong hook.

Running the entire suite after every small change slows iteration and encourages batching or workarounds. A better post-edit hook maps changed paths to deduplicated test targets and stores them for the validator, providing relevant feedback without paying for the full suite after every patch.

Hooks collect obligations; the validator settles them.

The hook records what the edit implies. The validation planner decides how much evidence is sufficient.

Hooks are not security boundaries

Hooks may be unsupported, disabled, bypassed, or invoked outside the harness entirely. Anything security-critical still belongs in the application’s policy layer, sandboxing, permissions, negative tests, and CI. A hook can stop an agent from accidentally running the wrong test command; it should not be the only thing preventing an unsafe application action.

Make validation understand the architecture

The validation planner should answer a more important question than “Which command do we normally run?”

Given these changed files, what evidence is sufficient?

That requires an explicit impact map: a machine-readable description of how changes propagate through the repository. It might look roughly like this:

rules:
  - match: "api/schema/**"
    require:
      - schema-validation
      - generated-client
      - frontend-typecheck
      - contract-tests

  - match: ".agents/**"
    require:
      - harness-tests

  - match: ".github/workflows/**"
    require:
      - full-gate

The format matters less than keeping the mapping explicit, versioned, readable, and testable.

An impact map may encode source-to-test paths, cross-package dependencies, generated-client requirements, domain acceptance tests, and broad-risk files that trigger the full gate.

Policy documents can warrant tests too. If changing AGENTS.md alters the behavior of every coding agent working in the repository, it is not “just documentation.” It is executable governance. A harness test might assert that AGENTS.md still requires reviewers to inspect the committed revision rather than an uncommitted working tree.

The map should fail safely when uncertain and escalate ambiguous, infrastructure-heavy, or unusually broad changes. A stale impact map creates false confidence, so the mappings themselves should be covered by tests.

Targeted validation is an optimization, not an excuse to under-test.

Use agents for judgment—and constrain their evidence

Subagents are valuable when delegation creates independent judgment: code review, adversarial analysis, unfamiliar codebase research, or investigation of genuinely separable domains. They are usually unnecessary for deterministic chores such as running commands, editing obvious paired tests, or repeating the primary agent’s summary.

A second model running pytest is not independent judgment. It is an expensive shell wrapper.

For important reviews, dispatch by domain when useful, but require the primary agent to validate findings. After substantial fixes, a fresh reviewer can reduce inherited assumptions; if findings stop decreasing, escalate rather than loop ceremonially.

Define what reviewers may claim

Adding a reviewer is not enough. The harness should define what counts as knowledge.

A reviewer that trusts the pull request description or a drifting working tree can review code that does not exist at the claimed revision. Working-tree review is useful during implementation, but the final authoritative review should examine a stable revision. A useful reviewer contract requires:

  • Explicit base and head SHAs, with files read from the reviewed revision.
  • Revision-pinned file, symbol, and relevant line-range evidence.
  • Wrappers traced far enough to verify the claimed behavior.
  • Framework semantics verified rather than inferred from names.
  • Speculative findings dropped or labeled as open questions.

The mindset is simple: inspect the implementation, not the report. Do not promote uncertainty into a defect merely because the finding sounds sophisticated.

A reviewer should be allowed to say, “This remains an open question.” That is more valuable than an unsupported false positive.

The harness should constrain not only what an agent can do, but also what it may claim to know.

CI is where guidance becomes a merge contract

Local controls improve behavior, but they are not authoritative. Hooks may be missing, tools may change, developers may use a different harness, and local state can drift.

CI must independently derive the required evidence.

A mature workflow can use the same planner to select validation scope, generate parallel lanes, require coverage or harness acceptance, and produce a stable aggregate result. Branch protection needs one authoritative answer: did the required evidence pass?

Using the same planner locally and in CI prevents two validation systems from slowly diverging. Local hooks guide the agent toward the paved road; CI decides whether the destination has actually been reached.

Make the rules portable after the canonical harness is stable

A repository may be used through Codex, Claude Code, Cursor, OpenCode, or another harness, each with its own configuration and conventions. Maintaining every copy by hand works only until one changes and the others do not.

Once one canonical harness is stable, generate product-native formats from canonical sources where supported. Disable unsupported resources intentionally, preview writes, restrict synchronization to known generated paths, and let CI detect drift.

Agent configuration is infrastructure.

Test the harness itself

The harness changes agent behavior, so treat it as production code. Test shell-wrapper bypass detection, hook output shape, file-to-test mappings, broad-risk escalation, CI planning, important policy statements, and generated-file consistency.

Those tests may look strange if documentation is assumed to be passive. In an agent-driven repository, removing a sentence from AGENTS.md can be behaviorally equivalent to deleting a guard clause.

Harness tests are where ordinary bugs surface: a hook may detect pytest but miss python -m pytest, return malformed output, or queue a target the validator never consumes. Treating the harness as mystical prompt configuration only makes those bugs harder to see.

Common failure modes

Failure modeBetter pattern
Everything lives in one giant instruction fileKeep durable intent in prose and move deterministic rules into mechanisms
A local hook is treated as a security boundaryEnforce security in application policy, permissions, tests, and CI
Every edit runs the full suiteQueue targeted obligations and reserve the full gate for broad-risk changes
Subagents perform deterministic choresDelegate only work that benefits from independent judgment
Reviewer output is repeated without verificationRequire revision-specific evidence and independent validation
Every agent product gets hand-maintained copiesGenerate from canonical sources and detect drift
The impact map falls behind the architectureTest the map and escalate uncertainty
A rule exists locally but not in CIIndependently enforce every merge requirement

A starter repository blueprint

A Codex-centered implementation can remain fairly small:

AGENTS.md

.codex/
  config.toml
  hooks.json
  hooks/
    enforce_patch_paths.py
    enforce_validation_script.py
    queue_tests_for_edited_file.py
    test_enforce_patch_paths.py
    test_enforce_validation_script.py
  skills/
    test-engineering/
      SKILL.md
  tools/
    validate.py
    validation_targets.py
    test_validate.py
    test_validation_targets.py

.agents/
  skills/
    code-review/
      SKILL.md
      code-reviewer.md

.github/
  workflows/
    validation.yml

.agentsync/              # optional portability layer
  config.toml
  state.json

The filenames matter less than the separation of responsibilities: prose explains, permissions constrain, hooks catch deterministic mistakes, the planner selects evidence, the validator executes it, review contracts guide judgment, CI enforces the merge contract, and synchronization prevents drift.

A sensible adoption order is:

  1. Write the repository constitution.
  2. Set conservative tool permissions and sandbox defaults.
  3. Create one official validation command.
  4. Block obvious ways around that command.
  5. Add changed-file evidence routing.
  6. Escalate broad-risk paths.
  7. Add a review skill with an evidence contract.
  8. Make CI use the same validation planner.
  9. Test the harness itself.
  10. Add cross-harness synchronization after the canonical setup is stable.

Portability comes last; otherwise automation only produces synchronized inconsistency.

The paved road should be the correct road

The purpose of a harness is not to imprison the coding agent.

It is not to turn every file edit into an approval ceremony, require five reviewers for a typo, or make the agent recite the repository constitution before running a formatter.

The purpose is to make the intended workflow discoverable, efficient, and difficult to bypass accidentally.

Prompts remain useful; models still need context, goals, and judgment. But the highest-value instructions should not remain wishes forever. Mature expectations should become scripts, mappings, tests, contracts, and gates.

The best coding-agent prompt may not be a prompt at all.

It may be a repository whose rules, tools, tests, and gates all agree about what “done” means.