Last reviewed: 2026-08-11

Direct answer

Treat every coding-agent edit to an OpenAPI document as a contract change, not merely a YAML or JSON change. A useful merge gate compares the candidate contract with an identified baseline, validates the candidate, classifies semantic compatibility changes, exercises the implementation and representative consumers, and leaves the final exception decision with a human API owner.

That distinction matters because the OpenAPI Specification v3.2.0 defines a language-agnostic description of an HTTP API. Documentation generators, client generators, testing tools, validators, and people can all consume that description. A server may still accept an old request while the revised contract says the request is invalid. Passing server tests therefore does not prove that existing contract consumers remain compatible.

Use this operator workflow:

  1. Select an authoritative baseline. For a pull request, this is normally the contract from the target branch at the merge base. For a release gate, it may be the last published contract. Record the baseline revision and materialize the baseline as an artifact before running the agent’s candidate.
  2. Validate the complete candidate document. The Redocly CLI lint documentation describes linting API descriptions with recommended or configured rules and emitting machine-readable formats. Keep the ruleset in the repository so the agent and CI use the same policy.
  3. Run a semantic compatibility diff from baseline to candidate. The oasdiff breaking-change reference classifies changes across paths, schemas, parameters, request bodies, responses, headers, and security declarations. Direction is important: the old contract is the baseline and the proposed contract is the revision.
  4. Run implementation tests and, where practical, regenerate or compile at least one representative client. A semantic report shows what the description changed; it does not establish that the server implementation, fixtures, documentation, and generated consumers all changed together.
  5. Require a human decision for each reported breaking change. An intentional break needs an owner, migration plan, rollout boundary, and recorded reason. The coding agent may propose the remediation, but it should not approve its own exception.

Before delegating the edit, write a narrow change scope note that names the contract file, expected operations, baseline, compatibility requirement, generated outputs, and exception owner.

A representative CI step can be kept small:

set -eu

base_spec=artifacts/openapi-base.yaml
candidate_spec=api/openapi.yaml

redocly lint "$candidate_spec" --config=redocly.yaml --format=json > artifacts/openapi-lint.json
oasdiff breaking "$base_spec" "$candidate_spec" > artifacts/openapi-breaking.txt
./scripts/test-api-contract "$candidate_spec"

Adapt the paths and test wrapper to the repository. Pin the selected tools through the repository’s normal dependency mechanism, and change tool versions in a separate, reviewable update when possible. Otherwise, a tool upgrade can alter the report in the same pull request as the API change.

Happy path

The agent changes one operation, its implementation, fixtures, and documentation. CI reconstructs the baseline from the recorded revision, lints the entire candidate contract, and compares baseline to candidate. The lint report has no errors, the compatibility report has no unapproved breaking changes, contract tests pass, and a representative generated consumer still builds. The reviewer confirms that the changed files match the task scope and approves the patch. CI retains the reports with the run record.

Error path

The linter may find an invalid field or unresolved structure, or the compatibility check may find that an existing request is no longer valid. For example, making an optional request property required can break a client that legally omitted it under the baseline contract. The job should stop and preserve the rule identifier, severity, operation or schema location, baseline revision, candidate revision, and report path.

Return those structured findings to the agent instead of giving it the vague instruction to make CI pass. The next patch might restore compatibility by keeping the property optional, introducing an additive field, or placing an intentional break behind a documented version boundary. If the break remains intentional, the API owner records the migration and exception decision before rerunning the gate. Do not solve the failure by silently swapping the baseline, disabling the whole ruleset, or deleting the report.

Keep the summary log useful without copying payloads or security values into general CI output. A sanitized record can look like this:

{
  "run_id": "run-8421",
  "base_revision": "a1b2c3d",
  "candidate_revision": "d4e5f6a",
  "spec_path": "api/openapi.yaml",
  "declared_openapi_version": "3.2.0",
  "policy_version": "compat-v3",
  "lint_errors": 0,
  "lint_warnings": 1,
  "breaking_changes": 0,
  "changed_operations": ["GET /widgets/{widgetId}"],
  "gate_result": "pass",
  "reviewer_decision": "approved",
  "artifact_paths": [
    "artifacts/openapi-lint.json",
    "artifacts/openapi-breaking.txt"
  ]
}

Log counts, identifiers, revisions, paths, policy versions, and decisions. Avoid logging complete request or response examples, header values, security scheme values, production payloads, or unrelated environment data. Detailed artifacts should follow the repository’s normal access and retention controls.

Who this is for

This workflow is for teams that allow coding agents to edit OpenAPI descriptions, HTTP handlers, generated SDK inputs, API tests, or gateway configuration. It is especially useful when an API has consumers outside the service repository, because those consumers may not appear in the service’s unit test suite.

It also helps repositories where the OpenAPI document is generated. In that case, run the same generator against both baseline and candidate inputs, then compare the resulting contracts. The source template, generator configuration, generated contract, implementation, and tests all belong in the review surface.

This is not a replacement for API design review or runtime testing. It is a focused compatibility gate that turns a large textual agent diff into a smaller set of contract questions a reviewer can answer.

Key takeaways

  • Linting and compatibility analysis answer different questions. Linting checks the candidate against structural and policy rules; a semantic diff asks whether a consumer valid under the baseline can fail under the revision.
  • Baseline identity is part of the evidence. A report without a recorded baseline revision cannot reliably support a merge decision.
  • Request and response changes have different compatibility directions. Review requiredness, nullability, allowed values, constraints, and type changes from the consumer’s perspective.
  • Runtime leniency does not erase a declared contract break. Generated clients, validators, and gateways may enforce the description more strictly than the current server.
  • The agent can repair findings, but a human API owner should approve intentional breaks and broad suppressions.
  • Keep machine-readable reports and sanitized summaries so a later reviewer can reproduce the decision.

Sources checked

  • OpenAPI Specification v3.2.0 , published by the OpenAPI Initiative, was checked as the normative description of OpenAPI objects, fields, references, schemas, requests, responses, and security declarations. It also identifies documentation, code generation, and testing as uses of an OpenAPI Description.
  • Redocly CLI lint was checked for candidate validation behavior, configured rulesets, problem locations, severity reporting, and machine-readable output formats including JSON, JUnit, and GitHub Actions annotations.
  • OpenAPI Breaking Changes: The Complete List of Rules was checked for baseline-to-revision compatibility analysis. The refetched page classifies changes across OpenAPI areas and explains why a contract change can be breaking even when a particular server remains lenient.

These sources were publicly reachable and refetched with successful responses on the review date above.

Contract details to verify

Start with provenance. Record where the baseline came from, which revision produced it, which file or generation command produced the candidate, and which policy configuration ran. If the contract is split across files, make sure both runs resolve the same root document and all relevant references. Comparing one changed fragment while omitting referenced schemas can create a false pass.

Then verify these compatibility surfaces:

  • Paths and operations: Check removed paths, removed methods, operation identity, and deprecation or sunset information. A renamed operation may look small in text while changing generated client surfaces.
  • Requests: Review newly required parameters or properties, request-body requiredness, nullability, accepted media types, enumerations, patterns, length limits, ranges, and specialized types. A default value does not make omission valid when the revised contract marks a request property as required.
  • Responses: Review removed required properties, widened response possibilities, changed media types, changed status-code declarations, headers, and altered nullability. Consumers often deserialize against the declared response shape even when the server’s own tests only inspect a subset.
  • Parameters and serialization: Check whether a parameter moved between path, query, header, or cookie locations, and whether its style, explosion behavior, type, or requiredness changed. Object parameter serialization deserves explicit review when the description does not fully determine compatibility.
  • Schemas and references: Resolve references, composition, discriminators, formats, constraints, and read-only or write-only behavior. Confirm that the linter and compatibility tool are evaluating the same OpenAPI version and schema dialect used by the repository.
  • Security declarations: Review additions, removals, and requirement changes as contract changes. Keep actual security values out of the specification, reports, examples, and logs.
  • Generated consumers: Regenerate expected clients or server stubs in a clean directory. Compile or test representative output, and verify that generated churn is explained by the intended contract edit.
  • Implementation agreement: Exercise the affected handler with positive and negative contract tests. Confirm that implementation behavior, examples, fixtures, and documentation agree with the candidate description.

Do not reduce all findings to a single pass or fail line. Preserve the exact check identifier and location, then attach the human disposition: fixed, accepted with migration, false positive under a narrow policy exception, or deferred with an owner. A broad ignore entry makes later agent patches harder to review because unrelated breaks can pass under the same suppression.

Failure modes

The baseline moves during the run. If CI fetches a branch tip twice, the compatibility report may compare against a different contract than the reviewer expects. Resolve the baseline revision once, record it, and materialize the file from that revision.

Both inputs come from the candidate tree. A faulty script may generate both the baseline and revision after checking out the pull request. The diff then reports no change. Log both revisions and test the gate with a known breaking fixture.

A clean lint report is treated as compatibility proof. A structurally valid contract can still remove an operation or make a request more restrictive. Keep lint and semantic diff as separate named checks.

Server leniency hides the break. The implementation may continue accepting an omitted field even though the revised contract marks it required. Other validators or generated clients can follow the contract instead of the server’s permissive behavior. Review compatibility against the declared contract.

Request and response direction are inverted. A rule that is safe for accepted requests is not automatically safe for emitted responses. Classify each finding by direction before deciding whether it breaks existing consumers.

Generated and authored files disagree. An agent may edit a generated OpenAPI file while the source template remains unchanged, or update the template without regenerating the checked-in document. Identify the source of truth and verify regeneration in CI.

The toolchain changes with the contract. A new linter version, ruleset, generator, and API edit in one patch can produce a large report whose cause is unclear. Isolate policy or tool upgrades when practical, and always record their versions.

Suppressions become permanent escape hatches. An agent may add a repository-wide ignore to clear one failure. Require a check identifier, narrow scope, reason, owner, and removal condition for every exception.

Evidence is overwritten on failure. Shell settings can stop a job before reports are uploaded. Arrange CI so lint and diff artifacts are retained for failed runs as well as successful ones.

Logs capture sensitive or irrelevant material. Dumping entire contracts, examples, environment variables, or payloads into a public job log expands exposure without helping the compatibility decision. Emit the sanitized fields shown above and store detailed reports under normal CI controls.

The agent approves its own break. A generated explanation is useful input, not independent authorization. Keep the API owner or designated reviewer as the exception approver.

FAQ

Can linting alone catch breaking OpenAPI changes?

No. Linting can find malformed structures and violations of configured API rules, but a valid candidate can still be incompatible with its baseline. Run linting on the complete candidate and a semantic baseline-to-candidate diff as distinct checks.

What should I use as the baseline?

Use the contract that current consumers are expected to follow. For pull requests, that is commonly the target branch at the resolved merge base. For a release, it may be the last published contract. The important properties are stability, traceability, and using the same generation process as the candidate.

Is every reported breaking change forbidden?

Not necessarily. Some APIs intentionally introduce a version boundary or retire behavior. The report should block automatic merging until an API owner verifies the finding and records the migration, rollout, and consumer impact. An exception is a review decision, not a reason to discard the report.

Should the agent change the specification or the implementation?

That depends on intent. If the specification accidentally became stricter, restore compatibility in the description. If the implementation changed intentionally, update the description, fixtures, tests, generated consumers, and migration material together. The reviewer should reject a patch when the two disagree.

How do I test that the gate itself works?

Add small fixtures with known outcomes. One should add an optional request property and pass. Another should make an existing request property required and block. Run both through the same wrapper used in CI, then verify the baseline revision, findings, exit result, and retained artifacts.

What evidence belongs in the pull request?

Include baseline and candidate revisions, contract path, declared OpenAPI version, tool and policy versions, lint totals, semantic findings, affected operations, test result, artifact locations, and reviewer disposition. Keep payloads and security values out of the summary.

Reader next step

Choose one API repository and add the gate in report-only mode first. Resolve a fixed baseline, lint the complete candidate, run a semantic compatibility diff, retain both reports, and emit the sanitized summary fields. Exercise the workflow with one compatible fixture and one known break before making the check required.

Assign a named API owner for exceptions and add a short pull-request section for compatibility findings, consumer impact, generated outputs, and migration work. Use the guide to produce reviewable coding-agent diffs so contract changes are not buried under unrelated formatting or generated-file churn.

After several clean runs, make the compatibility job a required merge check. The immediate goal is simple: no coding-agent OpenAPI patch merges without a reproducible baseline, a valid candidate, a semantic compatibility report, and a human decision for every intentional break.