Check the combined version when two AI coding agents contribute to the same release. A clean merge tells you that the version-control system combined the changes without an unresolved textual conflict. It does not establish that the changes agree about a shared field, default or user-visible behavior, and the test results each agent reported were about a version of the code that no longer exists.
This guide starts after separate contributions exist. The useful artifact is a short record of their interactions and the checks run on the combined candidate. It is different from deciding whether to use parallel agents or giving each one a separate workspace. The sections below set out the six places contributions meet, what the merge tool itself claims to resolve, a worked example of a value crossing both changes, why a conflict resolution is a third change, the ways a green build still ships a broken release, and the record that ties the evidence to the version that actually went out.
- 01Test the combined candidate.Results from separate branches refer to different code states. Release evidence comes from tests run on the version being released.
- 02Inspect shared assumptions.Changes in different files can disagree about the same interface or default. A merge tool compares text, not meaning.
- 03Keep resolution intent visible.A conflict resolution should preserve the required behavior, not merely remove markers. Record what was chosen and what was given up.
- 04Pin the evidence to a version.Every check result names the candidate it ran on. If the target moves, decide which results still apply rather than assuming all do.
01 — The ClaimWhat a clean merge does and does not tell you
“Merged cleanly” is one of the most reassuring phrases in software and one of the narrowest. It means that for every line both branches touched, the tool could decide mechanically which text to keep, or that no line was touched by both. It says nothing about lines that were touched by one branch and relied on by the other. Those are exactly the lines two agents working on related features produce.
The reassurance compounds when each agent reports its own tests passing. Each report is true. Each describes a different codebase: branch A with A’s change, branch B with B’s change. The release is branch A plus branch B, a state neither agent ever ran. The gap between “both passed” and “the release passes” is not a failure of either agent; it is a third piece of work that nobody was assigned.
“Which test results were produced on the exact commit we are about to release?” If the answer is none, the release has not been tested. It has been assembled from tested parts, which is a different and weaker claim.
02 — The TableReview the points where contributions meet
Use this table for a release with multiple contributions. An interface contract means the names, values and behavior one part of the program expects from another. The review should follow those contracts across files, not stop at the list of paths changed by both agents, because the dangerous interactions are between files only one agent touched.
The middle column explains why running each branch’s tests alone misses the interaction; the right column is the check that only the combined candidate can pass. Not every row applies to every release. The discipline is to ask each question and write down “not applicable” where it is, rather than skipping the table because the merge was clean.
| Interaction | Why separate checks can miss it | Combined-candidate check |
|---|---|---|
| Shared field or type | Producer and consumer changed independently. | Pass a combined-version value across the interface. |
| Defaults and missing values | One change broadens inputs while another assumes a value exists. | Exercise the newly allowed absence or default. |
| Configuration | Both changes depend on different settings or environments. | Verify the candidate under the intended configuration. |
| Generated artifacts | Source edits and generated output came from different states. | Regenerate as prescribed and inspect consistency. |
| Conflict resolution | A chosen side can discard the other requirement. | Check the final behavior against both accepted intentions. |
| Cross-feature journey | Each feature passes alone while their interaction fails. | Exercise the user path that crosses the contributions. |
03 — The ToolsWhat a merge actually resolves
Git’s merge documentation explains how non-overlapping changes can be incorporated and how conflicting changes are presented for resolution. That is a rule for combining file content. The inference for agent work is straightforward: code that combines cleanly still needs checks of the resulting behavior, because Git reports a conflict when both sides change the same area of a file, not when the changes disagree in behavior.
Playwright’s testing guidance recommends testing the behavior visible to users. Applied here, that means exercising the interaction across both changes on the same candidate. A browser test is appropriate for a browser interaction; other systems need checks at their own user or service boundary. The common thread is that the check observes what the combined code does, not what each half was designed to do.
Between the two documents sits the whole problem. One tool is confident about text and silent about behavior; the other is confident about behavior and indifferent to how the code arrived. The combined-candidate review is the step that connects them.
Combines text
Incorporates non-overlapping changes and presents a conflict where both sides changed the same area of a file. Has no concept of a field name, a default value or a user journey.
Observe behavior
Prove what a specific commit does. Each agent’s suite proved its own branch. Nothing proves the merge result until something is run on the merge result.
Follows contracts
Asks whether the producer and consumer of each shared thing still agree. This is the step neither tool performs and the one the table is for.
04 — The ExampleFollow a value through both changes
Imagine one agent changes an API field from “name” to “displayName.” Another independently adds an export feature that reads “name.” The edits can sit in different files and merge without a conflict. The API branch may pass its updated tests, while the export branch passes against its older fixture. In combination, the exported label is missing, and nothing in either agent’s report hints at it.
The useful check starts with a record created or read through the combined API and follows it into the export. Keep the relevant implementation real. If the export test substitutes the old response shape, it can conceal the disagreement: the fixture still says “name”, the test still passes, the production response says “displayName”. The test-data reference explains how to label that simulated boundary so a reviewer knows which tests touched real code and which touched a stand-in.
Check defaults and absent values too. One contribution might make a field optional while another assumes it is populated. A successful example with every field filled does not exercise that interaction; the failing case is the record with the field missing, and someone has to construct it deliberately.
05 — The Third ChangeTreat conflict resolution as a new change
Resolve a textual conflict against the accepted purpose of both contributions. Record any requirement discarded or changed when choosing the final behavior. A resolution that “takes ours” has made a product decision about “theirs”, and that decision deserves the same sentence of justification any other change would get.
Keep the resolution note short: the conflicting assumption, the chosen behavior and the check that demonstrates it. If generated files are involved, use the project’s prescribed generator where appropriate and inspect the resulting changes. Hand-combining generated output can leave it inconsistent with its source, and the inconsistency will not surface until the next regeneration quietly undoes the merge.
Our worktree isolation guide addresses keeping concurrent edits apart. Isolation makes separate work manageable, but the combined candidate still has to reconcile the assumptions that crossed those workspaces. Isolation prevents agents from overwriting each other; it does nothing about agents quietly depending on each other.
06 — The FailuresFour green builds that shipped a broken release
Each illustrative case below passed every check that was actually run and failed in production, and each maps to a row of the table. They are the shapes to recognize, not incidents we are reporting.
The renamed field: one agent renames, another consumes the old name through a fixture, the merge is clean and the export ships blank. The optional-made-mandatory: one agent allows a null, another adds a formatter that dereferences it, both suites pass on populated fixtures, the first real empty record crashes the page. The stale generated client: one agent regenerates an API client from the old schema, another changes the schema, the merge keeps both, and the client is now wrong in a file nobody reads. The resolved-away requirement: a conflict in a validation rule is resolved by taking one side, which removes a limit the other side had added for a reason, and the reason is not written anywhere.
In every case the agents did their jobs. The release was undone by the absence of a third job: running the table against the candidate. The row that would have caught each one is, in order, shared field, defaults and missing values, generated artifacts, conflict resolution.
An agent reports on the code it can see. The interaction lives in the space between two agents’ views, so neither view contains it. The combined-candidate review exists because the interaction first becomes visible in the merged tree, after the merge.
07 — The RecordRecord the combined version and its evidence
Identify the source contributions, their starting point and the final candidate being checked. Run the project’s required validation, then the focused checks justified by the interactions in the table. If the target branch changes again, decide which results remain applicable and which need rerunning; a test that passed on the candidate before a third contribution landed has become a test of a historical state.
The bug-report evidence guide is useful when an interaction fails: preserve the triggering inputs, expected result and observed behavior on the combined version. Send that specific failure to the responsible agent rather than asking both agents to “double-check everything.” And when the release step itself is handed to an agent, our guide to showing changes before publishing describes how the approved candidate stays the one that ships. Teams running several coding agents in parallel who want the combined-candidate review built into their pipeline rather than remembered per release can work with our AI transformation practice.
08 — DecisionSeparate successes do not add up to a checked release
Accept one combined result.
Trace the interactions between contributions, inspect any resolution and verify the final candidate. Keep the version identifier beside the evidence so separate successes do not get mistaken for a checked release, and so the next contribution knows which results it has just invalidated.
For implementation support, explore our AI transformation services.