AI coding agents can already write classes, add tests, refactor code, and fix bugs.
But using an AI agent for coding is not the same as having an agentic development workflow.
If one agent receives a large task, loads the entire repository into context, and does everything by itself, the workflow is still mostly:
prompt
↓
generate code
↓
hope it is correct
A more useful approach is controlled delegation:
user intent
↓
targeted discovery
↓
small task contract
↓
required planning agents
↓
bounded implementation
↓
independent review
↓
deterministic verification
This is the approach I have been experimenting with in ModelMatrix4J , a Java project I also use to explore agent-first development.
The current workflow looks roughly like this:
┌─ Architect
User Intent ──┤
└─ Test Planner
↓
Orchestrator
↓
Implementer
↓
┌─ Reviewer
└─ Adversarial Reviewer
↓
mvnw verify
The important point is not the number of agents.
The important point is that each agent gets a specific responsibility, a bounded authority, and only the context needed for its part of the task.
What Does Agent-First Mean?
Agent-first means the repository is prepared for coding agents to work inside it without requiring a large custom prompt every time.
A fresh coding agent should be able to determine:
What is the requested outcome?
What am I allowed to change?
What must I not change?
Which repository rules apply?
Which agents are actually needed?
What evidence proves the task is complete?
If these answers exist only inside a developer's head, every new agent session needs the developer to reconstruct the workflow manually.
A better approach is to keep stable boundaries inside the repository while letting the orchestrator discover task-specific details from the codebase.
The user should provide intent and authority.
The user should not need to decide:
which files to edit
which module is affected
which agent should run
whether agents should run in parallel
which tests should be written
which order the work should happen in
Those are orchestration decisions.
Discover Before Loading Context
One lesson from agentic coding is that more context is not always better.
Giving every agent the complete product specification, architecture document, roadmap, full repository history, and every workflow file can make an agent slower and less focused.
The workflow in ModelMatrix4J now starts with read-only discovery.
user intent
↓
search affected code
↓
find affected modules and symbols
↓
find existing tests
↓
read nearest AGENTS.md
↓
read only relevant doc sections
↓
build task contract
The goal is to identify the smallest authorized impact surface before anyone starts writing.
For a small bug fix, an agent may only need:
objective
affected class
existing tests
nearest AGENTS.md
relevant contract
writable scope
It should not automatically load every repository document.
This gives a useful principle:
small context
+
strong boundaries
>
large context
+
weak boundaries
Separate Agents for Separate Jobs
ModelMatrix4J currently uses five canonical engineering roles:
architect
test-planner
implementer
reviewer
adversarial-reviewer
Their repository-level semantics live under:
.agents/roles/
The Codex-specific runtime adapters live separately under:
.codex/agents/
This separation is intentional.
The role file describes what the agent means inside the repository. The Codex adapter describes how that role is executed.
Architect
The architect is read-only.
It is used when the task affects things such as:
public or shared APIs
module boundaries
dependency direction
package boundaries
ownership boundaries
integration seams
framework containment
concurrency ownership
The architect does not need to run for every local implementation change.
Test Planner
The test planner is also read-only.
It is useful when the task changes observable behavior or contains regression-sensitive semantics such as:
timeouts
cancellation
retry behavior
ordering
concurrency
failure handling
negative paths
Implementer
The implementer is the agent that receives writable scope and performs the actual code changes.
It receives only the contract subset and repository context needed for that implementation.
Reviewer
The reviewer independently checks correctness, architecture, scope, public API impact, dependency direction, tests, and failure semantics.
Adversarial Reviewer
The adversarial reviewer intentionally looks for different classes of problems:
race conditions
lost interrupts
resource leaks
deadlocks
hidden retries
incorrect timeout behavior
nondeterminism
scope bypasses
provider leakage
accidental API expansion
false completion claims
Both review agents stay read-only and independent from the implementation agent.
Permissions Are Part of the Design
Agent responsibilities are more useful when they are also reflected in execution permissions.
A simplified architect configuration looks like:
name = "architect"
sandbox_mode = "read-only"
approval_policy = "never"
The implementer is different:
name = "implementer"
sandbox_mode = "workspace-write"
This creates a real distinction between:
thinking about a change
and
being allowed to make the change
Planning and review do not automatically imply write permission.
The role is therefore not only a persona inside a prompt. It is part of the execution boundary.
Keep Repository Instructions Small
Agent instructions can easily turn into another documentation system.
That should be avoided.
The root AGENTS.md should contain only repository-wide rules that most agents need.
For example:
Respect the current product authority.
Change only the delegated writable scope.
Do not silently change shared APIs or dependencies.
Do not implement future functionality early.
Read the nearest module-level AGENTS.md.
Keep agent context minimal.
Use the canonical verification command.
More specific rules should live closer to the module that owns them.
For example:
modelmatrix-core/AGENTS.md
modelmatrix-junit/AGENTS.md
This keeps the root file small and lets agents load instructions incrementally.
The same idea applies to other documentation.
An agent should read a specific architecture or product section because the task requires it, not because every agent always reads every document.
Use Skills for Repeated Workflows
Roles answer:
Who should do this?
Skills answer:
How should this workflow run?
ModelMatrix4J keeps a small set of workflow skills:
.agents/skills/
modelmatrix-task/
modelmatrix-review/
modelmatrix-verify/
The main orchestration entry point is:
modelmatrix-task
It replaced an earlier milestone-specific workflow because repository work is broader than roadmap milestones.
A task may be:
a feature
a bug fix
a refactor
a hardening change
a maintenance task
a roadmap milestone
The main task skill intentionally stays focused on orchestration:
- Discover the smallest relevant context.
- Create a bounded task contract.
- Select only the agents required by the task.
- Schedule work according to dependencies.
- Delegate writable work to implementers.
- Invoke the review workflow.
- Invoke final verification.
Detailed review rules live in modelmatrix-review.
Detailed verification rules live in modelmatrix-verify.
This matters because a good agent workflow should also be lazy-loaded.
task orchestration
↓
load review protocol when review starts
↓
load verification protocol when verification starts
There is no reason to carry every workflow rule through every agent context.
The Task Contract Is the Authority Boundary
Before writable work starts, the orchestrator creates a small canonical task contract.
It contains the important execution boundaries:
authorization
objective
baseline / state identity
writable scope
relevant read-only context
forbidden changes
prerequisites
acceptance evidence
verification requirements
escalation conditions
This is different from asking the user to specify implementation topology.
The orchestrator discovers the likely files and symbols first, then creates the smallest writable scope that can satisfy the requested outcome.
For example, instead of asking:
Which files should I change?
the coding agent should investigate:
Where is this behavior implemented?
Which tests already describe it?
Which module owns it?
Does the solution require a public API change?
Then it delegates the implementation with a bounded contract.
A child agent may receive a smaller subset of the parent contract, but it cannot silently weaken the parent task.
Delegation Should Be Small and Specific
A coding agent should not simply receive:
Implement the next milestone.
A better delegation is closer to:
Objective:
Fix transient retry behavior.
Writable scope:
RetryPolicy.java
RetryPolicyTest.java
Relevant context:
existing retry implementation
specific failure contract
Forbidden:
public API changes
new dependencies
unrelated provider behavior
Evidence:
transient failures retry
permanent failures fail immediately
regression tests pass
The agent knows:
what outcome is required
where it may write
what evidence is required
where its authority stops
That is more useful than giving the agent a very large prompt.
Schedule by Dependency, Not by Role
Having several agents does not mean running all of them sequentially.
The orchestrator owns a dependency graph.
Independent read-only planning can run in parallel:
architect ──────┐
├─ parallel
test-planner ───┘
↓
reconcile
Independent reviewers of the same final state can also run in parallel:
reviewer ─────────────┐
├─ parallel
adversarial-reviewer ─┘
Writable work needs stronger constraints.
parallel writers are allowed only when:
prerequisites are satisfied
+
writable scopes do not overlap
+
neither task depends on the other's output
+
each writer has a separate Git worktree
If one change depends on another, the work is sequential.
shared contract
↓
implementation using contract
↓
review
↓
verification
Parallelism is an optimization.
It is not an authority boundary.
Independent Review Comes Before Done
The implementation agent does not decide by itself that the task is complete.
After implementation, the same exact integrated state is sent to two independent read-only reviewers.
The normal reviewer focuses on:
correctness
design clarity
scope
public API
dependencies
tests
failure semantics
concurrency semantics
The adversarial reviewer asks different questions:
What happens on failure?
What assumption is not tested?
Could this leak a resource?
Could a concurrency edge case break it?
Can the implementation escape its writable scope?
Did a framework leak into a provider-neutral module?
Are we calling this complete only because the happy path passes?
Review verdicts are tied to the exact state that was reviewed.
If a reviewer finds a major issue and the implementer changes the code, the previous verdict becomes stale.
implementation
↓
review
↓
correction
↓
fresh review
This sounds obvious, but making it explicit prevents an old approval from being treated as evidence for new code.
Verification Is Different From Review
Review answers:
Does the change look correct?
Verification answers:
Does the final integrated repository actually satisfy the required checks?
For ModelMatrix4J, the canonical build command is:
./mvnw -B verify
The final verification also checks the integrated diff and writable scope.
A green Maven build is important, but it is not automatically evidence for every requirement.
For example:
build passes
does not necessarily prove:
retry semantics are correct
a regression is covered
an architecture boundary was preserved
no unauthorized file was changed
The workflow therefore tracks acceptance evidence separately from the build result.
Keep Sources of Truth Separate
One common problem in AI-assisted repositories is semantic duplication.
The same rule appears in several prompts and configuration files and eventually they disagree.
ModelMatrix4J now separates these responsibilities:
.agents/roles/
→ canonical agent responsibilities
.codex/agents/
→ Codex execution adapters and capabilities
.agents/skills/
→ reusable orchestration workflows
AGENTS.md
→ repository-wide engineering rules
module AGENTS.md
→ local module rules
docs/PRODUCT_SPEC.md
→ product behavior
docs/ARCHITECTURE.md
→ architecture and dependency boundaries
docs/ROADMAP.md
→ product sequencing and milestone authority
The Codex adapter does not redefine what an architect or reviewer means.
It points to the canonical repository role and configures execution details such as read-only or workspace-write access.
This gives one semantic authority per concern without requiring one giant document.
Agent Output Should Also Stay Small
Context optimization is not only about what an agent reads.
It is also about what an agent sends back.
A child agent should not repeat the entire task contract, product specification, architecture document, or diff in its response.
It should return the delta:
decisions
findings
changed files
evidence
blockers
escalations
residual risks
This becomes increasingly important when the orchestrator coordinates several agents.
Without compact outputs, the parent agent's context slowly fills with repeated information.
Not Every Task Needs Every Agent
Agentic development is not about maximizing the number of agents.
A small behavior-preserving local refactor may only need:
discovery
↓
implementer
↓
review
↓
verify
A public API or concurrency change may need:
architect + test-planner
↓
implementer
↓
dual independent review
↓
verify
The orchestrator selects agents based on risk and dependency.
The user does not need to know which combination applies.
A Small Agentic Setup Is Enough
You do not need ten agents, a custom Java workflow engine, or a large collection of AI-specific documents.
A useful setup can start with:
Orchestrator
↓
Implementer
↓
Reviewer
↓
Build + Tests
Then add specialized planning or adversarial review only when they solve a real problem.
The useful properties are:
- high-level user intent
- read-only discovery before writes
- small task-specific context
- clear agent responsibilities
- bounded writable scopes
- dependency-aware scheduling
- independent review
- state-bound evidence
- deterministic verification
- minimal semantic duplication
The Main Idea
The goal of agentic coding is not to run as many agents as possible.
The goal is controlled delegation with the smallest sufficient context.
A useful coding agent should be able to receive a high-level task such as:
Fix retry behavior.
Do not break the public API.
Add the required regression tests.
Then the repository and orchestrator should provide the rest:
discover
↓
scope
↓
plan when necessary
↓
delegate
↓
implement
↓
review
↓
correct
↓
re-review
↓
verify
The developer provides intent and makes decisions when real product or authority questions appear.
The coding system handles implementation topology.
For me, that is the important shift from AI-assisted coding toward agent-first development:
the right agent
+
the right authority
+
the smallest useful context
+
independent evidence
That is the direction I am currently using in ModelMatrix4J .